Browse Source

story-content: Added chapter move option.

1.1
Gisle Aune 6 years ago
parent
commit
adf73a4623
  1. 4
      marko/page/story-content/components/chapter/component.js
  2. 6
      marko/page/story-content/components/chapter/index.marko
  3. 89
      marko/page/story-content/components/move-chapter-modal/component.js
  4. 18
      marko/page/story-content/components/move-chapter-modal/index.marko
  5. 6
      marko/page/story-content/components/page/component.js
  6. 2
      marko/page/story-content/components/page/index.marko
  7. 28
      rpdata/api/Chapter.js

4
marko/page/story-content/components/chapter/component.js

@ -10,6 +10,10 @@ module.exports = class {
this.emit("edit", data)
}
moveChapter(data) {
this.emit("move", data)
}
removeChapter() {
this.state.removed = true
this.emit("remove")

6
marko/page/story-content/components/chapter/index.marko

@ -1,5 +1,3 @@
import moment from "moment"
<div class="story-chapter">
<a class="anchor" id=input.chapter.id />
<div class="metadata">
@ -7,6 +5,9 @@ import moment from "moment"
<if-permitted user=input.user author=input.chapter.author permission="chapter.edit">
<a on-click("open", "edit") >Edit</a>
</if-permitted>
<if-permitted user=input.user author=input.chapter.author permission="chapter.move">
<a on-click("open", "move") >Move</a>
</if-permitted>
<if-permitted user=input.user author=input.chapter.author permission="chapter.remove">
<a on-click("open", "remove") >Remove</a>
</if-permitted>
@ -19,5 +20,6 @@ import moment from "moment"
<markdown class="chapter-content color-text" source=input.chapter.source />
<edit-chapter-modal enabled=(state.modal === "edit") chapter=input.chapter on-close("close") on-edit("updateChapter") />
<move-chapter-modal enabled=(state.modal === "move") chapter=input.chapter user=input.user on-close("close") on-move("moveChapter") />
<remove-chapter-modal enabled=(state.modal === "remove") chapter=input.chapter on-close("close") on-remove("removeChapter") />
</div>

89
marko/page/story-content/components/move-chapter-modal/component.js

@ -0,0 +1,89 @@
const {storyApi} = require("../../../../../rpdata/api/Story")
const {chapterApi} = require("../../../../../rpdata/api/Chapter")
module.exports = class {
onCreate(input) {
this.state = {
error: null,
loading: false,
loadingStories: true,
stories: [],
selected: null,
}
this.first = false
}
change(key, ev) {
const value = ev.target.value
switch (key) {
case "selected": {
this.state.selected = Object.assign({}, this.state.stories.find(s => s.id === value))
break
}
}
}
open() {
const promises = []
if ((this.input.user.permissions || []).includes("chapter.move")) {
promises.push(storyApi.list())
} else {
promises.push(storyApi.list({author: this.input.user.name}))
promises.push(storyApi.list({open: true}))
}
this.state.loadingStories = true
Promise.all(promises).then(lists => {
this.state.stories = unique(Array.prototype.concat.call(...lists))
this.state.selected = this.state.stories[0]
}).catch(err => {
console.warn(err)
}).then(() => {
this.state.loadingStories = false
})
}
close() {
this.first = false
this.emit("close")
}
save() {
if (this.state.loading) {
return
}
const input = {id: this.input.chapter.id, storyId: this.state.selected.id}
this.state.loading = true
chapterApi.moveChapter(input).then(data => {
this.emit("move", input)
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
})
}
}
function unique(stories) {
const ids = {}
const results = []
for (const story of stories) {
if (ids[story.id]) {
continue
}
ids[story.id] = true
results.push(story)
}
return results
}

18
marko/page/story-content/components/move-chapter-modal/index.marko

@ -0,0 +1,18 @@
$ const selected = (state.selected||{id:null});
<modal class="modal color-text nolabel" key="modal" enabled=(input.enabled) closable on-close("close") on-open("open") >
<h1>Move Chapter</h1>
<p key="error" class="color-error">${state.error}</p>
<label>Target story</label>
<select key="story" on-change("change", "selected") value=selected.id>
<option for(story in state.stories) value=story.id selected=(selected.id === story.id)>${story.name}</option>
</select>
<if-permitted not permission="story.move">
<p>Only stories you are allowed to move the chapter to appear in the above list.</p>
</if-permitted>
<button disabled=state.loading on-click("save")>Move</button>
</modal>

6
marko/page/story-content/components/page/component.js

@ -24,6 +24,12 @@ module.exports = class {
this.refreshStory()
}
moveChapter(chapter, data) {
if (data.storyId !== this.state.story.id) {
this.state.story = Object.assign({}, this.state.story, {chapters: this.state.story.chapters.filter(ch => ch.id !== chapter.id)})
}
}
updateChapter(id, data) {
const index = this.state.story.chapters.findIndex(ch => ch.id === id)
if (index === -1) {

2
marko/page/story-content/components/page/index.marko

@ -19,7 +19,7 @@
so you can still read it (or back it up) before leaving the page.
</p>
</annotation>
<chapter for(chapter in state.story.chapters) key=chapter.id chapter=chapter user=(!state.removed ? input.user : null) on-edit("updateChapter", chapter.id) on-remove("removeChapter", chapter.id)/>
<chapter for(chapter in state.story.chapters) key=chapter.id chapter=chapter user=(!state.removed ? input.user : null) on-edit("updateChapter", chapter.id) on-remove("removeChapter", chapter.id) on-move("moveChapter", chapter) />
</div>
<create-chapter-modal storyId=state.story.id enabled=(state.modal === "chapter.add") chapter=input.chapter on-close("close") on-add("addChapter") />

28
rpdata/api/Chapter.js

@ -21,7 +21,7 @@ class Chapter {
}
}
const chapterApi = {
class ChapterAPI {
/**
* Call `addChapter(input)` mutation, returns the entire object.
*
@ -46,7 +46,7 @@ const chapterApi = {
return new Chapter(ac.id, ac.title, ac.author, ac.source, ac.createdDate, ac.fictionalDate, ac.editedDate)
})
},
}
/**
* Call `editChapter(input)` mutation, returns editable fields
@ -70,7 +70,25 @@ const chapterApi = {
return editChapter
})
},
}
/**
* Call `moveChapter(input)` mutation, returns the ID.
*
* @param {{id:string, storyId:string}} input
* @returns {Promise<{id:string}>}
*/
moveChapter(input) {
return query(`
mutation MoveChapter($input: ChapterMoveInput!) {
moveChapter(input: $input) {
id
}
}
`, {input}, {permissions: ["member", "story.move"]}).then(({moveChapter}) => {
return moveChapter
})
}
/**
* Call `removeChapter(input)` mutation, returns only the id
@ -88,7 +106,7 @@ const chapterApi = {
`, {input}, {permissions: ["member", "story.edit"]}).then(({removeChapter}) => {
return removeChapter
})
},
}
}
module.exports = {Chapter, chapterApi}
module.exports = {Chapter, chapterApi: new ChapterAPI}
Loading…
Cancel
Save