feat: edit shortcuts

This commit is contained in:
NGPixel 2022-09-20 16:55:05 -04:00
parent fa35f3a254
commit 8715cd69b2
No known key found for this signature in database
GPG Key ID: 8FDA2F1757F60D63
10 changed files with 246 additions and 10 deletions

View File

@ -144,7 +144,7 @@
//- ) //- )
//- v-divider.mt-3 //- v-divider.mt-3
v-switch( v-switch.mt-0(
inset inset
label='Comments' label='Comments'
color='indigo' color='indigo'
@ -177,6 +177,76 @@
persistent-hint persistent-hint
) )
v-card.mt-5.animated.fadeInUp.wait-p7s
v-toolbar(color='primary', dark, dense, flat)
v-toolbar-title.subtitle-1 {{$t('admin:general.editShortcuts')}}
v-card-text
v-switch.mt-0(
inset
:label='$t(`admin:general.editFab`)'
color='primary'
v-model='config.editFab'
persistent-hint
:hint='$t(`admin:general.editFabHint`)'
)
v-divider
.overline.grey--text.pa-4 {{$t('admin:general.editMenuBar')}}
.px-3.pb-3
v-switch.mt-0.ml-1(
inset
:label='$t(`admin:general.displayEditMenuBar`)'
color='primary'
v-model='config.editMenuBar'
persistent-hint
:hint='$t(`admin:general.displayEditMenuBarHint`)'
)
v-switch.mt-4.ml-1(
v-if='config.editMenuBar'
inset
:label='$t(`admin:general.displayEditMenuBtn`)'
color='primary'
v-model='config.editMenuBtn'
persistent-hint
:hint='$t(`admin:general.displayEditMenuBtnHint`)'
)
v-switch.mt-4.ml-1(
v-if='config.editMenuBar'
inset
:label='$t(`admin:general.displayEditMenuExternalBtn`)'
color='primary'
v-model='config.editMenuExternalBtn'
persistent-hint
:hint='$t(`admin:general.displayEditMenuExternalBtnHint`)'
)
template(v-if='config.editMenuBar && config.editMenuExternalBtn')
v-divider
.overline.grey--text.pa-4 External Edit Button
.px-3.pb-3
v-text-field(
outlined
:label='$t(`admin:general.editMenuExternalName`)'
v-model='config.editMenuExternalName'
prepend-icon='mdi-format-title'
:hint='$t(`admin:general.editMenuExternalNameHint`)'
persistent-hint
)
v-text-field.mt-3(
outlined
:label='$t(`admin:general.editMenuExternalIcon`)'
v-model='config.editMenuExternalIcon'
prepend-icon='mdi-dice-5'
:hint='$t(`admin:general.editMenuExternalIconHint`)'
persistent-hint
)
v-text-field.mt-3(
outlined
:label='$t(`admin:general.editMenuExternalUrl`)'
v-model='config.editMenuExternalUrl'
prepend-icon='mdi-near-me'
:hint='$t(`admin:general.editMenuExternalUrlHint`)'
persistent-hint
)
component(:is='activeModal') component(:is='activeModal')
</template> </template>
@ -216,7 +286,14 @@ export default {
featurePageComments: false, featurePageComments: false,
featurePersonalWikis: false, featurePersonalWikis: false,
featureTinyPNG: false, featureTinyPNG: false,
pageExtensions: '' pageExtensions: '',
editFab: false,
editMenuBar: false,
editMenuBtn: false,
editMenuExternalBtn: false,
editMenuExternalName: '',
editMenuExternalIcon: '',
editMenuExternalUrl: ''
}, },
metaRobots: [ metaRobots: [
{ text: 'Index', value: 'index' }, { text: 'Index', value: 'index' },
@ -274,6 +351,13 @@ export default {
$featurePageRatings: Boolean $featurePageRatings: Boolean
$featurePageComments: Boolean $featurePageComments: Boolean
$featurePersonalWikis: Boolean $featurePersonalWikis: Boolean
$editFab: Boolean
$editMenuBar: Boolean
$editMenuBtn: Boolean
$editMenuExternalBtn: Boolean
$editMenuExternalName: String
$editMenuExternalIcon: String
$editMenuExternalUrl: String
) { ) {
site { site {
updateConfig( updateConfig(
@ -290,6 +374,13 @@ export default {
featurePageRatings: $featurePageRatings featurePageRatings: $featurePageRatings
featurePageComments: $featurePageComments featurePageComments: $featurePageComments
featurePersonalWikis: $featurePersonalWikis featurePersonalWikis: $featurePersonalWikis
editFab: $editFab
editMenuBar: $editMenuBar
editMenuBtn: $editMenuBtn
editMenuExternalBtn: $editMenuExternalBtn
editMenuExternalName: $editMenuExternalName
editMenuExternalIcon: $editMenuExternalIcon
editMenuExternalUrl: $editMenuExternalUrl
) { ) {
responseResult { responseResult {
succeeded succeeded
@ -314,7 +405,14 @@ export default {
pageExtensions: _.get(this.config, 'pageExtensions', ''), pageExtensions: _.get(this.config, 'pageExtensions', ''),
featurePageRatings: _.get(this.config, 'featurePageRatings', false), featurePageRatings: _.get(this.config, 'featurePageRatings', false),
featurePageComments: _.get(this.config, 'featurePageComments', false), featurePageComments: _.get(this.config, 'featurePageComments', false),
featurePersonalWikis: _.get(this.config, 'featurePersonalWikis', false) featurePersonalWikis: _.get(this.config, 'featurePersonalWikis', false),
editFab: _.get(this.config, 'editFab', false),
editMenuBar: _.get(this.config, 'editMenuBar', false),
editMenuBtn: _.get(this.config, 'editMenuBtn', false),
editMenuExternalBtn: _.get(this.config, 'editMenuExternalBtn', false),
editMenuExternalName: _.get(this.config, 'editMenuExternalName', ''),
editMenuExternalIcon: _.get(this.config, 'editMenuExternalIcon', ''),
editMenuExternalUrl: _.get(this.config, 'editMenuExternalUrl', '')
}, },
watchLoading (isLoading) { watchLoading (isLoading) {
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-site-update') this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-site-update')
@ -368,6 +466,13 @@ export default {
featurePageRatings featurePageRatings
featurePageComments featurePageComments
featurePersonalWikis featurePersonalWikis
editFab
editMenuBar
editMenuBtn
editMenuExternalBtn
editMenuExternalName
editMenuExternalIcon
editMenuExternalUrl
} }
} }
} }

View File

@ -41,7 +41,16 @@ const state = {
manage: false manage: false
} }
}, },
commentsCount: 0 commentsCount: 0,
editShortcuts: {
editFab: false,
editMenuBar: false,
editMenuBtn: false,
editMenuExternalBtn: false,
editMenuExternalName: '',
editMenuExternalIcon: '',
editMenuExternalUrl: ''
}
} }
export default { export default {

View File

@ -49,10 +49,28 @@
status-indicator.ml-3(negative, pulse) status-indicator.ml-3(negative, pulse)
v-divider v-divider
v-container.grey.pa-0(fluid, :class='$vuetify.theme.dark ? `darken-4-l3` : `lighten-4`') v-container.grey.pa-0(fluid, :class='$vuetify.theme.dark ? `darken-4-l3` : `lighten-4`')
v-row(no-gutters, align-content='center', style='height: 90px;') v-row.page-header-section(no-gutters, align-content='center', style='height: 90px;')
v-col.page-col-content.is-page-header(offset-xl='2', offset-lg='3', style='margin-top: auto; margin-bottom: auto;', :class='$vuetify.rtl ? `pr-4` : `pl-4`') v-col.page-col-content.is-page-header(offset-xl='2', offset-lg='3', style='margin-top: auto; margin-bottom: auto;', :class='$vuetify.rtl ? `pr-4` : `pl-4`')
.headline.grey--text(:class='$vuetify.theme.dark ? `text--lighten-2` : `text--darken-3`') {{title}} .headline.grey--text(:class='$vuetify.theme.dark ? `text--lighten-2` : `text--darken-3`') {{title}}
.caption.grey--text.text--darken-1 {{description}} .caption.grey--text.text--darken-1 {{description}}
.page-edit-shortcuts(v-if='editShortcutsObj.editMenuBar')
v-btn(
v-if='editShortcutsObj.editMenuBtn'
@click='pageEdit'
depressed
small
)
v-icon.mr-2(small) mdi-pencil
span.text-none {{$t(`common:actions.edit`)}}
v-btn(
v-if='editShortcutsObj.editMenuExternalBtn'
:href='editMenuExternalUrl'
target='_blank'
depressed
small
)
v-icon.mr-2(small) {{ editShortcutsObj.editMenuExternalIcon }}
span.text-none {{$t(`common:page.editExternal`, { name: editShortcutsObj.editMenuExternalName })}}
v-divider v-divider
v-container.pl-5.pt-4(fluid, grid-list-xl) v-container.pl-5.pt-4(fluid, grid-list-xl)
v-layout(row) v-layout(row)
@ -186,7 +204,7 @@
v-spacer v-spacer
v-flex.page-col-content(xs12, lg9, xl10) v-flex.page-col-content(xs12, lg9, xl10)
v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasAnyPagePermissions') v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasAnyPagePermissions && editShortcutsObj.editFab')
template(v-slot:activator='{ on: onEditActivator }') template(v-slot:activator='{ on: onEditActivator }')
v-speed-dial( v-speed-dial(
v-model='pageEditFab' v-model='pageEditFab'
@ -440,6 +458,14 @@ export default {
commentsExternal: { commentsExternal: {
type: Boolean, type: Boolean,
default: false default: false
},
editShortcuts: {
type: String,
default: ''
},
filename: {
type: String,
default: ''
} }
}, },
data() { data() {
@ -478,6 +504,7 @@ export default {
isAuthenticated: get('user/authenticated'), isAuthenticated: get('user/authenticated'),
commentsCount: get('page/commentsCount'), commentsCount: get('page/commentsCount'),
commentsPerms: get('page/effectivePermissions@comments'), commentsPerms: get('page/effectivePermissions@comments'),
editShortcutsObj: get('page/editShortcuts'),
rating: { rating: {
get () { get () {
return 3.5 return 3.5
@ -519,7 +546,14 @@ export default {
return this.hasAdminPermission || this.hasWritePagesPermission || this.hasManagePagesPermission || return this.hasAdminPermission || this.hasWritePagesPermission || this.hasManagePagesPermission ||
this.hasDeletePagesPermission || this.hasReadSourcePermission || this.hasReadHistoryPermission this.hasDeletePagesPermission || this.hasReadSourcePermission || this.hasReadHistoryPermission
}, },
printView: sync('site/printView') printView: sync('site/printView'),
editMenuExternalUrl () {
if (this.editShortcutsObj.editMenuBar && this.editShortcutsObj.editMenuExternalBtn) {
return this.editShortcutsObj.editMenuExternalUrl.replace('{filename}', this.filename)
} else {
return ''
}
}
}, },
created() { created() {
this.$store.set('page/authorId', this.authorId) this.$store.set('page/authorId', this.authorId)
@ -537,6 +571,9 @@ export default {
if (this.effectivePermissions) { if (this.effectivePermissions) {
this.$store.set('page/effectivePermissions', JSON.parse(Buffer.from(this.effectivePermissions, 'base64').toString())) this.$store.set('page/effectivePermissions', JSON.parse(Buffer.from(this.effectivePermissions, 'base64').toString()))
} }
if (this.editShortcuts) {
this.$store.set('page/editShortcuts', JSON.parse(Buffer.from(this.editShortcuts, 'base64').toString()))
}
this.$store.set('page/mode', 'view') this.$store.set('page/mode', 'view')
}, },
@ -676,4 +713,43 @@ export default {
display: none; display: none;
} }
.page-header-section {
position: relative;
.page-edit-shortcuts {
position: absolute;
bottom: -14px;
right: 10px;
.v-btn {
border-right: 1px solid #DDD !important;
border-bottom: 1px solid #DDD !important;
border-radius: 0;
color: #777;
background-color: #FFF !important;
@at-root .theme--dark & {
background-color: #222 !important;
border-right-color: #444 !important;
border-bottom-color: #444 !important;
color: #CCC;
}
.v-icon {
color: mc('blue', '700');
}
&:first-child {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
&:last-child {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
}
}
}
</style> </style>

View File

@ -1036,4 +1036,8 @@
.comments-container { .comments-container {
display: none; display: none;
} }
.page-edit-shortcuts {
display: none;
}
} }

View File

@ -67,6 +67,14 @@ defaults:
audience: 'urn:wiki.js' audience: 'urn:wiki.js'
tokenExpiration: '30m' tokenExpiration: '30m'
tokenRenewal: '14d' tokenRenewal: '14d'
editShortcuts:
editFab: true
editMenuBar: false
editMenuBtn: true
editMenuExternalBtn: true
editMenuExternalName: 'GitHub'
editMenuExternalIcon: 'mdi-github'
editMenuExternalUrl: 'https://github.com/org/repo/blob/main/{filename}'
features: features:
featurePageRatings: true featurePageRatings: true
featurePageComments: true featurePageComments: true

View File

@ -542,13 +542,18 @@ router.get('/*', async (req, res, next) => {
}) })
} }
// -> Page Filename (for edit on external repo button)
let pageFilename = WIKI.config.lang.namespacing ? `${pageArgs.locale}/${page.path}` : page.path
pageFilename += page.contentType === 'markdown' ? '.md' : '.html'
// -> Render view // -> Render view
res.render('page', { res.render('page', {
page, page,
sidebar, sidebar,
injectCode, injectCode,
comments: commentTmpl, comments: commentTmpl,
effectivePermissions effectivePermissions,
pageFilename
}) })
} }
} else if (pageArgs.path === 'home') { } else if (pageArgs.path === 'home') {

View File

@ -20,6 +20,7 @@ module.exports = {
logoUrl: WIKI.config.logoUrl, logoUrl: WIKI.config.logoUrl,
pageExtensions: WIKI.config.pageExtensions.join(', '), pageExtensions: WIKI.config.pageExtensions.join(', '),
...WIKI.config.seo, ...WIKI.config.seo,
...WIKI.config.editShortcuts,
...WIKI.config.features, ...WIKI.config.features,
...WIKI.config.security, ...WIKI.config.security,
authAutoLogin: WIKI.config.auth.autoLogin, authAutoLogin: WIKI.config.auth.autoLogin,
@ -84,6 +85,16 @@ module.exports = {
tokenRenewal: _.get(args, 'authJwtRenewablePeriod', WIKI.config.auth.tokenRenewal) tokenRenewal: _.get(args, 'authJwtRenewablePeriod', WIKI.config.auth.tokenRenewal)
} }
WIKI.config.editShortcuts = {
editFab: _.get(args, 'editFab', WIKI.config.editShortcuts.editFab),
editMenuBar: _.get(args, 'editMenuBar', WIKI.config.editShortcuts.editMenuBar),
editMenuBtn: _.get(args, 'editMenuBtn', WIKI.config.editShortcuts.editMenuBtn),
editMenuExternalBtn: _.get(args, 'editMenuExternalBtn', WIKI.config.editShortcuts.editMenuExternalBtn),
editMenuExternalName: _.get(args, 'editMenuExternalName', WIKI.config.editShortcuts.editMenuExternalName),
editMenuExternalIcon: _.get(args, 'editMenuExternalIcon', WIKI.config.editShortcuts.editMenuExternalIcon),
editMenuExternalUrl: _.get(args, 'editMenuExternalUrl', WIKI.config.editShortcuts.editMenuExternalUrl)
}
WIKI.config.features = { WIKI.config.features = {
featurePageRatings: _.get(args, 'featurePageRatings', WIKI.config.features.featurePageRatings), featurePageRatings: _.get(args, 'featurePageRatings', WIKI.config.features.featurePageRatings),
featurePageComments: _.get(args, 'featurePageComments', WIKI.config.features.featurePageComments), featurePageComments: _.get(args, 'featurePageComments', WIKI.config.features.featurePageComments),
@ -109,7 +120,7 @@ module.exports = {
forceDownload: _.get(args, 'uploadForceDownload', WIKI.config.uploads.forceDownload) forceDownload: _.get(args, 'uploadForceDownload', WIKI.config.uploads.forceDownload)
} }
await WIKI.configSvc.saveToDb(['host', 'title', 'company', 'contentLicense', 'seo', 'logoUrl', 'pageExtensions', 'auth', 'features', 'security', 'uploads']) await WIKI.configSvc.saveToDb(['host', 'title', 'company', 'contentLicense', 'seo', 'logoUrl', 'pageExtensions', 'auth', 'editShortcuts', 'features', 'security', 'uploads'])
if (WIKI.config.security.securityTrustProxy) { if (WIKI.config.security.securityTrustProxy) {
WIKI.app.enable('trust proxy') WIKI.app.enable('trust proxy')

View File

@ -41,6 +41,13 @@ type SiteMutation {
authJwtAudience: String authJwtAudience: String
authJwtExpiration: String authJwtExpiration: String
authJwtRenewablePeriod: String authJwtRenewablePeriod: String
editFab: Boolean
editMenuBar: Boolean
editMenuBtn: Boolean
editMenuExternalBtn: Boolean
editMenuExternalName: String
editMenuExternalIcon: String
editMenuExternalUrl: String
featurePageRatings: Boolean featurePageRatings: Boolean
featurePageComments: Boolean featurePageComments: Boolean
featurePersonalWikis: Boolean featurePersonalWikis: Boolean
@ -83,6 +90,13 @@ type SiteConfig {
authJwtAudience: String authJwtAudience: String
authJwtExpiration: String authJwtExpiration: String
authJwtRenewablePeriod: String authJwtRenewablePeriod: String
editFab: Boolean
editMenuBar: Boolean
editMenuBtn: Boolean
editMenuExternalBtn: Boolean
editMenuExternalName: String
editMenuExternalIcon: String
editMenuExternalUrl: String
featurePageRatings: Boolean featurePageRatings: Boolean
featurePageComments: Boolean featurePageComments: Boolean
featurePersonalWikis: Boolean featurePersonalWikis: Boolean

View File

@ -148,6 +148,7 @@ module.exports = class Page extends Model {
isPublished: 'boolean', isPublished: 'boolean',
publishEndDate: 'string', publishEndDate: 'string',
publishStartDate: 'string', publishStartDate: 'string',
contentType: 'string',
render: 'string', render: 'string',
tags: [ tags: [
{ {
@ -787,7 +788,7 @@ module.exports = class Page extends Model {
* @returns {Promise} Promise with no value * @returns {Promise} Promise with no value
*/ */
static async deletePage(opts) { static async deletePage(opts) {
const page = await WIKI.models.pages.getPageFromDb(_.has(opts, 'id') ? opts.id : opts); const page = await WIKI.models.pages.getPageFromDb(_.has(opts, 'id') ? opts.id : opts)
if (!page) { if (!page) {
throw new WIKI.Error.PageNotFound() throw new WIKI.Error.PageNotFound()
} }
@ -1067,6 +1068,7 @@ module.exports = class Page extends Model {
isPublished: page.isPublished === 1 || page.isPublished === true, isPublished: page.isPublished === 1 || page.isPublished === true,
publishEndDate: page.publishEndDate, publishEndDate: page.publishEndDate,
publishStartDate: page.publishStartDate, publishStartDate: page.publishStartDate,
contentType: page.contentType,
render: page.render, render: page.render,
tags: page.tags.map(t => _.pick(t, ['tag', 'title'])), tags: page.tags.map(t => _.pick(t, ['tag', 'title'])),
title: page.title, title: page.title,

View File

@ -29,6 +29,8 @@ block body
comments-enabled=config.features.featurePageComments comments-enabled=config.features.featurePageComments
effective-permissions=Buffer.from(JSON.stringify(effectivePermissions)).toString('base64') effective-permissions=Buffer.from(JSON.stringify(effectivePermissions)).toString('base64')
comments-external=comments.codeTemplate comments-external=comments.codeTemplate
edit-shortcuts=Buffer.from(JSON.stringify(config.editShortcuts)).toString('base64')
filename=pageFilename
) )
template(slot='contents') template(slot='contents')
div!= page.render div!= page.render