Browse Source

feat: page locale migration + deps update

pull/921/head
Nick 5 years ago
parent
commit
5689444a17
11 changed files with 735 additions and 892 deletions
  1. 51
      client/components/admin/admin-theme.vue
  2. 20
      client/components/admin/admin-utilities-cache.vue
  3. 2
      client/components/admin/admin-utilities-content.vue
  4. 1
      client/graph/admin/utilities/utilities-mutation-content-migratelocale.gql
  5. 102
      package.json
  6. 9
      server/controllers/common.js
  7. 5
      server/graph/resolvers/page.js
  8. 7
      server/graph/schemas/page.graphql
  9. 13
      server/models/pages.js
  10. 4
      server/views/editor.pug
  11. 1413
      yarn.lock

51
client/components/admin/admin-theme.vue

@ -69,7 +69,10 @@
:hint='$t(`admin:theme.cssOverrideHint`)'
auto-grow
)
v-textarea.mt-2(
i18next.caption.pl-2.ml-1(path='admin:theme.cssOverrideWarning', tag='div')
strong.red--text(place='caution') {{$t('admin:theme.cssOverrideWarningCaution')}}
code(place='cssClass') .contents
v-textarea.mt-3(
v-model='config.injectHead'
:label='$t(`admin:theme.headHtmlInjection`)'
outline
@ -96,7 +99,26 @@
.subheading {{$t('admin:theme.downloadThemes')}}
v-spacer
v-chip(label, color='white', small).teal--text coming soon
v-card-text.caption -- Coming soon --
v-data-table(
:headers='headers',
:items='themes',
hide-actions,
item-key='value',
:rows-per-page-items='[-1]'
)
template(v-slot:items='thm')
td
strong {{thm.item.text}}
td
span {{ thm.item.author }}
td.text-xs-center
v-progress-circular(v-if='thm.item.isDownloading', indeterminate, color='blue', size='20', :width='2')
v-btn(v-else-if='thm.item.isInstalled && thm.item.installDate < thm.item.updatedAt', icon)
v-icon.blue--text cached
v-btn(v-else-if='thm.item.isInstalled', icon)
v-icon.green--text check
v-btn(v-else, icon)
v-icon.grey--text cloud_download
</template>
<script>
@ -111,7 +133,7 @@ export default {
return {
loading: false,
themes: [
{ text: 'Default', author: 'requarks.io', value: 'default' }
{ text: 'Default', author: 'requarks.io', value: 'default', isInstalled: true, installDate: '', updatedAt: '' }
],
iconsets: [
{ text: 'Material Icons (default)', value: 'md' },
@ -131,7 +153,28 @@ export default {
}
},
computed: {
darkMode: sync('site/dark')
darkMode: sync('site/dark'),
headers() {
return [
{
text: this.$t('admin:theme.downloadName'),
align: 'left',
value: 'text'
},
{
text: this.$t('admin:theme.downloadAuthor'),
align: 'left',
value: 'author'
},
{
text: this.$t('admin:theme.downloadDownload'),
align: 'center',
value: 'value',
sortable: false,
width: 100
}
]
}
},
mounted() {
this.darkModeInitial = this.darkMode

20
client/components/admin/admin-utilities-cache.vue

@ -15,6 +15,13 @@
v-btn(outline, color='primary', @click='flushUploads', :disabled='loading').ml-0.mt-3
v-icon(left) build
span Proceed
v-divider.my-3
v-subheader.pl-0.primary--text Flush Client-Side Locale Cache
.body-1 Locale strings are cached in the browser local storage for 24h. You can delete your current cache in order to fetch the latest data during the next page load.
.body-1 Note that this affects only #[strong your own browser] and not everyone.
v-btn(outline, color='primary', @click='flushClientLocaleCache', :disabled='loading').ml-0.mt-3
v-icon(left) build
span Proceed
</template>
<script>
@ -78,6 +85,19 @@ export default {
this.$store.commit(`loadingStop`, 'admin-utilities-cache-flushUploads')
this.loading = false
},
async flushClientLocaleCache () {
for (let i = 0; i < window.localStorage.length; i++) {
const lsKey = window.localStorage.key(i)
if (_.startsWith(lsKey, 'i18next_res')) {
window.localStorage.removeItem(lsKey)
}
}
this.$store.commit('showNotification', {
message: 'Locale Client-Side Cache flushed successfully.',
style: 'success',
icon: 'check'
})
}
}
}

2
client/components/admin/admin-utilities-content.vue

@ -70,7 +70,7 @@ export default {
const resp = _.get(respRaw, 'data.pages.migrateToLocale.responseResult', {})
if (resp.succeeded) {
this.$store.commit('showNotification', {
message: 'Migrated all content to target locale successfully.',
message: `Migrated ${_.get(respRaw, 'data.pages.migrateToLocale.count', 0)} page(s) to target locale successfully.`,
style: 'success',
icon: 'check'
})

1
client/graph/admin/utilities/utilities-mutation-content-migratelocale.gql

@ -7,6 +7,7 @@ mutation($sourceLocale: String!, $targetLocale: String!) {
slug
message
}
count
}
}
}

102
package.json

@ -35,13 +35,13 @@
},
"dependencies": {
"@aoberoi/passport-slack": "1.0.5",
"@bugsnag/js": "6.3.1",
"@bugsnag/js": "6.3.2",
"algoliasearch": "3.33.0",
"apollo-fetch": "0.7.0",
"apollo-server": "2.6.4",
"apollo-server-express": "2.6.4",
"apollo-server": "2.6.9",
"apollo-server-express": "2.6.9",
"auto-load": "3.0.4",
"aws-sdk": "2.480.0",
"aws-sdk": "2.493.0",
"axios": "0.19.0",
"azure-search-client": "3.1.5",
"bcryptjs-then": "1.0.1",
@ -50,7 +50,7 @@
"brute-knex": "4.0.0",
"chalk": "2.4.2",
"cheerio": "1.0.0-rc.3",
"chokidar": "3.0.1",
"chokidar": "3.0.2",
"clean-css": "4.2.1",
"compression": "1.7.4",
"connect-session-knex": "1.4.0",
@ -59,7 +59,7 @@
"custom-error-instance": "2.1.1",
"dependency-graph": "0.8.0",
"diff": "4.0.1",
"diff2html": "2.10.0",
"diff2html": "2.11.2",
"dotize": "0.3.0",
"elasticsearch6": "npm:@elastic/elasticsearch@6",
"elasticsearch7": "npm:@elastic/elasticsearch@7",
@ -67,17 +67,17 @@
"express": "4.17.1",
"express-brute": "1.0.1",
"express-session": "1.16.2",
"file-type": "12.0.0",
"file-type": "12.0.1",
"filesize": "4.1.2",
"fs-extra": "8.0.1",
"fs-extra": "8.1.0",
"getos": "3.1.1",
"graphql": "14.3.1",
"graphql": "14.4.2",
"graphql-list-fields": "2.0.2",
"graphql-rate-limit-directive": "1.1.0",
"graphql-subscriptions": "1.1.0",
"graphql-tools": "4.0.5",
"highlight.js": "9.15.8",
"i18next": "17.0.4",
"i18next": "17.0.6",
"i18next-express-middleware": "1.8.0",
"i18next-node-fs-backend": "2.1.3",
"image-size": "0.7.4",
@ -86,16 +86,16 @@
"js-yaml": "3.13.1",
"jsonwebtoken": "8.5.1",
"klaw": "3.0.0",
"knex": "0.17.6",
"lodash": "4.17.13",
"markdown-it": "8.4.2",
"knex": "0.19.0",
"lodash": "4.17.14",
"markdown-it": "9.0.1",
"markdown-it-abbr": "1.0.4",
"markdown-it-anchor": "5.2.4",
"markdown-it-attrs": "2.4.1",
"markdown-it-emoji": "1.4.0",
"markdown-it-expand-tabs": "1.0.13",
"markdown-it-external-links": "0.0.6",
"markdown-it-footnote": "3.0.1",
"markdown-it-footnote": "3.0.2",
"markdown-it-imsize": "2.0.1",
"markdown-it-mark": "2.0.0",
"markdown-it-mathjax": "2.0.0",
@ -105,7 +105,7 @@
"mathjax-node": "2.1.1",
"mime-types": "2.1.24",
"moment": "2.24.0",
"moment-timezone": "0.5.25",
"moment-timezone": "0.5.26",
"mongodb": "3.2.7",
"mssql": "5.1.0",
"multer": "1.4.1",
@ -113,7 +113,7 @@
"nanoid": "2.0.3",
"node-2fa": "1.1.2",
"node-cache": "4.2.0",
"nodemailer": "6.2.1",
"nodemailer": "6.3.0",
"objection": "1.6.9",
"passport": "0.4.0",
"passport-auth0": "1.1.0",
@ -138,7 +138,7 @@
"pg": "7.11.0",
"pg-hstore": "2.3.3",
"pg-query-stream": "2.0.0",
"pg-tsquery": "8.0.4",
"pg-tsquery": "8.0.5",
"pug": "2.0.4",
"qr-image": "3.2.0",
"raven": "2.6.4",
@ -148,41 +148,41 @@
"safe-regex": "2.0.2",
"sanitize-filename": "1.6.1",
"scim-query-filter-parser": "1.1.0",
"semver": "6.1.1",
"semver": "6.2.0",
"serve-favicon": "2.5.0",
"simple-git": "1.116.0",
"simple-git": "1.121.0",
"solr-node": "1.2.1",
"sqlite3": "4.0.9",
"striptags": "3.1.1",
"subscriptions-transport-ws": "0.9.16",
"tar-fs": "2.0.0",
"twemoji": "12.0.4",
"twemoji": "12.1.2",
"uslug": "1.0.4",
"uuid": "3.3.2",
"validate.js": "0.13.1",
"validator": "11.0.0",
"validator": "11.1.0",
"validator-as-promised": "1.0.2",
"winston": "3.2.1",
"yargs": "13.2.4"
},
"devDependencies": {
"@babel/cli": "^7.4.4",
"@babel/core": "^7.4.5",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/cli": "^7.5.0",
"@babel/core": "^7.5.4",
"@babel/plugin-proposal-class-properties": "^7.5.0",
"@babel/plugin-proposal-decorators": "^7.4.4",
"@babel/plugin-proposal-export-namespace-from": "^7.2.0",
"@babel/plugin-proposal-function-sent": "^7.2.0",
"@babel/plugin-proposal-export-namespace-from": "^7.5.2",
"@babel/plugin-proposal-function-sent": "^7.5.0",
"@babel/plugin-proposal-json-strings": "^7.2.0",
"@babel/plugin-proposal-numeric-separator": "^7.2.0",
"@babel/plugin-proposal-throw-expressions": "^7.2.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-syntax-import-meta": "^7.2.0",
"@babel/polyfill": "^7.4.4",
"@babel/preset-env": "^7.4.5",
"@babel/preset-env": "^7.5.4",
"@panter/vue-i18next": "0.15.1",
"@vue/babel-preset-app": "3.9.2",
"animate-sass": "0.8.2",
"animated-number-vue": "0.1.5",
"animated-number-vue": "1.0.0",
"apollo-cache-inmemory": "1.6.2",
"apollo-client": "2.6.3",
"apollo-link": "1.2.12",
@ -192,16 +192,16 @@
"apollo-link-persisted-queries": "0.2.2",
"apollo-link-ws": "1.0.18",
"apollo-utilities": "1.3.2",
"autoprefixer": "9.6.0",
"autoprefixer": "9.6.1",
"babel-eslint": "10.0.2",
"babel-jest": "24.8.0",
"babel-loader": "^8.0.6",
"babel-plugin-graphql-tag": "2.4.0",
"babel-plugin-lodash": "3.3.4",
"babel-plugin-prismjs": "1.0.2",
"babel-plugin-transform-imports": "1.5.1",
"babel-plugin-transform-imports": "2.0.0",
"brace": "0.11.1",
"cache-loader": "4.0.0",
"cache-loader": "4.0.1",
"chart.js": "2.8.0",
"clean-webpack-plugin": "3.0.0",
"copy-webpack-plugin": "5.0.3",
@ -210,16 +210,16 @@
"cssnano": "4.1.10",
"duplicate-package-checker-webpack-plugin": "3.0.0",
"epic-spinners": "1.1.0",
"eslint": "6.0.0",
"eslint": "6.0.1",
"eslint-config-requarks": "1.0.7",
"eslint-config-standard": "12.0.0",
"eslint-plugin-import": "2.17.3",
"eslint-config-standard": "13.0.1",
"eslint-plugin-import": "2.18.0",
"eslint-plugin-node": "9.1.0",
"eslint-plugin-promise": "4.1.1",
"eslint-plugin-promise": "4.2.1",
"eslint-plugin-standard": "4.0.0",
"eslint-plugin-vue": "5.2.2",
"eslint-plugin-vue": "5.2.3",
"file-loader": "4.0.0",
"filepond": "4.4.9",
"filepond": "4.4.11",
"filepond-plugin-file-validate-type": "1.2.4",
"filesize.js": "1.0.2",
"grapesjs": "0.14.62",
@ -239,16 +239,16 @@
"moment-duration-format": "2.3.2",
"node-sass": "4.12.0",
"offline-plugin": "5.0.7",
"optimize-css-assets-webpack-plugin": "5.0.1",
"optimize-css-assets-webpack-plugin": "5.0.3",
"postcss-cssnext": "3.1.0",
"postcss-flexbugs-fixes": "4.1.0",
"postcss-flexibility": "2.0.0",
"postcss-import": "12.0.1",
"postcss-loader": "3.0.0",
"postcss-preset-env": "6.6.0",
"postcss-preset-env": "6.7.0",
"postcss-selector-parser": "6.0.2",
"prismjs": "1.16.0",
"pug-lint": "2.5.0",
"pug-lint": "2.6.0",
"pug-loader": "2.4.0",
"pug-plain-loader": "1.0.0",
"raw-loader": "3.0.0",
@ -257,15 +257,15 @@
"resolve-url-loader": "3.1.0",
"sass-loader": "7.1.0",
"sass-resources-loader": "2.0.1",
"script-ext-html-webpack-plugin": "2.1.3",
"script-ext-html-webpack-plugin": "2.1.4",
"simple-progress-webpack-plugin": "1.1.2",
"style-loader": "0.23.1",
"stylus": "0.54.5",
"stylus-loader": "3.0.2",
"terser": "4.0.0",
"terser": "4.1.2",
"twemoji-awesome": "1.0.6",
"url-loader": "2.0.0",
"vee-validate": "2.2.11",
"url-loader": "2.0.1",
"vee-validate": "2.2.12",
"velocity-animate": "1.5.2",
"viz.js": "2.1.2",
"vue": "2.6.10",
@ -276,30 +276,30 @@
"vue-filepond": "5.1.1",
"vue-hot-reload-api": "2.3.3",
"vue-loader": "15.7.0",
"vue-material-design-icons": "3.2.0",
"vue-material-design-icons": "3.3.1",
"vue-moment": "4.0.0",
"vue-router": "3.0.6",
"vue-router": "3.0.7",
"vue-simple-breakpoints": "1.0.3",
"vue-status-indicator": "1.1.1",
"vue-template-compiler": "2.6.10",
"vue-tour": "1.1.0",
"vue2-animate": "2.1.0",
"vuedraggable": "2.22.0",
"vuescroll": "4.13.0",
"vuedraggable": "2.23.0",
"vuescroll": "4.13.1",
"vuetify": "1.5.16",
"vuex": "3.1.1",
"vuex-pathify": "1.2.4",
"vuex-persistedstate": "2.5.4",
"webpack": "4.35.0",
"webpack": "4.35.3",
"webpack-bundle-analyzer": "3.3.2",
"webpack-cli": "3.3.4",
"webpack-cli": "3.3.6",
"webpack-dev-middleware": "3.7.0",
"webpack-hot-middleware": "2.25.0",
"webpack-merge": "4.2.1",
"webpack-subresource-integrity": "1.3.2",
"whatwg-fetch": "3.0.0",
"write-file-webpack-plugin": "4.5.0",
"xterm": "3.14.2",
"xterm": "3.14.5",
"zxcvbn": "4.4.2"
},
"browserslist": [

9
server/controllers/common.js

@ -58,6 +58,13 @@ router.get(['/e', '/e/*'], async (req, res, next) => {
userId: req.user.id,
isPrivate: false
})
const injectCode = {
css: WIKI.config.theming.injectCSS,
head: WIKI.config.theming.injectHead,
body: WIKI.config.theming.injectBody
}
if (page) {
if (!WIKI.auth.checkAccess(req.user, ['manage:pages'], pageArgs)) {
_.set(res.locals, 'pageMeta.title', 'Unauthorized')
@ -84,7 +91,7 @@ router.get(['/e', '/e/*'], async (req, res, next) => {
content: null
}
}
res.render('editor', { page })
res.render('editor', { page, injectCode })
})
/**

5
server/graph/resolvers/page.js

@ -98,9 +98,10 @@ module.exports = {
},
async migrateToLocale(obj, args, context) {
try {
const count = await WIKI.models.pages.migrateToLocale(args)
return {
responseResult: graphHelper.generateSuccess('Migrated all content to target locale successfully.')
responseResult: graphHelper.generateSuccess('Migrated content to target locale successfully.'),
count
}
} catch (err) {
return graphHelper.generateError(err)

7
server/graph/schemas/page.graphql

@ -77,7 +77,7 @@ type PageMutation {
migrateToLocale(
sourceLocale: String!
targetLocale: String!
): DefaultResponse @auth(requires: ["manage:system"])
): PageMigrationResponse @auth(requires: ["manage:system"])
}
# -----------------------------------------------
@ -89,6 +89,11 @@ type PageResponse {
page: Page
}
type PageMigrationResponse {
responseResult: ResponseStatus!
count: Int
}
type Page {
id: Int!
path: String!

13
server/models/pages.js

@ -421,6 +421,19 @@ module.exports = class Page extends Model {
return fs.emptyDir(path.join(process.cwd(), `data/cache`))
}
static async migrateToLocale({ sourceLocale, targetLocale }) {
return WIKI.models.pages.query()
.patch({
localeCode: targetLocale
})
.where({
localeCode: sourceLocale
})
.whereNotExists(function() {
this.select('id').from('pages AS pagesm').where('pagesm.localeCode', targetLocale).andWhereRaw('pagesm.path = pages.path')
})
}
static cleanHTML(rawHTML = '') {
return striptags(rawHTML || '')
.replace(emojiRegex(), '')

4
server/views/editor.pug

@ -1,5 +1,9 @@
extends master.pug
block head
if injectCode.css
style(type='text/css')!= injectCode.css
block body
#root
editor(

1413
yarn.lock
File diff suppressed because it is too large
View File

Loading…
Cancel
Save