2
0

admin-utilities-importv1.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. <template lang='pug'>
  2. v-card
  3. v-toolbar(flat, color='primary', dark, dense)
  4. .subtitle-1 {{ $t('admin:utilities.importv1Title') }}
  5. v-card-text
  6. .text-center
  7. img.animated.fadeInUp.wait-p1s(src='/svg/icon-software.svg')
  8. .body-2 Import from Wiki.js 1.x
  9. v-divider.my-4
  10. .body-2 Data from a Wiki.js 1.x installation can easily be imported using this tool. What do you want to import?
  11. v-checkbox(
  12. label='Content + Uploads'
  13. value='content'
  14. color='deep-orange darken-2'
  15. v-model='importFilters'
  16. hide-details
  17. )
  18. template(v-slot:label)
  19. strong.deep-orange--text.text--darken-2 Content + Uploads
  20. .pl-8(v-if='wantContent')
  21. v-radio-group(v-model='contentMode', hide-details)
  22. v-radio(
  23. value='git'
  24. color='primary'
  25. )
  26. template(v-slot:label)
  27. div
  28. span Import from Git Connection
  29. .caption: em #[strong.primary--text Recommended] | The Git storage module will also be configured for you.
  30. .pl-8.mt-5(v-if='needGit')
  31. v-row
  32. v-col(cols='8')
  33. v-select(
  34. label='Authentication Mode'
  35. :items='gitAuthModes'
  36. v-model='gitAuthMode'
  37. outlined
  38. hide-details
  39. )
  40. v-col(cols='4')
  41. v-switch(
  42. label='Verify SSL Certificate'
  43. v-model='gitVerifySSL'
  44. hide-details
  45. color='primary'
  46. )
  47. v-col(cols='8')
  48. v-text-field(
  49. outlined
  50. label='Repository URL'
  51. :placeholder='(gitAuthMode === `ssh`) ? `e.g. git@github.com:orgname/repo.git` : `e.g. https://github.com/orgname/repo.git`'
  52. hide-details
  53. v-model='gitRepoUrl'
  54. )
  55. v-col(cols='4')
  56. v-text-field(
  57. label='Branch'
  58. placeholder='e.g. master'
  59. v-model='gitRepoBranch'
  60. outlined
  61. hide-details
  62. )
  63. v-col(v-if='gitAuthMode === `ssh`', cols='12')
  64. v-textarea(
  65. outlined
  66. label='Private Key'
  67. placeholder='-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----'
  68. hide-details
  69. v-model='gitPrivKey'
  70. )
  71. template(v-else-if='gitAuthMode === `basic`')
  72. v-col(cols='6')
  73. v-text-field(
  74. label='Username'
  75. v-model='gitUserEmail'
  76. outlined
  77. hide-details
  78. )
  79. v-col(cols='6')
  80. v-text-field(
  81. type='password'
  82. label='Password / PAT'
  83. v-model='gitUserName'
  84. outlined
  85. hide-details
  86. )
  87. v-col(cols='6')
  88. v-text-field(
  89. label='Default Author Email'
  90. placeholder='e.g. name@company.com'
  91. v-model='gitUserEmail'
  92. outlined
  93. hide-details
  94. )
  95. v-col(cols='6')
  96. v-text-field(
  97. label='Default Author Name'
  98. placeholder='e.g. John Smith'
  99. v-model='gitUserName'
  100. outlined
  101. hide-details
  102. )
  103. v-col(cols='12')
  104. v-text-field(
  105. label='Local Repository Path'
  106. placeholder='e.g. ./data/repo'
  107. v-model='gitRepoPath'
  108. outlined
  109. hide-details
  110. )
  111. v-radio-group(v-model='contentMode', hide-details)
  112. v-divider
  113. v-radio.mt-3(
  114. value='local'
  115. color='primary'
  116. )
  117. template(v-slot:label)
  118. div
  119. span Import from local folder
  120. .caption: em Choose this option only if you didn't have git configured in your Wiki.js 1.x installation.
  121. .pl-8.mt-5(v-if='needDisk')
  122. v-text-field(
  123. outlined
  124. label='Content Repo Path'
  125. hint='The absolute path to where the Wiki.js 1.x content is stored on disk.'
  126. persistent-hint
  127. v-model='contentPath'
  128. )
  129. v-checkbox(
  130. label='Users'
  131. value='users'
  132. color='deep-orange darken-2'
  133. v-model='importFilters'
  134. hide-details
  135. )
  136. template(v-slot:label)
  137. strong.deep-orange--text.text--darken-2 Users
  138. .pl-8.mt-5(v-if='wantUsers')
  139. v-text-field(
  140. outlined
  141. label='MongoDB Connection String'
  142. hint='The connection string to connect to the Wiki.js 1.x MongoDB database.'
  143. persistent-hint
  144. v-model='dbConnStr'
  145. )
  146. v-radio-group(v-model='groupMode', hide-details, mandatory)
  147. v-radio(
  148. value='MULTI'
  149. color='primary'
  150. )
  151. template(v-slot:label)
  152. div
  153. span Create groups for each unique user permissions configuration
  154. .caption: em Note that this can result in a large amount of groups being created.
  155. v-divider
  156. v-radio.mt-3(
  157. value='SINGLE'
  158. color='primary'
  159. )
  160. template(v-slot:label)
  161. div
  162. span Create a single group with all imported users
  163. .caption: em #[strong.primary--text Recommended] | The new group will have read permissions enabled by default.
  164. v-divider
  165. v-radio.mt-3(
  166. value='NONE'
  167. color='primary'
  168. )
  169. template(v-slot:label)
  170. div
  171. span Don't create any group
  172. .caption: em Users will not be able to access your wiki until they are assigned to a group.
  173. v-card-chin
  174. v-btn.px-3(depressed, color='deep-orange darken-2', :disabled='!wantUsers && !wantContent', @click='startImport').ml-0
  175. v-icon(left, color='white') mdi-database-import
  176. span.white--text Start Import
  177. v-dialog(
  178. v-model='isLoading'
  179. persistent
  180. max-width='350'
  181. )
  182. v-card(color='deep-orange darken-2', dark)
  183. v-card-text.pa-10.text-center
  184. semipolar-spinner.animated.fadeIn(
  185. :animation-duration='1500'
  186. :size='65'
  187. color='#FFF'
  188. style='margin: 0 auto;'
  189. )
  190. .mt-5.body-1.white--text Importing from Wiki.js 1.x...
  191. .caption Please wait
  192. v-progress-linear.mt-5(
  193. color='white'
  194. :value='progress'
  195. stream
  196. rounded
  197. :buffer-value='0'
  198. )
  199. v-dialog(
  200. v-model='isSuccess'
  201. persistent
  202. max-width='350'
  203. )
  204. v-card(color='green darken-2', dark)
  205. v-card-text.pa-10.text-center
  206. v-icon(size='60') mdi-check-circle-outline
  207. .my-5.body-1.white--text Import completed
  208. template(v-if='wantUsers')
  209. .body-2
  210. span #[strong {{successUsers}}] users imported
  211. v-btn.text-none.ml-3(
  212. v-if='failedUsers.length > 0'
  213. text
  214. color='white'
  215. dark
  216. @click='showFailedUsers = true'
  217. )
  218. v-icon(left) mdi-alert
  219. span {{failedUsers.length}} failed
  220. .body-2 #[strong {{successGroups}}] groups created
  221. template(v-if='wantContent')
  222. .body-2 #[strong {{successPages}}] pages
  223. .body-2 #[strong {{successAssets}}] assets
  224. v-card-actions.green.darken-1
  225. v-spacer
  226. v-btn.px-5(
  227. color='white'
  228. outlined
  229. @click='isSuccess = false'
  230. ) Close
  231. v-spacer
  232. v-dialog(
  233. v-model='showFailedUsers'
  234. persistent
  235. max-width='800'
  236. )
  237. v-card(color='red darken-2', dark)
  238. v-toolbar(color='red darken-2', dense)
  239. v-icon mdi-alert
  240. .body-2.pl-3 Failed User Imports
  241. v-spacer
  242. v-btn.px-5(
  243. color='white'
  244. text
  245. @click='showFailedUsers = false'
  246. ) Close
  247. v-simple-table(dense, fixed-header, height='300px')
  248. template(v-slot:default)
  249. thead
  250. tr
  251. th Provider
  252. th Email
  253. th Error
  254. tbody
  255. tr(v-for='(fusr, idx) in failedUsers', :key='`fusr-` + idx')
  256. td {{fusr.provider}}
  257. td {{fusr.email}}
  258. td {{fusr.error}}
  259. </template>
  260. <script>
  261. import _ from 'lodash'
  262. import { SemipolarSpinner } from 'epic-spinners'
  263. import utilityImportv1UsersMutation from 'gql/admin/utilities/utilities-mutation-importv1-users.gql'
  264. export default {
  265. components: {
  266. SemipolarSpinner
  267. },
  268. data() {
  269. return {
  270. importFilters: ['content', 'users'],
  271. groupMode: 'SINGLE',
  272. contentMode: 'git',
  273. dbConnStr: 'mongodb://',
  274. contentPath: '/wiki-v1/repo',
  275. isLoading: false,
  276. isSuccess: false,
  277. gitAuthMode: 'ssh',
  278. gitAuthModes: [
  279. { text: 'SSH', value: 'ssh' },
  280. { text: 'Basic', value: 'basic' }
  281. ],
  282. gitVerifySSL: true,
  283. gitRepoUrl: '',
  284. gitRepoBranch: 'master',
  285. gitPrivKey: '',
  286. gitUserEmail: '',
  287. gitUserName: '',
  288. gitRepoPath: './data/repo',
  289. progress: 0,
  290. successUsers: 0,
  291. successPages: 0,
  292. successGroups: 0,
  293. successAssets: 0,
  294. showFailedUsers: false,
  295. failedUsers: []
  296. }
  297. },
  298. computed: {
  299. wantContent () {
  300. return this.importFilters.indexOf('content') >= 0
  301. },
  302. wantUsers () {
  303. return this.importFilters.indexOf('users') >= 0
  304. },
  305. needDisk () {
  306. return this.contentMode === `local`
  307. },
  308. needGit () {
  309. return this.contentMode === `git`
  310. }
  311. },
  312. methods: {
  313. async startImport () {
  314. this.isLoading = true
  315. this.progress = 0
  316. this.failedUsers = []
  317. // -> Import Users
  318. if (this.wantUsers) {
  319. try {
  320. const resp = await this.$apollo.mutate({
  321. mutation: utilityImportv1UsersMutation,
  322. variables: {
  323. mongoDbConnString: this.dbConnStr,
  324. groupMode: this.groupMode
  325. }
  326. })
  327. const respObj = _.get(resp, 'data.system.importUsersFromV1', {})
  328. if (!_.get(respObj, 'responseResult.succeeded', false)) {
  329. throw new Error(_.get(respObj, 'responseResult.message', 'An unexpected error occured'))
  330. }
  331. this.successUsers = _.get(respObj, 'usersCount', 0)
  332. this.successGroups = _.get(respObj, 'groupsCount', 0)
  333. this.failedUsers = _.get(respObj, 'failed', [])
  334. this.progress += 50
  335. } catch (err) {
  336. this.$store.commit('pushGraphError', err)
  337. this.isLoading = false
  338. return
  339. }
  340. }
  341. // -> Import Content
  342. if (this.wantContent) {
  343. }
  344. this.isLoading = false
  345. this.isSuccess = true
  346. }
  347. }
  348. }
  349. </script>
  350. <style lang='scss'>
  351. </style>