Browse Source

feat: editor modals translations

Nick 6 years ago
parent
commit
a3be2a772a

+ 2 - 2
.eslintrc.yml

@@ -1,6 +1,6 @@
 extends:
   - requarks
-  - plugin:vue/recommended
+  - plugin:vue/strongly-recommended
 env:
   node: true
   jest: true
@@ -12,4 +12,4 @@ globals:
   document: false
   navigator: false
   window: false
-  FuseBox: false
+  FuseBox: false

+ 6 - 6
client/components/common/duration-picker.vue

@@ -1,6 +1,6 @@
 <template lang='pug'>
   v-toolbar.radius-7(flat, :color='$vuetify.dark ? "grey darken-4-l3" : "grey lighten-3"')
-    .body-2.mr-3 Every
+    .body-2.mr-3 {{$t('common:duration.every')}}
     v-text-field(
       solo
       hide-details
@@ -8,7 +8,7 @@
       reverse
       v-model='minutes'
     )
-    .body-2.mx-3 Minute(s)
+    .body-2.mx-3 {{$t('common:duration.minutes')}}
     v-divider.mr-3()
     v-text-field(
       solo
@@ -17,7 +17,7 @@
       reverse
       v-model='hours'
     )
-    .body-2.mx-3 Hour(s)
+    .body-2.mx-3 {{$t('common:duration.hours')}}
     v-divider.mr-3()
     v-text-field(
       solo
@@ -26,7 +26,7 @@
       reverse
       v-model='days'
     )
-    .body-2.mx-3 Day(s)
+    .body-2.mx-3 {{$t('common:duration.days')}}
     v-divider.mr-3()
     v-text-field(
       solo
@@ -35,7 +35,7 @@
       reverse
       v-model='months'
     )
-    .body-2.mx-3 Month(s)
+    .body-2.mx-3 {{$t('common:duration.months')}}
     v-divider.mr-3()
     v-text-field(
       solo
@@ -44,7 +44,7 @@
       reverse
       v-model='years'
     )
-    .body-2.mx-3 Year(s)
+    .body-2.mx-3 {{$t('common:duration.years')}}
 </template>
 
 <script>

+ 3 - 3
client/components/common/user-search.vue

@@ -5,7 +5,7 @@
     )
     v-card.wiki-form
       .dialog-header
-        span Search User
+        span {{$t('common:user.search')}}
         v-spacer
         v-progress-circular(
           indeterminate
@@ -17,7 +17,7 @@
       v-card-text
         v-text-field(
           outline
-          label='Search Users...'
+          :label='$t(`common:user.searchPlaceholder`)'
           v-model='search'
           prepend-inner-icon='search'
           color='primary'
@@ -45,7 +45,7 @@
           flat
           @click='close'
           :disabled='loading'
-          ) Cancel
+          ) {{$t('common:actions.cancel')}}
 </template>
 
 <script>

+ 27 - 44
client/components/editor/editor-markdown.vue

@@ -86,6 +86,12 @@
           v-btn.animated.fadeIn.wait-p11s(icon, slot='activator', @click='insertAfter({ content: `---`, newLine: true })').mx-0
             v-icon remove
           span Horizontal Bar
+        template(v-if='$vuetify.breakpoint.mdAndUp')
+          v-spacer
+          v-tooltip(bottom, color='primary')
+            v-btn.animated.fadeIn.wait-p11s(icon, slot='activator', @click='previewShown = !previewShown').mx-0
+              v-icon flip
+            span Hide / Show Preview Pane
     .editor-markdown-main
       .editor-markdown-sidebar
         v-tooltip(right, color='teal')
@@ -131,12 +137,9 @@
               v-icon(:color='helpShown ? `teal` : ``') help
             span Markdown Formatting Help
       .editor-markdown-editor
-        .editor-markdown-editor-title(v-if='previewShown', @click='previewShown = false') Editor
-        .editor-markdown-editor-title(v-else='previewShown', @click='previewShown = true'): v-icon(dark) drag_indicator
         codemirror(ref='cm', v-model='code', :options='cmOptions', @ready='onCmReady', @input='onCmInput')
       transition(name='editor-markdown-preview')
         .editor-markdown-preview(v-if='previewShown')
