@oxygen-cms/ui 1.4.0 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/.eslintrc.js +23 -0
  2. package/.github/workflows/node.js.yml +4 -4
  3. package/.idea/modules.xml +8 -0
  4. package/.idea/ui.iml +10 -0
  5. package/package.json +13 -5
  6. package/src/AuthApi.js +77 -42
  7. package/src/CrudApi.js +3 -3
  8. package/src/GroupsApi.js +9 -0
  9. package/src/MediaDirectoryApi.js +1 -1
  10. package/src/PreferencesApi.js +2 -0
  11. package/src/UserPermissions.js +2 -9
  12. package/src/UserPreferences.js +0 -4
  13. package/src/UserPreferences.test.js +0 -2
  14. package/src/UsersApi.js +41 -0
  15. package/src/api.js +96 -38
  16. package/src/components/App.vue +19 -240
  17. package/src/components/AuthenticatedLayout.vue +254 -0
  18. package/src/components/AuthenticationLog.vue +86 -30
  19. package/src/components/CodeEditor.vue +16 -32
  20. package/src/components/EditButtonOnRowHover.vue +21 -0
  21. package/src/components/Error404.vue +15 -5
  22. package/src/components/EventsChooser.vue +11 -11
  23. package/src/components/EventsTable.vue +14 -8
  24. package/src/components/GenericEditableField.vue +74 -0
  25. package/src/components/GroupsChooser.vue +58 -0
  26. package/src/components/GroupsList.vue +129 -0
  27. package/src/components/ImportExport.vue +32 -1
  28. package/src/components/LegacyPage.vue +22 -23
  29. package/src/components/UserJoined.vue +35 -0
  30. package/src/components/UserManagement.vue +168 -0
  31. package/src/components/UserProfileForm.vue +214 -0
  32. package/src/components/ViewProfile.vue +7 -219
  33. package/src/components/auth/Auth404.vue +16 -0
  34. package/src/components/auth/Login.vue +135 -0
  35. package/src/components/auth/LoginLogo.vue +30 -0
  36. package/src/components/auth/Logout.vue +26 -0
  37. package/src/components/auth/PasswordRemind.vue +71 -0
  38. package/src/components/auth/PasswordReset.vue +97 -0
  39. package/src/components/auth/TwoFactorSetup.vue +115 -0
  40. package/src/components/auth/VerifyEmail.vue +71 -0
  41. package/src/components/auth/WelcomeFloat.vue +87 -0
  42. package/src/components/auth/login.scss +17 -0
  43. package/src/components/{MediaChooseDirectory.vue → media/MediaChooseDirectory.vue} +12 -12
  44. package/src/components/{MediaDirectory.vue → media/MediaDirectory.vue} +8 -8
  45. package/src/components/{MediaInsertModal.vue → media/MediaInsertModal.vue} +2 -2
  46. package/src/components/{MediaItem.vue → media/MediaItem.vue} +24 -23
  47. package/src/components/{MediaItemPreview.vue → media/MediaItemPreview.vue} +5 -5
  48. package/src/components/{MediaList.vue → media/MediaList.vue} +42 -38
  49. package/src/components/{MediaPage.vue → media/MediaPage.vue} +1 -1
  50. package/src/components/{MediaResponsiveImages.vue → media/MediaResponsiveImages.vue} +5 -5
  51. package/src/components/{MediaUpload.vue → media/MediaUpload.vue} +10 -10
  52. package/src/components/{media.scss → media/media.scss} +1 -1
  53. package/src/components/preferences/PreferencesField.vue +10 -10
  54. package/src/components/preferences/PreferencesList.vue +13 -20
  55. package/src/components/preferences/PreferencesThemeChooser.vue +9 -9
  56. package/src/components/preferences/ShowIfPermitted.vue +9 -14
  57. package/src/components/users/CreateUserModal.vue +73 -0
  58. package/src/icons.js +90 -0
  59. package/src/main.js +111 -0
  60. package/src/modules/LegacyPages.js +18 -0
  61. package/src/modules/Media.js +45 -0
  62. package/src/modules/UserManagement.js +24 -0
  63. package/src/routes/index.js +92 -0
  64. package/src/store/index.js +70 -0
  65. package/src/styles/_variables.scss +1 -0
  66. package/src/styles/app.scss +15 -2
  67. package/src/login.js +0 -17
  68. package/src/routes.js +0 -61
  69. package/src/styles/login.scss +0 -86
