Browse Source

feat: All Pages - include full parent paths in nav

pull/89/head
NGPixel 7 years ago
parent
commit
3c73f8285c
7 changed files with 90 additions and 20 deletions
  1. 32
      client/js/pages/all.js
  2. 28
      client/scss/components/collapsable-nav.scss
  3. 37
      libs/entries.js
  4. 4
      models/entry.js
  5. 2
      npm/package.json
  6. 2
      package.json
  7. 5
      views/pages/all.pug

32
client/js/pages/all.js

@ -20,9 +20,9 @@ module.exports = (alerts, socket) => {
Vue.nextTick(() => { Vue.nextTick(() => {
socket.emit('treeFetch', { basePath }, (data) => { socket.emit('treeFetch', { basePath }, (data) => {
if (self.tree.length > 0) { if (self.tree.length > 0) {
let curTree = _.last(self.tree)
curTree.hasChildren = true
_.find(curTree.pages, { _id: basePath }).isActive = true
let branch = _.last(self.tree)
branch.hasChildren = true
_.find(branch.pages, { _id: basePath }).isActive = true
} }
self.tree.push({ self.tree.push({
hasChildren: false, hasChildren: false,
@ -34,6 +34,32 @@ module.exports = (alerts, socket) => {
}, },
goto: function (entryPath) { goto: function (entryPath) {
window.location.assign(rootUrl + entryPath) window.location.assign(rootUrl + entryPath)
},
unfold: function (entryPath) {
let self = this
let lastIndex = 0
_.forEach(self.tree, branch => {
lastIndex++
if (_.find(branch.pages, { _id: entryPath }) !== undefined) {
return false
}
})
self.tree = _.slice(self.tree, 0, lastIndex)
let branch = _.last(self.tree)
branch.hasChildren = false
branch.pages.forEach(page => {
page.isActive = false
})
},
mainAction: function (page) {
let self = this
if (page.isActive) {
self.unfold(page._id)
} else if (page.isDirectory) {
self.fetch(page._id)
} else {
self.goto(page._id)
}
} }
}, },
mounted: function () { mounted: function () {

28
client/scss/components/collapsable-nav.scss

@ -58,6 +58,11 @@
a { a {
height: 50px; height: 50px;
&:nth-child(2) {
display: none;
}
} }
} }
@ -65,7 +70,8 @@
a { a {
display: flex; display: flex;
height: 40px;
flex: 1 1 auto;
min-height: 40px;
width: 100%; width: 100%;
align-items: center; align-items: center;
padding: 0 15px; padding: 0 15px;
@ -74,9 +80,9 @@
transition: all .4s ease; transition: all .4s ease;
background-color: rgba(0,0,0,0); background-color: rgba(0,0,0,0);
i {
font-size: 14px;
margin-right: 10px;
&.is-pagelink {
flex: 0 1 70px;
justify-content: center;
} }
&:hover { &:hover {
@ -84,6 +90,20 @@
text-decoration: none; text-decoration: none;
} }
i {
font-size: 14px;
&:first-of-type {
margin-right: 10px;
}
}
span {
display: block;
padding: 5px 0;
}
} }
} }

37
libs/entries.js

@ -310,20 +310,15 @@ module.exports = {
subtitle: content.meta.subtitle || '', subtitle: content.meta.subtitle || '',
parentTitle: content.parent.title || '', parentTitle: content.parent.title || '',
parentPath: parentPath, parentPath: parentPath,
isDirectory: false
isDirectory: false,
isEntry: true
}, { }, {
new: true, new: true,
upsert: true upsert: true
}) })
}).then(result => { }).then(result => {
return db.Entry.distinct('parentPath', { parentPath: { $ne: '' } }).then(allPaths => {
if (allPaths.length > 0) {
return db.Entry.updateMany({ _id: { $in: allPaths } }, { $set: { isDirectory: true } }).then(() => {
return result
})
} else {
return result
}
return self.updateTreeInfo().then(() => {
return result
}) })
}).catch(err => { }).catch(err => {
winston.error(err) winston.error(err)
@ -331,6 +326,28 @@ module.exports = {
}) })
}, },
/**
* Update tree info for all directory and parent entries
*
* @returns {Promise<Boolean>} Promise of the operation
*/
updateTreeInfo () {
return db.Entry.distinct('parentPath', { parentPath: { $ne: '' } }).then(allPaths => {
if (allPaths.length > 0) {
return Promise.map(allPaths, pathItem => {
let parentPath = _.chain(pathItem).split('/').initial().join('/').value()
let guessedTitle = _.chain(pathItem).split('/').last().startCase().value()
return db.Entry.update({ _id: pathItem }, {
$set: { isDirectory: true },
$setOnInsert: { isEntry: false, title: guessedTitle, parentPath }
}, { upsert: true })
})
} else {
return true
}
})
},
/** /**
* Create a new document * Create a new document
* *
@ -428,6 +445,6 @@ module.exports = {
* @return {Promise<Array>} List of entries * @return {Promise<Array>} List of entries
*/ */
getFromTree (basePath) { getFromTree (basePath) {
return db.Entry.find({ parentPath: basePath })
return db.Entry.find({ parentPath: basePath }, 'title parentPath isDirectory isEntry').sort({ title: 'asc' })
} }
} }

