You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
6.1 KiB

  1. <template lang="pug">
  2. v-app.setup
  3. v-content
  4. v-container
  5. v-layout
  6. v-flex(xs12, lg6, offset-lg3)
  7. v-card.radius-7.animated.fadeInUp
  8. .text-center
  9. img.setup-logo.animated.fadeInUp.wait-p2s(src='/svg/logo-wikijs-full.svg', alt='Wiki.js Logo')
  10. v-alert(v-model='error', type='error', icon='mdi-alert', tile, dismissible) {{ errorMessage }}
  11. v-alert(v-if='!error', tile, color='indigo lighten-5', :value='true')
  12. v-icon.mr-3(color='indigo') mdi-package-variant
  13. span.indigo--text You are about to install Wiki.js #[strong {{wikiVersion}}].
  14. v-card-text
  15. .overline.pl-3 Administrator Account
  16. v-container.pa-3.mt-3(grid-list-xl)
  17. v-layout(row, wrap)
  18. v-flex(xs12)
  19. v-text-field(
  20. outlined
  21. v-model='conf.adminEmail',
  22. label='Administrator Email',
  23. hint='The email address of the administrator account.',
  24. persistent-hint
  25. required
  26. ref='adminEmailInput'
  27. )
  28. v-flex(xs6)
  29. v-text-field(
  30. outlined
  31. ref='adminPassword',
  32. counter='255'
  33. v-model='conf.adminPassword',
  34. label='Password',
  35. :append-icon="pwdMode ? 'mdi-eye-off' : 'mdi-eye'"
  36. @click:append="() => (pwdMode = !pwdMode)"
  37. :type="pwdMode ? 'password' : 'text'"
  38. hint='At least 8 characters long.',
  39. persistent-hint
  40. )
  41. v-flex(xs6)
  42. v-text-field(
  43. outlined
  44. ref='adminPasswordConfirm',
  45. counter='255'
  46. v-model='conf.adminPasswordConfirm',
  47. label='Confirm Password',
  48. :append-icon="pwdConfirmMode ? 'mdi-eye-off' : 'mdi-eye'"
  49. @click:append="() => (pwdConfirmMode = !pwdConfirmMode)"
  50. :type="pwdConfirmMode ? 'password' : 'text'"
  51. hint='Verify your password again.',
  52. persistent-hint
  53. @keyup.enter='install'
  54. )
  55. v-divider.mb-4
  56. v-checkbox.ml-3(
  57. color='primary',
  58. v-model='conf.telemetry',
  59. label='Allow Telemetry',
  60. persistent-hint,
  61. hint='Help Wiki.js developers improve this app with anonymized telemetry.'
  62. )
  63. v-divider.mt-2
  64. v-card-actions
  65. v-btn(color='primary', @click='install', :disabled='loading', x-large, depressed, block)
  66. v-icon(left) mdi-check
  67. span Install
  68. v-dialog(v-model='loading', width='450', persistent)
  69. v-card(color='primary', dark).radius-7
  70. v-card-text.text-center.py-5
  71. .py-3(style='width: 64px; display:inline-block;')
  72. breeding-rhombus-spinner(
  73. :animation-duration='2000'
  74. :size='64'
  75. color='#FFF'
  76. )
  77. template(v-if='!success')
  78. .subtitle-1.white--text Finalizing your installation...
  79. .caption Just a moment
  80. template(v-else)
  81. .subtitle-1.white--text Installation complete!
  82. .caption Redirecting...
  83. </template>
  84. <script>
  85. import _ from 'lodash'
  86. import validate from 'validate.js'
  87. import { BreedingRhombusSpinner } from 'epic-spinners'
  88. export default {
  89. components: {
  90. BreedingRhombusSpinner
  91. },
  92. props: {
  93. wikiVersion: {
  94. type: String,
  95. required: true
  96. }
  97. },
  98. data() {
  99. return {
  100. loading: false,
  101. success: false,
  102. error: false,
  103. errorMessage: '',
  104. conf: {
  105. adminEmail: '',
  106. adminPassword: '',
  107. adminPasswordConfirm: '',
  108. telemetry: true
  109. },
  110. pwdMode: true,
  111. pwdConfirmMode: true
  112. }
  113. },
  114. mounted() {
  115. _.delay(() => {
  116. this.$refs.adminEmailInput.focus()
  117. }, 500)
  118. },
  119. methods: {
  120. async install () {
  121. this.error = false
  122. const validationResults = validate(this.conf, {
  123. adminEmail: {
  124. presence: {
  125. allowEmpty: false
  126. },
  127. email: true
  128. },
  129. adminPassword: {
  130. presence: {
  131. allowEmpty: false
  132. },
  133. length: {
  134. minimum: 6,
  135. maximum: 255
  136. }
  137. },
  138. adminPasswordConfirm: {
  139. equality: 'adminPassword'
  140. }
  141. }, {
  142. format: 'flat'
  143. })
  144. if (validationResults) {
  145. this.error = true
  146. this.errorMessage = validationResults[0]
  147. this.$forceUpdate()
  148. return
  149. }
  150. this.loading = true
  151. this.success = false
  152. this.$forceUpdate()
  153. _.delay(async () => {
  154. try {
  155. const resp = await fetch('/finalize', {
  156. method: 'POST',
  157. cache: 'no-cache',
  158. headers: {
  159. 'Content-Type': 'application/json'
  160. },
  161. body: JSON.stringify(this.conf)
  162. }).then(res => res.json())
  163. if (resp.ok === true) {
  164. this.success = true
  165. _.delay(() => {
  166. window.location.assign('/login')
  167. }, 3000)
  168. } else {
  169. this.error = true
  170. this.errorMessage = resp.error
  171. this.loading = false
  172. }
  173. } catch (err) {
  174. window.alert(err.message)
  175. }
  176. }, 1000)
  177. }
  178. }
  179. }
  180. </script>
  181. <style lang='scss'>
  182. .setup {
  183. .v-application--wrap {
  184. padding-top: 10vh;
  185. background-color: darken(mc('grey', '900'), 5%);
  186. background-image: url(/svg/motif-circuit.svg) !important;
  187. background-repeat: repeat;
  188. }
  189. &-logo {
  190. width: 400px;
  191. margin: 2rem 0 2rem 0;
  192. }
  193. }
  194. </style>