-          .editor-markdown-preview-title(@click='previewShown = false') Preview
           .editor-markdown-preview-content.contents(ref='editorPreview', v-html='previewHTML')
 
     v-system-bar.editor-markdown-sysbar(dark, status, color='grey darken-3')
@@ -264,7 +267,9 @@ export default {
         highlightSelectionMatches: {
           annotateScrollbar: true
         },
-        viewportMargin: 50
+        viewportMargin: 50,
+        inputStyle: 'contenteditable',
+        allowDropFileTypes: ['image/jpg', 'image/png', 'image/svg', 'image/jpeg', 'image/gif']
       },
       cursorPos: { ch: 0, line: 1 },
       previewShown: true,
@@ -339,6 +344,7 @@ export default {
         this.positionSync(cm)
         this.scrollSync(cm)
       })
+      cm.on('paste', this.onCmPaste)
       this.onCmInput(this.code)
     },
     onCmInput: _.debounce(function (newContent) {
@@ -351,6 +357,23 @@ export default {
         this.scrollSync(this.cm)
       })
     }, 500),
+    onCmPaste (cm, ev) {
+      const clipItems = (ev.clipboardData || ev.originalEvent.clipboardData).items
+      for (const clipItem of clipItems) {
+        if (_.startsWith(clipItem.type, 'image/')) {
+          const file = clipItem.getAsFile()
+          const reader = new FileReader()
+          reader.onload = evt => {
+            this.$store.commit(`loadingStart`, 'editor-paste-image')
+            this.insertAfter({
+              content: `![${file.name}](${evt.target.result})`,
+              newLine: true
+            })
+          }
+          reader.readAsDataURL(file)
+        }
+      }
+    },
     /**
      * Update cursor state
      */
@@ -514,28 +537,6 @@ $editor-height-mobile: calc(100vh - 112px - 16px);
     @include until($tablet) {
       height: $editor-height-mobile;
     }
-
-    &-title {
-      background-color: mc('grey', '800');
-      border-bottom-left-radius: 5px;
-      display: inline-flex;
-      height: 30px;
-      justify-content: center;
-      align-items: center;
-      padding: 0 1rem;
-      color: mc('grey', '500');
-      position: absolute;
-      top: 0;
-      right: 0;
-      z-index: 7;
-      text-transform: uppercase;
-      font-size: .7rem;
-      cursor: pointer;
-
-      @include until($tablet) {
-        display: none;
-      }
-    }
   }
 
   &-preview {
@@ -582,24 +583,6 @@ $editor-height-mobile: calc(100vh - 112px - 16px);
         height: $editor-height-mobile;
       }
     }