@@ -0,0 +1,71 @@
1
+ <template>
2
+ <div class="box container">
3
+ <LoginLogo />
4
+
5
+ <h1 class="subtitle has-text-centered">
6
+ <span v-if="success">
7
+ Password reset link sent!
8
+ </span>
9
+ <span v-else>Forgot Password</span>
10
+ </h1>
11
+
12
+ <transition name="fade" mode="out-in">
13
+ <div v-if="!success">
14
+ <p>Enter the email address associated with your account, and we'll send you a link to reset your password.</p>
15
+ <br />
16
+ <b-field label="Email Address" label-position="inside">
17
+ <b-input v-model="accountEmail" name="email" type="email" required @keyup.enter.native="submitForm"></b-input>
18
+ </b-field>
19
+
20
+ <div class="login-justify-content">
21
+ <b-button type="is-primary" :loading="submitting" @click="submitForm">Send Reminder Email</b-button>
22
+ <router-link to="/auth/login">
23
+ Back to Login
24
+ </router-link>
25
+ </div>
26
+ </div>
27
+ <div v-else>
28
+ <p>Please check your email for further instructions on how to complete the process.</p>
29
+ </div>
30
+ </transition>
31
+
32
+
33
+ </div>
34
+ </template>
35
+
36
+ <script>
37
+
38
+ import LoginLogo from "./LoginLogo.vue";
39
+ import AuthApi from "../../AuthApi";
40
+ import {morphToNotification} from "../../api";
41
+
42
+ export default {
43
+ name: "PasswordRemind",
44
+ components: { LoginLogo },
45
+ data() {
46
+ return {
47
+ authApi: new AuthApi(this.$buefy),
48
+ accountEmail: '',
49
+ success: false,
50
+ submitting: false,
51
+ }
52
+ },
53
+ methods: {
54
+ async submitForm() {
55
+ try {
56
+ this.submitting = true;
57
+ let response = await this.authApi.sendReminderEmail(this.accountEmail);
58
+ this.$buefy.notification.open(morphToNotification(response));
59
+ this.success = true;
60
+ } catch(e) {
61
+ // let the user try again
62
+ }
63
+ this.submitting = false;
64
+ }
65
+ }
66
+ }
67
+ </script>
68
+
69
+ <style scoped>
70
+
71
+ </style>
@@ -0,0 +1,97 @@
1
+ <template>
2
+ <div class="box container">
3
+ <LoginLogo />
4
+
5
+ <h1 class="subtitle has-text-centered">
6
+ <span v-if="successfullyReset">Password Reset Successful!</span>
7
+ <span v-else-if="hasRequiredParams">Reset Your Password</span>
8
+ <span v-else>Invalid password reset link</span>
9
+ </h1>
10
+
11
+ <div v-if="successfullyReset" class="content">
12
+ <p>
13
+ Your password reset request was successful. You should now be able to login with your new password.
14
+ </p>
15
+ <div class="is-flex is-justify-content-center">
16
+ <b-button tag="router-link" to="/auth/login" type="is-success">Login</b-button>
17
+ </div>
18
+ </div>
19
+ <div v-else-if="hasRequiredParams">
20
+ <div class="content">
21
+ <p>Enter a new, secure password to use for this account.<br />It is recommended you use a password manager to keep your passwords unique and random.</p>
22
+ </div>
23
+
24
+ <b-field label="New Password" label-position="inside">
25
+ <b-input v-model="password" type="password"></b-input>
26
+ </b-field>
27
+
28
+ <b-field label="New Password Again" label-position="inside"
29
+ :type="passwordsMatch ? '' : 'is-danger'"
30
+ :message="passwordsMatch ? '' : 'Passwords do not match'">
31
+ <b-input v-model="passwordConfirmation" type="password" @keyup.native.enter="submit"></b-input>
32
+ </b-field>
33
+
34
+ <div class="login-justify-content">
35
+ <b-button type="is-primary" :disabled="!passwordsMatch" :loading="submitting" @click="submit">Reset</b-button>
36
+ <router-link to="/auth/login">
37
+ Back to Login
38
+ </router-link>
39
+ </div>
40
+ </div>
41
+ <div v-else class="content">
42
+ <p>One or more required parameters were missing from the link. Double-check that you have used the correct password reset link.</p>
43
+ </div>
44
+
45
+ </div>
46
+ </template>
47
+
48
+ <script>
49
+ import LoginLogo from "./LoginLogo.vue";
50
+ import AuthApi from "../../AuthApi";
51
+ import {morphToNotification} from "../../api";
52
+ export default {
53
+ name: "PasswordReset",
54
+ components: {LoginLogo},
55
+ data() {
56
+ return {
57
+ authApi: new AuthApi(this.$buefy),
58
+ password: '',
59
+ passwordConfirmation: '',
60
+ submitting: false,
61
+ successfullyReset: false
62
+ };
63
+ },
64
+ computed: {
65
+ hasRequiredParams() {
66
+ return this.$route.query.email && this.$route.query.token;
67
+ },
68
+ passwordsMatch() {
69
+ return this.password === this.passwordConfirmation;
70
+ }
71
+ },
72
+ methods: {
73
+ async submit() {
74
+ let req = {
75
+ password: this.password,
76
+ password_confirmation: this.passwordConfirmation,
77
+ email: this.$route.query.email,
78
+ token: this.$route.query.token
79
+ };
80
+ console.log(req);
81
+ this.submitting = true;
82
+ try {
83
+ let data = await this.authApi.resetPassword(req);
84
+ this.$buefy.notification.open(morphToNotification(data));
85
+ this.successfullyReset = true;
86
+ } catch(e) {
87
+ // let the user try again
88
+ }
89
+ this.submitting = false;
90
+ }
91
+ }
92
+ }
93
+ </script>
94
+
95
+ <style scoped>
96
+
97
+ </style>
@@ -0,0 +1,115 @@
1
+ <template>
2
+ <div class="box container is-wider two-factor-setup">
3
+ <LoginLogo />
4
+
5
+ <transition name="fade" mode="out-in">
6
+ <div v-if="twoFactorQRCode">
7
+ <h1 class="subtitle has-text-centered">
8
+ You need to set up two-factor authentication for this account.
9
+ </h1>
10
+
11
+ <div class="content">
12
+ <p>Two-factor authentication uses once-off codes from another device (e.g.: your phone) for additional security. To use two-factor authentication with Oxygen CMS, you need to download an authenticator app onto your phone.</p>
13
+ <p>Supported apps include:</p>
14
+ <ul>
15
+ <li>Google Authenticator</li>
16
+ <li><a href="https://lastpass.com/auth/" target="_blank">LastPass Authenticator</a></li>
17
+ <li><a href="https://www.microsoft.com/en-us/account/authenticator" target="_blank">Microsoft Authenticator</a></li>
18
+ <li><a href="https://authy.com/features/" target="_blank">Authy</a></li>
19
+ </ul>
20
+ </div>
21
+
22
+ <h2 class="subtitle">Getting started</h2>
23
+ <p>Scan the QR code below on your phone to begin setting up two-factor authentication, or follow <a :href="twoFactorUri">this link</a>.</p>
24
+
25
+ <div class="qr-code">
26
+ <div v-html="twoFactorQRCode"></div>
27
+ </div>
28
+
29
+ <p>Or, manually enter this secret key into your chosen authenticator app:<br><br>
30
+ <pre>{{ twoFactorString }}</pre></p>
31
+
32
+ <br>
33
+ <h2 class="subtitle">Confirm a two-factor code to continue</h2>
34
+ <p>Once you've successfully configured your authenticator app, enter a valid code below to continue.</p>
35
+ <br>
36
+
37
+ <div class="level">
38
+ <div class="level-left">
39
+ <b-field label="2FA Code" label-position="inside" :type="failedValidation ? 'is-danger' : ''">
40
+ <b-input v-model="totpCode" name="2fa_code" type="number" autofocus minlength="6" required placeholder="enter code here" @keyup.enter.native="confirm2FA"></b-input>
41
+ </b-field>
42
+ </div>
43
+ <div class="level-right">
44
+ <b-button type="is-primary" :loading="submitting" @click="confirm2FA">Confirm</b-button>
45
+ </div>
46
+ </div>
47
+ </div>
48
+ <div v-else style="height=20rem;"></div>
49
+ </transition>
50
+
51
+ <b-loading :active="!twoFactorQRCode" :is-full-page="false"></b-loading>
52
+
53
+ </div>
54
+ </template>
55
+
56
+ <script>
57
+ import AuthApi from "../../AuthApi";
58
+ import LoginLogo from "./LoginLogo.vue";
59
+ import {morphToNotification} from "../../api";
60
+
61
+ export default {
62
+ name: "TwoFactorSetup",
63
+ components: { LoginLogo },
64
+ data() {
65
+ return {
66
+ twoFactorUri: null,
67
+ twoFactorString: null,
68
+ twoFactorQRCode: null,
69
+ totpCode: '',
70
+ failedValidation: false,
71
+ submitting: false,
72
+ authApi: new AuthApi(this.$buefy)
73
+ }
74
+ },
75
+ async created() {
76
+ try {
77
+ let data = await this.authApi.setupTwoFactorAuth();
78
+ this.twoFactorUri = data.as_uri;
79
+ this.twoFactorString = data.as_string;
80
+ this.twoFactorQRCode = data.as_qr_code;
81
+ } catch(e) {
82
+ console.log('Already set up?');
83
+ }
84
+ },
85
+ methods: {
86
+ async confirm2FA() {
87
+ try {
88
+ this.submitting = true;
89
+ let response = await this.authApi.confirmTwoFactorAuth(this.totpCode);
90
+ this.$buefy.notification.open(morphToNotification(response));
91
+ this.$router.push('/');
92
+ } catch(e) {
93
+ this.failedValidation = true;
94
+ }
95
+ this.submitting = false;
96
+ }
97
+ }
98
+ }
99
+ </script>
100
+
101
+ <style scoped lang="scss">
102
+ @import './login.scss';
103
+
104
+ .qr-code {
105
+ padding: 1rem 0;
106
+ }
107
+
108
+ .qr-code ::v-deep .b-skeleton {
109
+ max-width: 200px;
110
+ }
111
+
112
+ .two-factor-setup {
113
+ position: relative;
114
+ }
115
+ </style>
@@ -0,0 +1,71 @@
1
+ <template>
2
+ <div class="box container">
3
+ <LoginLogo />
4
+
5
+ <h1 class="subtitle has-text-centered">
6
+ You need to verify your email address to continue
7
+ </h1>
8
+
9
+ <transition name="fade">
10
+ <div v-if="sent" class="content">
11
+ <p>An email has been sent to your inbox with a confirmation link. You need to open the link to continue.</p>
12
+ <p>If you don't receive the email in the next few minutes, we can try and send it again.</p>
13
+ <b-button type="is-link" @click="send">Retry</b-button>
14
+ </div>
15
+ <div v-else-if="sendFailure" class="content">
16
+ <p>The email failed to send.</p>
17
+ <b-button type="is-link" @click="send">Retry</b-button>
18
+ </div>
19
+ <div v-else class="content has-text-centered">
20
+ <p>Sending verification email...</p>
21
+ <b-progress ></b-progress>
22
+ </div>
23
+ </transition>
24
+ </div>
25
+ </template>
26
+
27
+ <script>
28
+ import LoginLogo from './LoginLogo.vue';
29
+ import AuthApi from "../../AuthApi";
30
+
31
+ export default {
32
+ name: "VerifyEmail",
33
+ components: { LoginLogo },
34
+ data() {
35
+ return {
36
+ authApi: new AuthApi(this.$buefy),
37
+ sent: false,
38
+ sendFailure: false
39
+ }
40
+ },
41
+ async created() {
42
+ await this.send()
43
+ },
44
+ methods: {
45
+ async send() {
46
+ this.sent = false;
47
+ try {
48
+ await this.authApi.sendEmailVerification();
49
+ this.sent = true;
50
+ } catch(e) {
51
+ if(e.response && e.response.code === 'already_verified') {
52
+ this.$buefy.notification.open({
53
+ message: 'Email address already verified',
54
+ type: 'is-info',
55
+ queue: false,
56
+ duration: 4000
57
+ });
58
+ await this.$router.push({path: '/'});
59
+ } else {
60
+ this.sendFailure = true;
61
+ throw e;
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
67
+ </script>
68
+
69
+ <style scoped>
70
+ @import './login.scss';
71
+ </style>
@@ -0,0 +1,87 @@
1
+ <template>
2
+ <!-- {{ Preferencesimport Vuex from 'vuex';::get('appearance.auth::theme', 'autumn') }}-->
3
+ <div class="login-fullscreen">
4
+ <b-loading :active="theme === null"></b-loading>
5
+ <transition name="fade">
6
+ <div v-if="theme !== null" :class="'login-background login-theme-' + theme">
7
+ <transition name="slide-left" mode="out-in">
8
+ <router-view></router-view>
9
+ </transition>
10
+ </div>
11
+ </transition>
12
+
13
+
14
+ </div>
15
+ </template>
16
+
17
+ <script>
18
+ import AuthApi from "../../AuthApi";
19
+
20
+ export default {
21
+ name: "WelcomeFloat",
22
+ data() {
23
+ return {
24
+ theme: null,
25
+ authApi: new AuthApi(this.$buefy)
26
+ }
27
+ },
28
+ async created() {
29
+ let preferences = await this.authApi.getLoginPreferences();
30
+ this.theme = preferences.theme;
31
+ }
32
+ }
33
+ </script>
34
+
35
+ <style scoped>
36
+ .login-fullscreen {
37
+ height: 100%;
38
+ overflow: auto;
39
+ }
40
+
41
+ .login-background {
42
+ min-height: 100%;
43
+ background-attachment: fixed;
44
+ background-size: cover;
45
+ display: flex;
46
+ flex-direction: column;
47
+ justify-content: center;
48
+ overflow-y: auto;
49
+ }
50
+
51
+ .login-theme-autumn {
52
+ background-image: url('/vendor/oxygen/ui-theme/img/bg/autumn-min.jpg');
53
+ }
54
+
55
+ .login-theme-city {
56
+ background-image: url('/vendor/oxygen/ui-theme/img/bg/city-min.jpg');
57
+ }
58
+
59
+ .login-theme-clouds {
60
+ background-image: url('/vendor/oxygen/ui-theme/img/bg/clouds-min.jpg');
61
+ }
62
+
63
+ .login-theme-coast {
64
+ background-image: url('/vendor/oxygen/ui-theme/img/bg/coast-min.jpg');
65
+ }
66
+
67
+ .login-theme-speckles {
68
+ background-image: url('/vendor/oxygen/ui-theme/img/bg/speckles-min.jpg');
69
+ }
70
+
71
+ .login-theme-trees {
72
+ background-image: url('/vendor/oxygen/ui-theme/img/bg/trees-min.jpg');
73
+ }
74
+
75
+ .login-theme-waves {
76
+ background-image: url('/vendor/oxygen/ui-theme/img/bg/waves.jpg');
77
+ }
78
+
79
+ .login-theme-yosemite {
80
+ background-image: url('/vendor/oxygen/ui-theme/img/bg/yosemite-falls-min.jpg');
81
+ }
82
+
83
+ .login-theme-white {
84
+ background-color: white;
85
+ }
86
+
87
+ </style>
@@ -0,0 +1,17 @@
1
+ .login-justify-content {
2
+ display: flex;
3
+ flex-direction: row-reverse;
4
+ justify-content: space-between;
5
+ align-items: center;
6
+ }
7
+
8
+ .login-fullscreen .container {
9
+ flex-grow: 0;
10
+ margin: 2rem auto;
11
+ width: 25em;
12
+ }
13
+
14
+ .login-fullscreen .container.is-wider {
15
+ width: 90%;
16
+ max-width: 55em;
17
+ }
@@ -1,10 +1,10 @@
1
1
  <template>
2
2
  <b-dropdown
3
+ ref="dropdown"
3
4
  position="is-top-left"
4
5
  append-to-body
5
6
  aria-role="menu"
6
7
  trap-focus
7
- ref="dropdown"
8
8
  class="choose-directory-dropdown"
9
9
  >
10
10
  <template #trigger>
@@ -26,8 +26,8 @@
26
26
  <section class="modal-card-body" style="overflow: visible;">
27
27
  <b-field>
28
28
  <b-autocomplete
29
- :disabled="isLoading"
30
29
  v-model="searchQuery"
30
+ :disabled="isLoading"
31
31
  open-on-focus
32
32
  :data="filteredDirectoriesList"
33
33
  :custom-formatter="data => getDirectoryPathString(data)"
@@ -55,10 +55,16 @@
55
55
  </template>
56
56
 
57
57
  <script>
58
- import MediaDirectoryApi, {getDirectoryPathString} from "../MediaDirectoryApi";
58
+ import MediaDirectoryApi, {getDirectoryPathString} from "../../MediaDirectoryApi";
59
59
 
60
60
  export default {
61
61
  name: "MediaChooseDirectory",
62
+ props: {
63
+ buttonText: {
64
+ type: String,
65
+ default: "Move to directory"
66
+ }
67
+ },
62
68
  data() {
63
69
  return {
64
70
  mediaDirectoryApi: new MediaDirectoryApi(this.$buefy),
@@ -70,15 +76,6 @@ export default {
70
76
  getDirectoryPathString: getDirectoryPathString
71
77
  }
72
78
  },
73
- props: {
74
- buttonText: {
75
- type: String,
76
- default: "Move to directory"
77
- }
78
- },
79
- created() {
80
- this.fetchData()
81
- },
82
79
  computed: {
83
80
  filteredDirectoriesList() {
84
81
  let query = this.searchQuery ? this.searchQuery.toLowerCase() : '';
@@ -89,6 +86,9 @@ export default {
89
86
  })
90
87
  }
91
88
  },
89
+ created() {
90
+ this.fetchData()
91
+ },
92
92
  methods: {
93
93
  async fetchData() {
94
94
  this.isLoading = true;
@@ -5,10 +5,10 @@
5
5
  </div>
6
6
  <div class="card-content">
7
7
  <p class="title is-4 cursor-pointer has-text-centered" @click.exact="select(true)" @click.shift.exact="select(false)">{{ directory.name }}</p>
8
- <p class="subtitle is-6 cursor-pointer has-text-centered" v-if="displayFullPath" @click.exact="select(true)" @click.shift.exact="select(false)">inside '{{ directoryPath }}'</p>
8
+ <p v-if="displayFullPath" class="subtitle is-6 cursor-pointer has-text-centered" @click.exact="select(true)" @click.shift.exact="select(false)">inside '{{ directoryPath }}'</p>
9
9
  <div v-if="directory.selected" class="content media-item-toolbar">
10
10
  <b-button v-if="directory.selected" icon-left="pencil-alt" size="is-small" rounded @click.stop="renameDirectory">Rename</b-button>
11
- <MediaChooseDirectory v-if="directory.selected" @submit="moveToDirectory" button-text="Move">
11
+ <MediaChooseDirectory v-if="directory.selected" button-text="Move" @submit="moveToDirectory">
12
12
  </MediaChooseDirectory>
13
13
  <b-button v-if="directory.selected" icon-left="trash" size="is-small" type="is-danger" rounded outlined @click.stop="confirmDeleteDirectory">Delete</b-button>
14
14
  </div>
@@ -30,7 +30,7 @@
30
30
  <footer class="modal-card-foot is-flex">
31
31
  <div class="is-flex-grow-1"></div>
32
32
  <b-button @click="isEditModalActive = false">Cancel</b-button>
33
- <b-button @click="doRenameDirectory" type="is-primary">Rename</b-button>
33
+ <b-button type="is-primary" @click="doRenameDirectory">Rename</b-button>
34
34
  </footer>
35
35
  </div>
36
36
  </b-modal>
@@ -41,14 +41,15 @@
41
41
  </template>
42
42
 
43
43
  <script>
44
- import MediaDirectoryApi, {getDirectoryPathString} from "../MediaDirectoryApi";
45
- import {morphToNotification} from "../api";
44
+ import MediaDirectoryApi, {getDirectoryPathString} from "../../MediaDirectoryApi";
45
+ import {morphToNotification} from "../../api";
46
46
  import MediaChooseDirectory from "./MediaChooseDirectory.vue";
47
47
 
48
48
  export default {
49
- name: "MediaDirectory.vue",
49
+ name: "MediaDirectory",
50
+ components: { MediaChooseDirectory },
50
51
  props: {
51
- directory: Object,
52
+ directory: { type: Object, required: true },
52
53
  displayFullPath: Boolean
53
54
  },
54
55
  data() {
@@ -64,7 +65,6 @@ export default {
64
65
  return getDirectoryPathString(this.directory.parentDirectory);
65
66
  }
66
67
  },
67
- components: { MediaChooseDirectory },
68
68
  methods: {
69
69
  select(toggle) {
70
70
  // if already selected, then navigate into a directory
@@ -5,12 +5,12 @@
5
5
  <slot name="title"><p class="modal-card-title">Choose an item to insert</p></slot>
6
6
  </header>
7
7
  <section class="modal-card-body">
8
- <MediaList @navigate="onNavigate" @double-click-action="doInsert" @select-files="items => selectedFiles = items" :current-path="currentPath" :in-trash="inTrash" :search-query="searchQuery" />
8
+ <MediaList :current-path="currentPath" :in-trash="inTrash" :search-query="searchQuery" @navigate="onNavigate" @double-click-action="doInsert" @select-files="items => selectedFiles = items" />
9
9
  </section>
10
10
  <footer class="modal-card-foot is-flex">
11
11
  <div class="is-flex-grow-1"></div>
12
12
  <b-button @click="emitClose">Close</b-button>
13
- <b-button @click="doInsert" :disabled="selectedFiles.length === 0 || (!multiselectAllowed && selectedFiles.length > 1)" type="is-primary">
13
+ <b-button :disabled="selectedFiles.length === 0 || (!multiselectAllowed && selectedFiles.length > 1)" type="is-primary" @click="doInsert">
14
14
  <span v-if="selectedFiles.length === 0">{{ actionVerb }}</span>
15
15
  <span v-else-if="selectedFiles.length === 1">{{actionVerb }} item</span>
16
16
  <span v-else-if="multiselectAllowed">{{ actionVerb }} {{ selectedFiles }} items</span>