4
models/entry.js

@ -28,6 +28,10 @@ var entrySchema = Mongoose.Schema({
isDirectory: { isDirectory: {
type: Boolean, type: Boolean,
default: false default: false
},
isEntry: {
type: Boolean,
default: false
} }
}, { }, {
timestamps: {} timestamps: {}

2
npm/package.json

@ -1,6 +1,6 @@
{ {
"name": "wiki.js", "name": "wiki.js",
"version": "1.0.0-beta.10",
"version": "1.0.0-beta.11",
"description": "A modern, lightweight and powerful wiki app built on NodeJS, Git and Markdown", "description": "A modern, lightweight and powerful wiki app built on NodeJS, Git and Markdown",
"main": "install.js", "main": "install.js",
"scripts": { "scripts": {

2
package.json

@ -1,6 +1,6 @@
{ {
"name": "wiki", "name": "wiki",
"version": "1.0.0-beta.10",
"version": "1.0.0-beta.11",
"description": "A modern, lightweight and powerful wiki app built on NodeJS, Git and Markdown", "description": "A modern, lightweight and powerful wiki app built on NodeJS, Git and Markdown",
"main": "server.js", "main": "server.js",
"scripts": { "scripts": {

5
views/pages/all.pug

@ -28,10 +28,13 @@ block content
span Login span Login
ul.collapsable-nav(v-for='treeItem in tree', :class='{ "has-children": treeItem.hasChildren }', v-cloak) ul.collapsable-nav(v-for='treeItem in tree', :class='{ "has-children": treeItem.hasChildren }', v-cloak)
li(v-for='page in treeItem.pages', :class='{ "is-active": page.isActive }') li(v-for='page in treeItem.pages', :class='{ "is-active": page.isActive }')
a(v-on:click='(page.isDirectory) ? fetch(page._id) : goto(page._id)')
a(v-on:click='mainAction(page)')
template(v-if='page._id !== "home"') template(v-if='page._id !== "home"')
i(:class='{ "icon-folder2": page.isDirectory, "icon-file-text-o": !page.isDirectory }') i(:class='{ "icon-folder2": page.isDirectory, "icon-file-text-o": !page.isDirectory }')
span {{ page.title }} span {{ page.title }}
template(v-else) template(v-else)
i.icon-home i.icon-home
span Home span Home
a.is-pagelink(v-if='page.isDirectory && page.isEntry', v-on:click='goto(page._id)')
i.icon-file-text-o
i.icon-arrow-right2
Loading…
Cancel
Save