-
-    &-title {
-      background-color: rgba(mc('blue', '100'), .75);
-      border-bottom-right-radius: 5px;
-      display: inline-flex;
-      height: 30px;
-      justify-content: center;
-      align-items: center;
-      padding: 0 1rem;
-      color: mc('blue', '800');
-      position: absolute;
-      top: 0;
-      left: 0;
-      z-index: 2;
-      text-transform: uppercase;
-      font-size: .7rem;
-      cursor: pointer;
-    }
   }
 
   &-toolbar {

+ 2 - 2
client/components/editor/editor-modal-editorselect.vue

@@ -2,7 +2,7 @@
   v-dialog(v-model='isShown', persistent, max-width='700')
     v-card.radius-7(color='blue darken-3', dark)
       v-card-text.text-xs-center.py-4
-        .subheading Which editor do you want to use for this page?
+        .subheading {{$t('editor:select.title')}}
         v-container(grid-list-lg, fluid)
           v-layout(row, wrap, justify-center)
             v-flex(xs4)
@@ -65,7 +65,7 @@
                   img(src='/svg/icon-news.svg', alt='WikiText', style='width: 36px;')
                   .body-2.grey--text.mt-2.text--darken-2 WikiText
                   .caption.grey--text.text--darken-1 MediaWiki Format
-        .caption.blue--text.text--lighten-2 This cannot be changed once the page is created.
+        .caption.blue--text.text--lighten-2 {{$t('editor:select.cannotChange')}}
 </template>
 
 <script>

+ 46 - 45
client/components/editor/editor-modal-media.vue

@@ -7,33 +7,34 @@
             v-card-text
               .d-flex
                 v-toolbar.radius-7(:color='$vuetify.dark ? `teal` : `teal lighten-5`', dense, flat, height='44')
-                  .body-2(:class='$vuetify.dark ? `white--text` : `teal--text`') Assets
+                  .body-2(:class='$vuetify.dark ? `white--text` : `teal--text`') {{$t('editor:assets.title')}}
                   v-spacer
                   v-btn(flat, icon, @click='refresh')
                     v-icon(:color='$vuetify.dark ? `white` : `teal`') refresh
                 v-dialog(v-model='newFolderDialog', max-width='550')
                   v-btn.ml-3.my-0.mr-0.radius-7(outline, large, color='teal', :icon='$vuetify.breakpoint.xsOnly', slot='activator')
                     v-icon(:left='$vuetify.breakpoint.mdAndUp') add
-                    span.hidden-sm-and-down(:class='$vuetify.dark ? `teal--text text--lighten-3` : ``') New Folder
+                    span.hidden-sm-and-down(:class='$vuetify.dark ? `teal--text text--lighten-3` : ``') {{$t('editor:assets.newFolder')}}
                   v-card.wiki-form
-                    .dialog-header.is-short New Folder
+                    .dialog-header.is-short {{$t('editor:assets.newFolder')}}
                     v-card-text
                       v-text-field.md2(
                         outline
                         background-color='grey lighten-3'
                         prepend-icon='folder'
                         v-model='newFolderName'
-                        label='Folder Name'
+                        :label='$t(`editor:assets.folderName`)'
                         counter='255'
                         @keyup.enter='createFolder'
                         @keyup.esc='newFolderDialog = false'
                         ref='folderNameIpt'
                         )
-                      .caption.grey--text.text--darken-1.pl-5 Must follow the asset folder #[a(href='https://docs-beta.requarks.io/guide/assets#naming-restrictions', target='_blank') naming rules].
+                      i18next.caption.grey--text.text--darken-1.pl-5(path='editor:assets.folderNameNamingRules', tag='div')
+                        a(place='namingRules', href='https://docs-beta.requarks.io/guide/assets#naming-restrictions', target='_blank') {{$t('editor:assets.folderNameNamingRulesLink')}}
                     v-card-chin
                       v-spacer
-                      v-btn(flat, @click='newFolderDialog = false') Cancel
-                      v-btn(color='primary', @click='createFolder', :disabled='!isFolderNameValid', :loading='newFolderLoading') Create
+                      v-btn(flat, @click='newFolderDialog = false') {{$t('common:actions.cancel')}}
+                      v-btn(color='primary', @click='createFolder', :disabled='!isFolderNameValid', :loading='newFolderLoading') {{$t('common:actions.create')}}
               v-toolbar(flat, dense, :color='$vuetify.dark ? `grey darken-3` : `white`')
                 template(v-if='folderTree.length > 0')
                   .body-2
@@ -81,48 +82,48 @@
                           v-list-tile(@click='', disabled)
                             v-list-tile-avatar
                               v-icon(color='teal') short_text
-                            v-list-tile-content Properties
+                            v-list-tile-content {{$t('common:actions.properties')}}
                           v-divider
                           template(v-if='props.item.kind === `IMAGE`')
                             v-list-tile(@click='previewDialog = true', disabled)
                               v-list-tile-avatar
                                 v-icon(color='green') image_search
-                              v-list-tile-content Preview
+                              v-list-tile-content {{$t('common:actions.preview')}}
                             v-divider
                             v-list-tile(@click='', disabled)
                               v-list-tile-avatar
                                 v-icon(color='indigo') crop_rotate
-                              v-list-tile-content Edit
+                              v-list-tile-content {{$t('common:actions.edit')}}
                             v-divider
                             v-list-tile(@click='', disabled)
                               v-list-tile-avatar
                                 v-icon(color='purple') offline_bolt
-                              v-list-tile-content Optimize
+                              v-list-tile-content {{$t('common:actions.optimize')}}
                             v-divider
                           v-list-tile(@click='openRenameDialog')
                             v-list-tile-avatar
                               v-icon(color='orange') keyboard
-                            v-list-tile-content Rename
+                            v-list-tile-content {{$t('common:actions.rename')}}
                           v-divider
                           v-list-tile(@click='', disabled)
                             v-list-tile-avatar
                               v-icon(color='blue') forward
-                            v-list-tile-content Move
+                            v-list-tile-content {{$t('common:actions.move')}}
                           v-divider
                           v-list-tile(@click='deleteDialog = true')
                             v-list-tile-avatar
                               v-icon(color='red') delete
-                            v-list-tile-content Delete
+                            v-list-tile-content {{$t('common:actions.delete')}}
                 template(slot='no-data')
-                  v-alert.mt-3.radius-7(icon='folder_open', :value='true', outline, color='teal') This asset folder is empty.
+                  v-alert.mt-3.radius-7(icon='folder_open', :value='true', outline, color='teal') {{$t('editor:assets.folderEmpty')}}
               .text-xs-center.py-2(v-if='this.pageTotal > 1')
                 v-pagination(v-model='pagination.page', :length='pageTotal')
               .d-flex.mt-3
                 v-toolbar.radius-7(flat, :color='$vuetify.dark ? `grey darken-2` : `grey lighten-4`', dense, height='44')
-                  .body-1(:class='$vuetify.dark ? `grey--text text--lighten-1` : `grey--text text--darken-1`') {{assets.length}} files
+                  .body-1(:class='$vuetify.dark ? `grey--text text--lighten-1` : `grey--text text--darken-1`') {{$t('editor:assets.fileCount', { count: assets.length })}}
                 v-btn.ml-3.mr-0.my-0.radius-7(color='teal', large, @click='insert', :disabled='!currentFileId', :dark='currentFileId !== null')
                   v-icon(left) save_alt
-                  span Insert
+                  span {{$t('common:actions.insert')}}
 
         v-flex(xs12, xl3)
           v-card.radius-7.animated.fadeInRight.wait-p3s(:light='!$vuetify.dark', :dark='$vuetify.dark')
@@ -130,14 +131,14 @@
               .d-flex
                 v-toolbar.radius-7(:color='$vuetify.dark ? `teal` : `teal lighten-5`', dense, flat, height='44')
                   v-icon.mr-3(:color='$vuetify.dark ? `white` : `teal`') cloud_upload
-                  .body-2(:class='$vuetify.dark ? `white--text` : `teal--text`') Upload Assets
+                  .body-2(:class='$vuetify.dark ? `white--text` : `teal--text`') {{$t('editor:assets.uploadAssets')}}
                 v-btn.my-0.ml-3.mr-0.radius-7(outline, large, color='teal', @click='browse', v-if='$vuetify.breakpoint.mdAndUp')
                   v-icon(left) touch_app
-                  span(:class='$vuetify.dark ? `teal--text text--lighten-3` : ``') Browse
+                  span(:class='$vuetify.dark ? `teal--text text--lighten-3` : ``') {{$t('common:actions.browse')}}
               file-pond.mt-3(
                 name='mediaUpload'
                 ref='pond'
-                label-idle='Browse or Drop files here...'
+                :label-idle='$t(`editor:assets.uploadAssetsDropZone`)'
                 allow-multiple='true'
                 :files='files'
                 max-files='10'
@@ -150,13 +151,13 @@
             v-card-actions.pa-3
               .caption.grey--text.text-darken-2 Max 10 files, 5 MB each
               v-spacer
-              v-btn(color='teal', dark, @click='upload') Upload
+              v-btn(color='teal', dark, @click='upload') {{$t('common:actions.upload')}}
 
           v-card.mt-3.radius-7.animated.fadeInRight.wait-p4s(:light='!$vuetify.dark', :dark='$vuetify.dark')
             v-card-text.pb-0
               v-toolbar.radius-7(:color='$vuetify.dark ? `teal` : `teal lighten-5`', dense, flat)
                 v-icon.mr-3(:color='$vuetify.dark ? `white` : `teal`') cloud_download
-                .body-2(:class='$vuetify.dark ? `white--text` : `teal--text`') Fetch Remote Image
+                .body-2(:class='$vuetify.dark ? `white--text` : `teal--text`') {{$t('editor:assets.fetchImage')}}
                 v-spacer
                 v-chip(label, color='white', small).teal--text coming soon
               v-text-field.mt-3(
@@ -170,13 +171,13 @@
             v-card-actions.pa-3
               .caption.grey--text.text-darken-2 Max 5 MB
               v-spacer
-              v-btn(color='teal', disabled) Fetch
+              v-btn(color='teal', disabled) {{$t('common:actions.fetch')}}
 
           v-card.mt-3.radius-7.animated.fadeInRight.wait-p4s(:light='!$vuetify.dark', :dark='$vuetify.dark')
             v-card-text.pb-0
               v-toolbar.radius-7(:color='$vuetify.dark ? `teal` : `teal lighten-5`', dense, flat)
                 v-icon.mr-3(:color='$vuetify.dark ? `white` : `teal`') format_align_left
-                .body-2(:class='$vuetify.dark ? `white--text` : `teal--text`') Image Alignment
+                .body-2(:class='$vuetify.dark ? `white--text` : `teal--text`') {{$t('editor:assets.imageAlign')}}
               v-select.mt-3(
                 v-model='imageAlignment'
                 :items='imageAlignments'
@@ -192,9 +193,9 @@
       v-card.wiki-form
         .dialog-header.is-short.is-orange
           v-icon.mr-2(color='white') keyboard
-          span Rename Asset
+          span {{$t('editor:assets.renameAsset')}}
         v-card-text
-          .body-2 Enter the new name for this asset:
+          .body-2 {{$t('editor:assets.renameAssetSubtitle')}}
           v-text-field(
             outline
             single-line
@@ -205,8 +206,8 @@
           )
         v-card-chin
           v-spacer
-          v-btn(flat, @click='renameDialog = false', :disabled='renameAssetLoading') Cancel
-          v-btn(color='orange darken-3', @click='renameAsset', :loading='renameAssetLoading').white--text Rename
+          v-btn(flat, @click='renameDialog = false', :disabled='renameAssetLoading') {{$t('common:actions.cancel')}}
+          v-btn(color='orange darken-3', @click='renameAsset', :loading='renameAssetLoading').white--text {{$t('common:actions.rename')}}
 
     //- DELETE DIALOG
 
@@ -214,15 +215,15 @@
       v-card.wiki-form
         .dialog-header.is-short.is-red
           v-icon.mr-2(color='white') highlight_off
-          span Delete Asset
+          span {{$t('editor:assets.deleteAsset')}}
         v-card-text
-          .body-2 Are you sure you want to delete asset
+          .body-2 {{$t('editor:assets.deleteAssetConfirm')}}
           .body-2.red--text.text--darken-2 {{currentAsset.filename}}?
-          .caption.mt-3 This action cannot be undone!
+          .caption.mt-3 {{$t('editor:assets.deleteAssetWarn')}}
         v-card-chin
           v-spacer
-          v-btn(flat, @click='deleteDialog = false', :disabled='deleteAssetLoading') Cancel
-          v-btn(color='red darken-2', @click='deleteAsset', :loading='deleteAssetLoading').white--text Delete
+          v-btn(flat, @click='deleteDialog = false', :disabled='deleteAssetLoading') {{$t('common:actions.cancel')}}
+          v-btn(color='red darken-2', @click='deleteAsset', :loading='deleteAssetLoading').white--text {{$t('common:actions.delete')}}
 </template>
 
 <script>
@@ -297,12 +298,12 @@ export default {
     },
     headers() {
       return _.compact([
-        this.$vuetify.breakpoint.smAndUp && { text: 'ID', value: 'id', width: 50, align: 'right' },
-        { text: 'Filename', value: 'filename' },
-        this.$vuetify.breakpoint.lgAndUp && { text: 'Type', value: 'ext', width: 50 },
-        this.$vuetify.breakpoint.mdAndUp && { text: 'File Size', value: 'fileSize', width: 110 },
-        this.$vuetify.breakpoint.mdAndUp && { text: 'Added', value: 'createdAt', width: 175 },
-        this.$vuetify.breakpoint.smAndUp && { text: 'Actions', value: '', width: 40, sortable: false, align: 'right' }
+        this.$vuetify.breakpoint.smAndUp && { text: this.$t('editor:assets.headerId'), value: 'id', width: 50, align: 'right' },
+        { text: this.$t('editor:assets.headerFilename'), value: 'filename' },
+        this.$vuetify.breakpoint.lgAndUp && { text: this.$t('editor:assets.headerType'), value: 'ext', width: 50 },
+        this.$vuetify.breakpoint.mdAndUp && { text: this.$t('editor:assets.headerFileSize'), value: 'fileSize', width: 110 },
+        this.$vuetify.breakpoint.mdAndUp && { text: this.$t('editor:assets.headerAdded'), value: 'createdAt', width: 175 },
+        this.$vuetify.breakpoint.smAndUp && { text: this.$t('editor:assets.headerActions'), value: '', width: 40, sortable: false, align: 'right' }
       ])
     },
     isFolderNameValid() {
@@ -349,7 +350,7 @@ export default {
     async refresh() {
       await this.$apollo.queries.assets.refetch()
       this.$store.commit('showNotification', {
-        message: 'List of assets refreshed successfully.',
+        message: this.$t('editor:assets.refreshSuccess'),
         style: 'success',
         icon: 'check'
       })
@@ -372,7 +373,7 @@ export default {
       const files = this.$refs.pond.getFiles()
       if (files.length < 1) {
         return this.$store.commit('showNotification', {
-          message: 'You must choose a file to upload first!',
+          message: this.$t('editor:assets.noUploadError'),
           style: 'warning',
           icon: 'warning'
         })
@@ -387,7 +388,7 @@ export default {
     async onFileProcessed (err, file) {
       if (err) {
         return this.$store.commit('showNotification', {
-          message: 'File upload failed.',
+          message: this.$t('editor:assets.uploadFailed'),
           style: 'error',
           icon: 'error'
         })
@@ -423,7 +424,7 @@ export default {
         if (_.get(resp, 'data.assets.createFolder.responseResult.succeeded', false)) {
           await this.$apollo.queries.folders.refetch()
           this.$store.commit('showNotification', {
-            message: 'Asset folder created successfully.',
+            message: this.$t('editor:assets.folderCreateSuccess'),
             style: 'success',
             icon: 'check'
           })
@@ -456,7 +457,7 @@ export default {
         if (_.get(resp, 'data.assets.renameAsset.responseResult.succeeded', false)) {
           await this.$apollo.queries.assets.refetch()
           this.$store.commit('showNotification', {
-            message: 'Asset renamed successfully.',
+            message: this.$t('editor:assets.renameSuccess'),
             style: 'success',
             icon: 'check'
           })
@@ -485,7 +486,7 @@ export default {
           this.currentFileId = null
           await this.$apollo.queries.assets.refetch()
           this.$store.commit('showNotification', {
-            message: 'Asset deleted successfully.',
+            message: this.$t('editor:assets.deleteSuccess'),
             style: 'success',
             icon: 'check'
           })

+ 22 - 22
client/components/editor/editor-modal-properties.vue

@@ -8,7 +8,7 @@
     )
     .dialog-header
       v-icon(color='white') sort_by_alpha
-      .subheading.white--text.ml-2 Page Properties
+      .subheading.white--text.ml-2 {{$t('editor:props.pageProperties')}}
       v-spacer
       v-btn.mx-0(
         outline
@@ -19,34 +19,34 @@
         span {{ $t('common:actions.ok') }}
     v-card.wiki-form(tile)
       v-card-text
-        v-subheader.pl-0 Page Info
+        v-subheader.pl-0 {{$t('editor:props.pageInfo')}}
         v-text-field(
           ref='iptTitle'
           outline
           background-color='grey lighten-2'
-          label='Title'
+          :label='$t(`editor:props.title`)'
           counter='255'
           v-model='title'
           )
         v-text-field(
           outline
           background-color='grey lighten-2'
-          label='Short Description'
+          :label='$t(`editor:props.shortDescription`)'
           counter='255'
           v-model='description'
           persistent-hint
-          hint='Shown below the title'
+          :hint='$t(`editor:props.shortDescriptionHint`)'
           )
       v-divider
       v-card-text.grey(:class='darkMode ? `darken-3-d3` : `lighten-5`')
-        v-subheader.pl-0 Path &amp; Categorization
+        v-subheader.pl-0 {{$t('editor:props.pathCategorization')}}
         v-container.pa-0(fluid, grid-list-lg)
           v-layout(row, wrap)
             v-flex(xs12, md2)
               v-select(
                 outline
                 background-color='grey lighten-2'
-                label='Locale'
+                :label='$t(`editor:props.locale`)'
                 suffix='/'
                 :items='namespaces'
                 v-model='locale'
@@ -57,10 +57,10 @@
               v-text-field(
                 outline
                 background-color='grey lighten-2'
-                label='Path'
+                :label='$t(`editor:props.path`)'
                 append-icon='folder'
                 v-model='path'
-                hint='Do not include any leading or trailing slashes.'
+                :hint='$t(`editor:props.pathHint`)'
                 persistent-hint
                 @click:append='showPathSelector'
                 :disabled='mode !== "create"'
@@ -69,25 +69,25 @@
           background-color='grey lighten-2'
           chips
           deletable-chips
-          label='Tags'
+          :label='$t(`editor:props.tags`)'
           outline
           multiple
           v-model='tags'
           single-line
-          hint='Use tags to categorize your pages and make them easier to find.'
+          :hint='$t(`editor:props.tagsHint`)'
           persistent-hint
           )
       v-divider
       v-card-text.pb-5.grey(:class='darkMode ? `darken-3-d5` : `lighten-4`')
-        v-subheader.pl-0 Publishing State
+        v-subheader.pl-0 {{$t('editor:props.publishState')}}
         v-container.pa-0(fluid, grid-list-lg)
           v-layout(row, wrap)
             v-flex(xs12, md4)
               v-switch(
-                label='Published'
+                :label='$t(`editor:props.publishToggle`)'
                 v-model='isPublished'
                 color='primary'
-                hint='Unpublished pages can still be seen by users having write permissions on this page.'
+                :hint='$t(`editor:props.publishToggleHint`)'
                 persistent-hint
                 )
             v-flex(xs12, md4)
@@ -103,14 +103,14 @@
                 )
                 v-text-field(
                   slot='activator'
-                  label='Publish starting on...'
+                  :label='$t(`editor:props.publishStart`)'
                   v-model='publishStartDate'
                   prepend-icon='event'
                   readonly
                   outline
                   background-color='grey lighten-2'
                   clearable
-                  hint='Leave empty for no start date'
+                  :hint='$t(`editor:props.publishStartHint`)'
                   persistent-hint
                   :disabled='!isPublished'
                   )
@@ -127,12 +127,12 @@
                     flat=''
                     color='primary'
                     @click='isPublishStartShown = false'
-                    ) Cancel
+                    ) {{$t('common:actions.cancel')}}
                   v-btn(
                     flat=''
                     color='primary'
                     @click='$refs.menuPublishStart.save(publishStartDate)'
-                    ) OK
+                    ) {{$t('common:actions.ok')}}
             v-flex(xs12, md4)
               v-dialog(
                 ref='menuPublishEnd'
@@ -146,14 +146,14 @@
                 )
                 v-text-field(
                   slot='activator'
-                  label='Publish ending on...'
+                  :label='$t(`editor:props.publishEnd`)'
                   v-model='publishEndDate'
                   prepend-icon='event'
                   readonly
                   outline
                   background-color='grey lighten-2'
                   clearable
-                  hint='Leave empty for no end date'
+                  :hint='$t(`editor:props.publishEndHint`)'
                   persistent-hint
                   :disabled='!isPublished'
                   )
@@ -170,12 +170,12 @@
                     flat=''
                     color='primary'
                     @click='isPublishEndShown = false'
-                    ) Cancel
+                    ) {{$t('common:actions.cancel')}}
                   v-btn(
                     flat=''
                     color='primary'
                     @click='$refs.menuPublishEnd.save(publishEndDate)'
-                    ) OK
+                    ) {{$t('common:actions.ok')}}
 
     page-selector(mode='create', v-model='pageSelectorShown', :path='path', :locale='locale', :open-handler='setPath')
     v-tour(name='editorPropertiesTour', :steps='tourSteps')

+ 4 - 4
client/components/editor/editor-modal-unsaved.vue

@@ -3,13 +3,13 @@
     v-card.wiki-form
       .dialog-header.is-short.is-red
         v-icon.mr-2(color='white') warning
-        span Discard Unsaved Changes?
+        span {{$t('editor:unsaved.title')}}
       v-card-text
-        .body-2 You have unsaved changes. Are you sure you want to leave the editor and discard any modifications you made since the last save?
+        .body-2 {{$t('editor:unsaved.body')}}
       v-card-chin
         v-spacer
-        v-btn(flat, @click='isShown = false') Cancel
-        v-btn(color='red', @click='discard', dark) Discard Changes
+        v-btn(flat, @click='isShown = false') {{$t('common:actions.cancel')}}
+        v-btn(color='red', @click='discard', dark) {{$t('common:actions.discardChanges')}}
 </template>
 
 <script>