feat: content link states
This commit is contained in:
parent
e491af44ad
commit
efab00fa0c
@ -71,6 +71,7 @@
|
||||
single-line,
|
||||
solo
|
||||
flat
|
||||
rounded
|
||||
hide-details,
|
||||
prepend-inner-icon='mdi-magnify',
|
||||
:loading='searchIsLoading',
|
||||
|
@ -21,6 +21,7 @@
|
||||
.overline.mr-3.animated.fadeInLeft Current Selection
|
||||
v-chip.mr-3.primary--text(
|
||||
v-for='tag of tagsSelected'
|
||||
:key='`tagSelected-` + tag.tag'
|
||||
color='white'
|
||||
close
|
||||
@click:close='toggleTag(tag.tag)'
|
||||
@ -38,7 +39,7 @@
|
||||
template(v-else)
|
||||
v-icon.mr-3.animated.fadeInRight mdi-arrow-left
|
||||
.overline.animated.fadeInRight Select one or more tags
|
||||
v-toolbar(color='grey lighten-4', flat, height='58')
|
||||
v-toolbar(:color='$vuetify.theme.dark ? `grey darken-4-l5` : `grey lighten-4`', flat, height='58')
|
||||
v-text-field.tags-search(
|
||||
label='Search within results...'
|
||||
solo
|
||||
@ -50,12 +51,29 @@
|
||||
prepend-icon='mdi-file-document-box-search-outline'
|
||||
append-icon='mdi-arrow-right'
|
||||
)
|
||||
template(v-if='locales.length > 1')
|
||||
v-divider.mx-3(vertical)
|
||||
.overline Locale
|
||||
v-select.ml-2(
|
||||
:items='locales'
|
||||
v-model='locale'
|
||||
:background-color='$vuetify.theme.dark ? `grey darken-3` : `white`'
|
||||
hide-details
|
||||
label='Locale'
|
||||
item-text='name'
|
||||
item-value='code'
|
||||
rounded
|
||||
single-line
|
||||
dense
|
||||
height='40'
|
||||
style='max-width: 170px;'
|
||||
)
|
||||
v-divider.mx-3(vertical)
|
||||
.overline Order By
|
||||
v-select.ml-2(
|
||||
:items='orderByItems'
|
||||
v-model='orderBy'
|
||||
background-color='white'
|
||||
:background-color='$vuetify.theme.dark ? `grey darken-3` : `white`'
|
||||
hide-details
|
||||
label='Order By'
|
||||
rounded
|
||||
@ -64,12 +82,13 @@
|
||||
height='40'
|
||||
style='max-width: 250px;'
|
||||
)
|
||||
v-divider.mx-3(vertical)
|
||||
v-btn-toggle(v-model='displayStyle', rounded, mandatory)
|
||||
v-btn(text, height='40'): v-icon(small) mdi-view-list
|
||||
v-btn(text, height='40'): v-icon(small) mdi-cards-variant
|
||||
v-btn(text, height='40'): v-icon(small) mdi-format-align-justify
|
||||
v-btn-toggle.ml-2(v-model='orderByDirection', rounded, mandatory)
|
||||
v-btn(text, height='40'): v-icon(size='20') mdi-chevron-double-up
|
||||
v-btn(text, height='40'): v-icon(size='20') mdi-chevron-double-down
|
||||
v-divider
|
||||
.text-center.pt-10
|
||||
img(src='/svg/icon-price-tag.svg')
|
||||
.subtitle-2.grey--text Select one or more tags on the left.
|
||||
nav-footer
|
||||
notify
|
||||
search-results
|
||||
@ -77,16 +96,25 @@
|
||||
|
||||
<script>
|
||||
import { get } from 'vuex-pathify'
|
||||
import VueRouter from 'vue-router'
|
||||
import _ from 'lodash'
|
||||
|
||||
import tagsQuery from 'gql/common/common-pages-query-tags.gql'
|
||||
|
||||
/* global siteLangs */
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
base: '/t'
|
||||
})
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tags: [],
|
||||
selection: [],
|
||||
displayStyle: 0,
|
||||
locale: 'any',
|
||||
locales: [],
|
||||
orderBy: 'TITLE',
|
||||
orderByItems: [
|
||||
{ text: 'Creation Date', value: 'CREATED' },
|
||||
@ -95,6 +123,7 @@ export default {
|
||||
{ text: 'Path', value: 'PATH' },
|
||||
{ text: 'Title', value: 'TITLE' }
|
||||
],
|
||||
orderByDirection: 0,
|
||||
scrollStyle: {
|
||||
vuescroll: {},
|
||||
scrollPanel: {
|
||||
@ -127,8 +156,27 @@ export default {
|
||||
return _.filter(this.tags, t => _.includes(this.selection, t.tag))
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
locale (newValue, oldValue) {
|
||||
this.rebuildURL()
|
||||
},
|
||||
orderBy (newValue, oldValue) {
|
||||
this.rebuildURL()
|
||||
},
|
||||
orderByDirection (newValue, oldValue) {
|
||||
this.rebuildURL()
|
||||
}
|
||||
},
|
||||
router,
|
||||
created () {
|
||||
this.$store.commit('page/SET_MODE', 'tags')
|
||||
|
||||
this.locales = _.concat(
|
||||
[{name: 'Any', code: 'any'}],
|
||||
(siteLangs.length > 0 ? siteLangs : [])
|
||||
)
|
||||
|
||||
this.selection = _.compact(this.$route.path.split('/'))
|
||||
},
|
||||
methods: {
|
||||
toggleTag (tag) {
|
||||
@ -137,9 +185,25 @@ export default {
|
||||
} else {
|
||||
this.selection.push(tag)
|
||||
}
|
||||
this.rebuildURL()
|
||||
},
|
||||
isSelected (tag) {
|
||||
return _.includes(this.selection, tag)
|
||||
},
|
||||
rebuildURL () {
|
||||
let urlObj = {
|
||||
path: '/' + this.selection.join('/')
|
||||
}
|
||||
if (this.locale !== `any`) {
|
||||
_.set(urlObj, 'query.lang', this.locale)
|
||||
}
|
||||
if (this.orderBy !== `TITLE`) {
|
||||
_.set(urlObj, 'query.sort', this.orderBy.toLowerCase())
|
||||
}
|
||||
if (this.orderByDirection !== 0) {
|
||||
_.set(urlObj, 'query.dir', this.orderByDirection === 0 ? `asc` : `desc`)
|
||||
}
|
||||
this.$router.push(urlObj)
|
||||
}
|
||||
},
|
||||
apollo: {
|
||||
|
1
client/static/svg/icon-price-tag.svg
Normal file
1
client/static/svg/icon-price-tag.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" width="256" height="256"><path fill="#f7f7fb" d="M43.5,28L16.9,45.4c-5,2.3-2.3,9.1,0,14.1l17.9,17.9l62.2,23l17-47L43.5,28 M35.3,59.5 c-3.9-1.4-5.9-5.7-4.5-9.6c1.4-3.9,5.7-5.9,9.6-4.5s5.9,5.7,4.5,9.6C43.5,58.9,39.2,61,35.3,59.5"/><path fill="#dfdfe3" d="M30.353,52.448c0-0.846,0.144-1.706,0.446-2.548c1.098-3.057,3.977-4.946,7.048-4.946 c0.847,0,1.709,0.144,2.552,0.446l0,0c3.065,1.1,4.957,3.993,4.946,7.074C45.349,53.317,45.206,54.17,44.9,55l0,0 c-1.091,3.04-3.945,4.986-6.997,4.986c-0.864,0-1.743-0.156-2.603-0.486C32.242,58.402,30.352,55.521,30.353,52.448 M43.5,28 L16.9,45.4c-2.078,0.956-2.826,2.689-2.825,4.746c0,2.894,1.481,6.431,2.825,9.354l17.9,17.9l21.635,8H102.4l11.6-32L43.5,28"/><path fill="#454b54" d="M97,103.5c-0.4,0-0.7-0.1-1-0.2l-62.2-23c-0.4-0.2-0.8-0.4-1.1-0.7L14.8,61.7 c-0.6-0.6-0.9-1.3-0.9-2.1V45.4c0-1,0.5-2,1.4-2.5l26.6-17.5c0.8-0.5,1.8-0.6,2.7-0.3l70.5,25.5c0.7,0.3,1.4,0.8,1.7,1.5 s0.4,1.5,0.1,2.3l-17,47c-0.3,0.8-0.8,1.4-1.6,1.7C97.9,103.4,97.4,103.5,97,103.5z M36.5,74.9l58.7,21.7l15-41.4l-66.3-24L19.9,47 v11.3L36.5,74.9z"/><path fill="#6ec7b0" d="M34.8,27.5L16.9,45.4c-3.9,3.9-3.9,10.2,0,14.1l17.9,17.9h75v-50h-75V27.5z M37.8,60 c-4.1,0-7.5-3.4-7.5-7.5s3.4-7.5,7.5-7.5s7.5,3.4,7.5,7.5S42,60,37.8,60z"/><path fill="#454b54" d="M109.8,80.5h-75c-0.8,0-1.6-0.3-2.1-0.9L14.8,61.7C12.3,59.2,11,56,11,52.5s1.4-6.7,3.8-9.2 l17.9-17.9c0.6-0.6,1.3-0.9,2.1-0.9h75c1.7,0,3,1.3,3,3v50C112.8,79.2,111.5,80.5,109.8,80.5z M36.1,74.5h70.8v-44H36.1L19,47.5 c-1.3,1.3-2,3.1-2,5s0.7,3.6,2,4.9L36.1,74.5z"/><path fill="#fff" d="M89.8 50.5h-25c-1.7 0-3-1.3-3-3s1.3-3 3-3h25c1.7 0 3 1.3 3 3S91.5 50.5 89.8 50.5zM89.8 60.5h-25c-1.7 0-3-1.3-3-3s1.3-3 3-3h25c1.7 0 3 1.3 3 3S91.5 60.5 89.8 60.5z"/><path fill="#454b54" d="M7.8,85.5c-0.8,0-1.5-0.3-2.1-0.9c-1.2-1.2-1.2-3.1,0-4.2l9.1-9.1c1.2-1.2,3.1-1.2,4.2,0 c1.2,1.2,1.2,3.1,0,4.2l-9.1,9.1C9.4,85.2,8.6,85.5,7.8,85.5z"/></svg>
|
After Width: | Height: | Size: 1.9 KiB |
@ -10,11 +10,40 @@
|
||||
}
|
||||
|
||||
@at-root .theme--dark & {
|
||||
// background-color: darken(mc('grey', '900'), 4%);
|
||||
color: mc('grey', '300');
|
||||
}
|
||||
|
||||
a {
|
||||
color: mc('blue', '100');
|
||||
// ---------------------------------
|
||||
// LINKS
|
||||
// ---------------------------------
|
||||
|
||||
a {
|
||||
color: mc('blue', '700');
|
||||
|
||||
&.is-internal-link.is-invalid-page {
|
||||
color: mc('red', '700');
|
||||
|
||||
@at-root .theme--dark & {
|
||||
color: mc('red', '200');
|
||||
}
|
||||
}
|
||||
|
||||
&.is-external-link {
|
||||
padding-right: 3px;
|
||||
|
||||
&::after {
|
||||
font-family: 'Material Design Icons';
|
||||
font-size: 24px/1;
|
||||
padding-left: 3px;
|
||||
display: inline-block;
|
||||
content: '\F3CC';
|
||||
color: mc('grey', '500');
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
@at-root .theme--dark & {
|
||||
color: mc('blue', '200');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ module.exports = {
|
||||
name: _.get(c, 'name', 'Anonymous') || '',
|
||||
profile: _.get(c, 'profile', ''),
|
||||
tier: _.toLower(_.get(c, 'tier', 'backers')),
|
||||
totalDonated: _.get(c, 'totalAmountDonated', 0),
|
||||
totalDonated: Math.ceil(_.get(c, 'totalAmountDonated', 0)),
|
||||
twitter: _.get(c, 'twitter', '') || '',
|
||||
website: _.get(c, 'website', '') || ''
|
||||
}))
|
||||
|
@ -8,6 +8,8 @@ module.exports = async (pageId) => {
|
||||
|
||||
try {
|
||||
WIKI.models = require('../core/db').init()
|
||||
await WIKI.configSvc.loadFromDb()
|
||||
await WIKI.configSvc.applyFlags()
|
||||
|
||||
const page = await WIKI.models.pages.getPageFromDb(pageId)
|
||||
if (!page) {
|
||||
|
@ -1,6 +1,8 @@
|
||||
const _ = require('lodash')
|
||||
const cheerio = require('cheerio')
|
||||
|
||||
/* global WIKI */
|
||||
|
||||
module.exports = {
|
||||
async render() {
|
||||
const $ = cheerio.load(this.input)
|
||||
@ -14,6 +16,98 @@ module.exports = {
|
||||
renderer.init($, child.config)
|
||||
}
|
||||
|
||||
// --------------------------------
|
||||
// Detect internal / external links
|
||||
// --------------------------------
|
||||
|
||||
let internalRefs = []
|
||||
const reservedPrefixes = /^\/[a-z]\//gi
|
||||
|
||||
const isHostSet = WIKI.config.host.length > 7 && WIKI.config.host !== 'http://'
|
||||
if (!isHostSet) {
|
||||
WIKI.logger.warn('Host is not set. You must set the Site Host under General in the Administration Area!')
|
||||
}
|
||||
|
||||
$('a').each((i, elm) => {
|
||||
let href = $(elm).attr('href')
|
||||
|
||||
// -> Ignore empty links
|
||||
if (!href || href.length < 1) {
|
||||
return
|
||||
}
|
||||
|
||||
// -> Strip host from local links
|
||||
if (isHostSet && href.indexOf(WIKI.config.site.host) === 0) {
|
||||
href = href.replace(WIKI.config.site.host, '')
|
||||
}
|
||||
|
||||
// -> Assign local / external tag
|
||||
if (href.indexOf('://') < 0) {
|
||||
// -> Remove trailing slash
|
||||
if (_.endsWith('/')) {
|
||||
href = href.slice(0, -1)
|
||||
}
|
||||
|
||||
// -> Check for system prefix
|
||||
if (!reservedPrefixes.test(href)) {
|
||||
$(elm).addClass(`is-internal-link`)
|
||||
|
||||
// -> Reformat paths
|
||||
if (href.indexOf('/') !== 0) {
|
||||
href = `/${this.page.localeCode}/${this.page.path}/${href}`
|
||||
} else if (href.charAt(3) !== '/') {
|
||||
href = `/${this.page.localeCode}${href}`
|
||||
}
|
||||
|
||||
// -> Save internal references
|
||||
internalRefs.push({
|
||||
localeCode: href.substring(1, 3),
|
||||
path: _.head(href.substring(4).split('#'))
|
||||
})
|
||||
} else {
|
||||
$(elm).addClass(`is-system-link`)
|
||||
}
|
||||
} else {
|
||||
$(elm).addClass(`is-external-link`)
|
||||
}
|
||||
|
||||
// -> Update element
|
||||
$(elm).attr('href', href)
|
||||
})
|
||||
|
||||
// --------------------------------
|
||||
// Detect internal link states
|
||||
// --------------------------------
|
||||
|
||||
if (internalRefs.length > 0) {
|
||||
// -> Find matching pages
|
||||
const results = await WIKI.models.pages.query().column('path', 'localeCode').where(builder => {
|
||||
internalRefs.forEach((ref, idx) => {
|
||||
if (idx < 1) {
|
||||
builder.where(ref)
|
||||
} else {
|
||||
builder.orWhere(ref)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// -> Apply tag to internal links for found pages
|
||||
$('a.is-internal-link').each((i, elm) => {
|
||||
const href = $(elm).attr('href')
|
||||
const hrefObj = {
|
||||
localeCode: href.substring(1, 3),
|
||||
path: _.head(href.substring(4).split('#'))
|
||||
}
|
||||
if (_.some(results, r => {
|
||||
return r.localeCode === hrefObj.localeCode && r.path === hrefObj.path
|
||||
})) {
|
||||
$(elm).addClass(`is-valid-page`)
|
||||
} else {
|
||||
$(elm).addClass(`is-invalid-page`)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return $.html('body').replace('<body>', '').replace('</body>', '')
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user