story-content: Added edit story modal, added toggle component.
This commit is contained in:
@@ -23,7 +23,9 @@ div.overlay {
|
||||
label {
|
||||
display: block;
|
||||
margin-top: 1em;
|
||||
margin-left: 0.5ch;
|
||||
font-size: 0.75em;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
input {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = class {
|
||||
set(value) {
|
||||
if (value !== this.input.value) {
|
||||
this.emit("change", {target: {value}})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<div class="toggle">
|
||||
<div class="toggle-pill color-primary">
|
||||
<a on-click("set", false) class=["toggle-option", !input.value ? "color-highlight-primary" : "color-primary"]>${input.off}</a>
|
||||
<a on-click("set", true) class=["toggle-option", input.value ? "color-highlight-primary" : "color-primary"]>${input.on}</a>
|
||||
</div>
|
||||
<div class="toggle-content color-text">${input.value ? input.onDesc : input.offDesc}</div>
|
||||
</div>
|
||||
@@ -0,0 +1,27 @@
|
||||
div.toggle {
|
||||
div.toggle-pill {
|
||||
display: inline-block;
|
||||
margin: 0.5em;
|
||||
margin-bottom: 0;
|
||||
|
||||
a.toggle-option {
|
||||
padding: 0.125em 0.5ch;
|
||||
display: inline-block;
|
||||
width: 8ch;
|
||||
text-align: center;
|
||||
outline: 0.5px dotted;
|
||||
cursor: pointer;
|
||||
opacity: 0.75;
|
||||
}
|
||||
a.toggle-option.color-highlight-primary {
|
||||
outline: 1px solid;
|
||||
}
|
||||
a.toggle-option:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
div.toggle-content {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
const moment = require("moment")
|
||||
|
||||
const {storyApi} = require("../../../../../rpdata/api/Story")
|
||||
|
||||
module.exports = class {
|
||||
onCreate() {
|
||||
this.state = {
|
||||
error: null,
|
||||
values: {
|
||||
name: "",
|
||||
fictionalDate: "",
|
||||
category: "",
|
||||
open: "",
|
||||
listed: "",
|
||||
},
|
||||
loading: false,
|
||||
}
|
||||
|
||||
this.filled = false
|
||||
}
|
||||
|
||||
onInput(input) {
|
||||
if (!this.filled) {
|
||||
this.state.values = {
|
||||
name: input.story.name,
|
||||
category: input.story.category,
|
||||
open: input.story.open,
|
||||
listed: input.story.listed,
|
||||
}
|
||||
|
||||
if (input.story.fictionalDate != null) {
|
||||
this.state.values.fictionalDate = moment.utc(input.story.fictionalDate).format("MMM D, YYYY")
|
||||
}
|
||||
|
||||
this.filled = true
|
||||
}
|
||||
}
|
||||
|
||||
change(key, ev) {
|
||||
this.state.values[key] = ev.target.value
|
||||
this.state.values = Object.assign({}, this.state.values)
|
||||
}
|
||||
|
||||
save() {
|
||||
const values = this.state.values
|
||||
|
||||
let fictionalDate = new Date(values.fictionalDate + " UTC")
|
||||
if (values.fictionalDate != "") {
|
||||
if (Number.isNaN(fictionalDate)) {
|
||||
this.state.error = `Could not parse ${values.fictionalDate} as date`
|
||||
return
|
||||
}
|
||||
} else {
|
||||
fictionalDate = null
|
||||
}
|
||||
|
||||
const input = {id: this.input.story.id, name: values.name, category: values.category, open: values.open, listed: values.listed}
|
||||
if (fictionalDate != null) {
|
||||
input.fictionalDate = fictionalDate
|
||||
} else {
|
||||
input.clearFictionalDate = true
|
||||
}
|
||||
|
||||
this.state.loading = true
|
||||
storyApi.edit(input).then(data => {
|
||||
this.emit("edit", data)
|
||||
this.emit("close")
|
||||
}).catch(errs => {
|
||||
console.warn("Failed to edit:", errs)
|
||||
this.state.error = "Failed to edit: " + errs[0].message
|
||||
}).then(() => {
|
||||
this.state.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
close() {
|
||||
this.emit("close")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<modal class="modal color-text nolabel" key="modal2" enabled=(input.enabled) closable on-close("close") >
|
||||
<h1>Edit Story</h1>
|
||||
|
||||
<p key="error" class="color-error">${state.error}</p>
|
||||
|
||||
<label>Title</label>
|
||||
<input key="name" placeholder="Name" class="big" on-change("change", "name") value=state.values.name />
|
||||
|
||||
<label>IC Date</label>
|
||||
<input key="icdate" placeholder="IC Date" on-change("change", "fictionalDate") value=state.values.fictionalDate />
|
||||
|
||||
<label>Category</label>
|
||||
<select key="category" placeholder="Kind" on-change("change", "category")>
|
||||
<option for(category in input.categories) value=category.name selected=(state.values.category === category.name)>${category.name}</option>
|
||||
</select>
|
||||
|
||||
<label>Options</label>
|
||||
<toggle value=state.values.listed on="Listed" off="Unlisted"
|
||||
onDesc="The story will be visible on the front page."
|
||||
offDesc="A direct link is required to view this story."
|
||||
on-change("change", "listed") />
|
||||
<toggle value=state.values.open on="Open" off="Closed"
|
||||
onDesc="Other authors can add chapters to this story."
|
||||
offDesc="Only you can add chapters to this story."
|
||||
on-change("change", "open") />
|
||||
|
||||
<button disabled=state.loading on-click("save")>Save</button>
|
||||
</modal>
|
||||
@@ -15,6 +15,10 @@ module.exports = class {
|
||||
this.state.modal = null
|
||||
}
|
||||
|
||||
updateStory(data) {
|
||||
this.state.story = Object.assign(Object.assign({}, this.state.story), data)
|
||||
}
|
||||
|
||||
addChapter(chapter) {
|
||||
this.state.story.chapters.push(chapter)
|
||||
this.refreshStory()
|
||||
|
||||
@@ -18,5 +18,6 @@
|
||||
|
||||
<create-chapter-modal storyId=state.story.id enabled=(state.modal === "chapter.add") chapter=input.chapter on-close("close") on-add("addChapter") />
|
||||
<edit-story-tags-modal enabled=(state.modal === "story.tags") story=state.story on-tags("updateStoryTags") on-close("close") />
|
||||
<edit-story-modal enabled=(state.modal === "story.edit") story=state.story categories=input.categories on-edit("updateStory") on-close("close") />
|
||||
<remove-story-modal enabled=(state.modal === "story.remove") story=state.story on-remove("timeToDie") on-close("close") />
|
||||
</main>
|
||||
@@ -14,7 +14,6 @@
|
||||
margin-bottom: 1em;
|
||||
|
||||
h1 {
|
||||
vertical-align: middle;
|
||||
display: block;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<include("../layout", {title: "Stories", site: "story"})>
|
||||
<@body>
|
||||
<background src="/assets/images/bg.png" opacity=0.25 />
|
||||
<page story=input.story user=input.user selected=input.selected />
|
||||
<page story=input.story categories=input.categories user=input.user selected=input.selected />
|
||||
</@body>
|
||||
</include>
|
||||
Reference in New Issue
Block a user