rails_admin_image_manager 0.1.3

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 (83) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +125 -0
  4. data/Rakefile +36 -0
  5. data/app/assets/config/rails_admin_image_manager_manifest.js +2 -0
  6. data/app/assets/fonts/FontAwesome.otf +0 -0
  7. data/app/assets/fonts/Simple-Line-Icons.eot +0 -0
  8. data/app/assets/fonts/Simple-Line-Icons.svg +1369 -0
  9. data/app/assets/fonts/Simple-Line-Icons.ttf +0 -0
  10. data/app/assets/fonts/Simple-Line-Icons.woff +0 -0
  11. data/app/assets/fonts/fontawesome-webfont.eot +0 -0
  12. data/app/assets/fonts/fontawesome-webfont.svg +2671 -0
  13. data/app/assets/fonts/fontawesome-webfont.ttf +0 -0
  14. data/app/assets/fonts/fontawesome-webfont.woff +0 -0
  15. data/app/assets/fonts/fontawesome-webfont.woff2 +0 -0
  16. data/app/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  17. data/app/assets/fonts/glyphicons-halflings-regular.svg +288 -0
  18. data/app/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  19. data/app/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  20. data/app/assets/fonts/glyphicons-halflings-regular.woff2 +0 -0
  21. data/app/assets/images/rails_admin_image_manager/image.png +0 -0
  22. data/app/assets/javascripts/rails_admin_image_manager/app-compiled.js.erb +34896 -0
  23. data/app/assets/javascripts/rails_admin_image_manager/app-vue.js +51 -0
  24. data/app/assets/javascripts/rails_admin_image_manager/application.js +17 -0
  25. data/app/assets/javascripts/rails_admin_image_manager/base.js.erb +62 -0
  26. data/app/assets/javascripts/rails_admin_image_manager/ckeditor_plugin.js.erb +58 -0
  27. data/app/assets/javascripts/rails_admin_image_manager/components/confirmationOverlay.vue +69 -0
  28. data/app/assets/javascripts/rails_admin_image_manager/components/imageInsertButton.vue +41 -0
  29. data/app/assets/javascripts/rails_admin_image_manager/components/imageInsertOverlay.vue +92 -0
  30. data/app/assets/javascripts/rails_admin_image_manager/components/imageListing.vue +167 -0
  31. data/app/assets/javascripts/rails_admin_image_manager/components/imageShow.vue +112 -0
  32. data/app/assets/javascripts/rails_admin_image_manager/components/imageTagSelector.vue +94 -0
  33. data/app/assets/javascripts/rails_admin_image_manager/components/imageUpload.vue +94 -0
  34. data/app/assets/javascripts/rails_admin_image_manager/components/listingFilter.vue +32 -0
  35. data/app/assets/javascripts/rails_admin_image_manager/components/notificationOverlay.vue +47 -0
  36. data/app/assets/javascripts/rails_admin_image_manager/components/progressOverlay.vue +37 -0
  37. data/app/assets/javascripts/rails_admin_image_manager/components/searchAutocomplete.vue +140 -0
  38. data/app/assets/javascripts/rails_admin_image_manager/editor/image_manager_picker.js.erb +41 -0
  39. data/app/assets/javascripts/rails_admin_image_manager/filters/index.js +7 -0
  40. data/app/assets/javascripts/rails_admin_image_manager/libs/helpers.js +13 -0
  41. data/app/assets/javascripts/rails_admin_image_manager/libs/lazyload.js +63 -0
  42. data/app/assets/javascripts/rails_admin_image_manager/router/index.js +55 -0
  43. data/app/assets/javascripts/rails_admin_image_manager/stores/ckeditor.js +25 -0
  44. data/app/assets/javascripts/rails_admin_image_manager/stores/index.js +16 -0
  45. data/app/assets/javascripts/rails_admin_image_manager/stores/medias.js +342 -0
  46. data/app/assets/javascripts/rails_admin_image_manager/stores/overlay.js +57 -0
  47. data/app/assets/javascripts/rails_admin_image_manager/stores/railsAdmin.js +28 -0
  48. data/app/assets/javascripts/rails_admin_image_manager/vendors/fuse.min.js +9 -0
  49. data/app/assets/javascripts/rails_admin_image_manager/vendors/oneui.min.js +8 -0
  50. data/app/assets/javascripts/rails_admin_image_manager/vendors/underscore.min.js +6 -0
  51. data/app/assets/stylesheets/rails_admin_image_manager/_font.scss +2845 -0
  52. data/app/assets/stylesheets/rails_admin_image_manager/application.css +16 -0
  53. data/app/assets/stylesheets/rails_admin_image_manager/global.css.erb +3723 -0
  54. data/app/assets/stylesheets/rails_admin_image_manager/global.sass +1 -0
  55. data/app/assets/stylesheets/rails_admin_image_manager/vendors/bootstrap.min.css +5 -0
  56. data/app/assets/stylesheets/rails_admin_image_manager/vendors/oneui.css +8865 -0
  57. data/app/controllers/rails_admin_image_manager/application_controller.rb +41 -0
  58. data/app/controllers/rails_admin_image_manager/home_controller.rb +8 -0
  59. data/app/controllers/rails_admin_image_manager/images_controller.rb +117 -0
  60. data/app/helpers/rails_admin_image_manager/application_helper.rb +4 -0
  61. data/app/jobs/rails_admin_image_manager/application_job.rb +4 -0
  62. data/app/models/rails_admin_image_manager/application_record.rb +5 -0
  63. data/app/models/rails_admin_image_manager/file.rb +78 -0
  64. data/app/models/rails_admin_image_manager/tag.rb +41 -0
  65. data/app/views/layouts/rails_admin_image_manager/application.html.erb +26 -0
  66. data/app/views/rails_admin/main/_form_image_manager_picker.html.erb +45 -0
  67. data/app/views/rails_admin_image_manager/images/index.html.erb +2 -0
  68. data/config/initializers/rails_admin/image_manager_file.rb +87 -0
  69. data/config/initializers/rails_admin/image_manager_tag.rb +22 -0
  70. data/config/locales/rails_admin_image_manager.en.yml +33 -0
  71. data/config/locales/rails_admin_image_manager.fr.yml +33 -0
  72. data/config/routes.rb +12 -0
  73. data/db/migrate/20170626000000_create_image_manager.rb +37 -0
  74. data/lib/dynamic_paperclip_patch.rb +92 -0
  75. data/lib/generators/rails_admin_image_manager/install/install_generator.rb +22 -0
  76. data/lib/paperclip_patch.rb +22 -0
  77. data/lib/rails_admin_image_manager.rb +46 -0
  78. data/lib/rails_admin_image_manager/engine.rb +36 -0
  79. data/lib/rails_admin_image_manager/has_managed_file.rb +47 -0
  80. data/lib/rails_admin_image_manager/rails_admin/config/fields/types/image_manager_picker.rb +49 -0
  81. data/lib/rails_admin_image_manager/version.rb +3 -0
  82. data/lib/tasks/rails_admin_image_manager_tasks.rake +4 -0
  83. metadata +253 -0
@@ -0,0 +1,112 @@
1
+ <template>
2
+ <div class="content content-narrow animated fadeIn">
3
+ <div class="row items-push">
4
+ <div class="col-sm-12">
5
+ <a href="#"><i class="fa fa-arrow-left"></i> Retour à la liste</a>
6
+ </div>
7
+ </div>
8
+ <div class="block">
9
+ <div class="block-header">
10
+ <h3 class="block-title">Modifier l'image</h3>
11
+ </div>
12
+ <div class="block-content">
13
+ <div class="row">
14
+
15
+ <div class="col-sm-6">
16
+ <div class="form-horizontal">
17
+
18
+ <div :class="[{ 'has-error': errors.name },'form-group']">
19
+ <div class="col-sm-12">
20
+ <div class="form-material">
21
+ <input v-model="currentImgTitle" class="form-control" type="text" id="image-title" name="material-text" >
22
+ <label for="image-title">Titre</label>
23
+ <span class="help-block" v-if="errors.name">{{ errors.name[0] }}</span>
24
+ </div>
25
+ </div>
26
+ </div>
27
+
28
+ <div :class="[{ 'has-error': errors.copyright },'form-group']">
29
+ <div class="col-sm-12">
30
+ <div class="form-material">
31
+ <input v-model="currentImgCopyright" class="form-control" type="text" id="image-copyright" name="material-text" >
32
+ <label for="image-copyright">Copyright</label>
33
+ <span class="help-block" v-if="errors.copyright">{{ errors.copyright[0] }}</span>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ <div :class="[{ 'has-error': errors.description },'form-group']">
38
+ <div class="col-sm-12">
39
+ <div class="form-material">
40
+ <textarea v-model="currentImgDescription" class="form-control" id="material-textarea-large" name="material-textarea-large" rows="8"></textarea>
41
+ <label for="material-textarea-large">Description</label>
42
+ <span class="help-block" v-if="errors.description">{{ errors.description[0] }}</span>
43
+ </div>
44
+ </div>
45
+ </div>
46
+
47
+ <div class="form-group">
48
+ <div class="col-sm-12">
49
+ <image-tag-selector label="Étiquettes"></image-tag-selector>
50
+ </div>
51
+ </div>
52
+
53
+ <div class="form-group">
54
+ <div class="col-sm-10">
55
+ <button class="btn btn-sm btn-primary" type="button" @click="save">Enregistrer</button>
56
+ <image-insert-button :save-method="save" :id="currentImgId"/>
57
+ </div>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ <div class="col-sm-6">
62
+ <p><image-upload></image-upload></p>
63
+ </div>
64
+ </div>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </template>
69
+
70
+ <script>
71
+ import {mapState} from 'vuex'
72
+ import imageInsertButton from './imageInsertButton.vue'
73
+ import imageUpload from './imageUpload.vue'
74
+ import imageTagSelector from './imageTagSelector.vue'
75
+
76
+ export default {
77
+ components: {imageInsertButton, imageUpload, imageTagSelector},
78
+ data () {
79
+ return {
80
+ currentImgTitle: '',
81
+ currentImgCopyright: '',
82
+ currentImgDescription: '',
83
+ currentImgId: ''
84
+ }
85
+ },
86
+ methods: {
87
+ save() {
88
+ let imgData = {
89
+ name: this.currentImgTitle,
90
+ description: this.currentImgDescription,
91
+ copyright: this.currentImgCopyright,
92
+ }
93
+ return new Promise((resolve, reject) => {
94
+ this.$store.dispatch('mediasStore/setCurrentImg', imgData)
95
+ this.$store.dispatch('mediasStore/saveCurrentImg').then(resolve).catch(reject)
96
+ });
97
+ },
98
+ },
99
+ computed: {
100
+ ...mapState('mediasStore', ['errors'])
101
+ },
102
+ created () {
103
+ this.currentImgId = this.$store.state.mediasStore.currentImgId
104
+ this.currentImgTitle = this.$store.state.mediasStore.currentImgTitle
105
+ this.currentImgCopyright = this.$store.state.mediasStore.currentImgCopyright
106
+ this.currentImgDescription = this.$store.state.mediasStore.currentImgDescription
107
+ }
108
+ }
109
+ </script>
110
+
111
+ <style media="screen">
112
+ </style>
@@ -0,0 +1,94 @@
1
+ <template>
2
+ <div class="image-tag-selector form-material">
3
+ <div class="image-tag-selector__choices">
4
+ <p><span class="label label-primary" @click="removeSelected(tag)" v-for="tag in currentImgTags">{{tag}}</span></p>
5
+ </div>
6
+ <input type="text" placeholder="Saisir une étiquette et faire enter" class="form-control" v-model="searchText" @keyup="addCusttom">
7
+ <label for="example-select2-multiple">{{label}}</label>
8
+ <ul class="image-tag-selector__pool-list">
9
+ <li v-for="tag in filteredTags" @click="selectTag(tag)"><button type="button">{{ tag }}</button></li>
10
+ </ul>
11
+ </div>
12
+ </template>
13
+
14
+ <script>
15
+ import { mapState } from 'vuex'
16
+
17
+ export default {
18
+ props: ['label'],
19
+ data () {
20
+ return {
21
+ searchText: '',
22
+ tagsPool: []
23
+ }
24
+ },
25
+ computed: {
26
+ filteredTags() {
27
+ let filtreTexte = (string) => {
28
+ if (string == '') return []
29
+ return this.tagsPool.filter((el) =>
30
+ el.toLowerCase().indexOf(string.toLowerCase()) > -1
31
+ );
32
+ }
33
+ return filtreTexte(this.searchText)
34
+ },
35
+ ...mapState('mediasStore', ['currentImgTags', 'tags'])
36
+ },
37
+ methods: {
38
+ selectTag(string) {
39
+ if (this.currentImgTags.indexOf(string) < 0) {
40
+ this.$store.dispatch('mediasStore/addTag', string)
41
+ this.searchText = ''
42
+ }
43
+ },
44
+ removeSelected(string) {
45
+ this.$store.dispatch('mediasStore/removeTag', string)
46
+ },
47
+ addCusttom(e) {
48
+ if (e.keyCode == 13 && this.tagsPool.indexOf(this.searchText) < 0 && this.currentImgTags.indexOf(this.searchText) < 0) {
49
+ this.$store.dispatch('mediasStore/addTag', this.searchText)
50
+ this.searchText = ''
51
+ }
52
+ }
53
+ },
54
+ mounted () {
55
+ this.$store.dispatch('mediasStore/fetchTags').then(()=> {
56
+ for (var i = 0; i < this.tags.length; i++) {
57
+ let tag = this.tags[i]
58
+ this.tagsPool.push(tag.name)
59
+ }
60
+ })
61
+ }
62
+ }
63
+ </script>
64
+
65
+ <style media="screen" lang="sass">
66
+
67
+ .image-tag-selector__pool-list
68
+ list-style: none
69
+ margin: 0
70
+ padding: 0
71
+ position: absolute
72
+ top: 100%
73
+ width: 100%
74
+ z-index: 100
75
+
76
+ li
77
+ background-color: #fcfcfc
78
+
79
+ button
80
+ background-color: transparent
81
+ border: none
82
+ display: block
83
+ width: 100%
84
+ text-align: left
85
+ padding-top: 10px
86
+ padding-bottom: 10px
87
+
88
+
89
+
90
+ .image-tag-selector__choices
91
+ .label
92
+ margin: 0 3px
93
+ cursor: pointer
94
+ </style>
@@ -0,0 +1,94 @@
1
+ <template>
2
+ <div :class="[{'has-error': imageError}, 'image-upload']">
3
+ <div class="image-upload__content">
4
+ <img :src="currentImgSrc" class="image-upload__img" v-if="currentImgSrc" alt="">
5
+ <div class="image-upload__placeholder" v-if="currentImgSrc == ''">
6
+ <i class="fa fa-image"></i>
7
+ Ajouter une image
8
+ </div>
9
+ <input class="image-upload__file-input" type="file" @change="encode($event)">
10
+ </div>
11
+ <span class="help-block" :if="imageError">{{imageError}}</span>
12
+
13
+ <button type="button" class="btn btn-default push-20-t" v-if="showOriginal" @click="undo" alt=""><i class="fa fa-undo"></i> Annuler</button>
14
+ </div>
15
+ </template>
16
+
17
+ <script>
18
+ import { encodeImageFileAsURL } from '../libs/helpers.js'
19
+ import { mapState } from 'vuex'
20
+
21
+ export default {
22
+ data() {
23
+ return {
24
+ originalSrc: '',
25
+ showOriginal: false
26
+ }
27
+ },
28
+ computed: {
29
+ ...mapState('mediasStore', ['currentImgSrc', 'errors']),
30
+ imageError() {
31
+ if(this.errors.hasOwnProperty('image')) {
32
+ return this.errors.image[0]
33
+ }
34
+ }
35
+ },
36
+ created () {
37
+ this.originalSrc = this.currentImgSrc
38
+ },
39
+ methods: {
40
+ encode(e) {
41
+ encodeImageFileAsURL(e.target)
42
+ .then((result) => {
43
+ if (this.originalSrc != '') this.showOriginal = true
44
+ this.$store.dispatch('mediasStore/updateSrc', result.src)
45
+ this.$store.dispatch('mediasStore/updateImageName', result.name)
46
+ })
47
+ },
48
+ undo() {
49
+ this.$store.dispatch('mediasStore/updateSrc', this.originalSrc)
50
+ this.showOriginal = false
51
+ }
52
+ }
53
+ }
54
+ </script>
55
+
56
+ <style media="screen" lang="sass">
57
+ .image-upload
58
+ position: relative
59
+
60
+ .image-upload__img
61
+ width: 100%
62
+
63
+ .image-upload__file-input
64
+ position: absolute
65
+ top: 0
66
+ left: 0
67
+ bottom: 0
68
+ right: 0
69
+ width: 100%
70
+ opacity: 0
71
+ cursor: pointer
72
+
73
+ .image-upload__content
74
+ position: relative
75
+ border: 6px dashed #fcfcfc
76
+ transition: all 200ms linear
77
+ .has-error &
78
+ border-color: #d26a5c
79
+
80
+ &:hover
81
+ border-color: #c9c9c9
82
+
83
+ .image-upload__placeholder
84
+ width: 100%
85
+ padding: 30px 0
86
+ display: flex
87
+ align-items: center
88
+ justify-content: center
89
+ flex-direction: column
90
+ cursor: pointer
91
+ opacity: 0.8
92
+ i
93
+ font-size: 70px
94
+ </style>
@@ -0,0 +1,32 @@
1
+ <template>
2
+ <span class="listing-filter" @click.prevent="filter()">{{label}}
3
+ <i v-if="activeFilters[type] == 'ASC'" class="fa fa-arrow-down"></i>
4
+ <i v-if="activeFilters[type] == 'DESC'" class="fa fa-arrow-up"></i>
5
+ </span>
6
+ </template>
7
+
8
+ <script>
9
+ import {mapState} from 'vuex'
10
+
11
+ export default {
12
+ props: ['label', 'type'],
13
+ data () {
14
+ return {}
15
+ },
16
+ computed: {
17
+ ...mapState('mediasStore', ['activeFilters'])
18
+ },
19
+ methods: {
20
+ filter () {
21
+ this.$store.dispatch('mediasStore/setSearchPage', 1)
22
+ this.$store.dispatch('mediasStore/clearImgListing')
23
+ this.$store.dispatch('mediasStore/toggleFilter', this.type)
24
+ this.$store.dispatch('mediasStore/fetchImage')
25
+ }
26
+ }
27
+ }
28
+ </script>
29
+ <style media="screen" lang="sass">
30
+ .listing-filter
31
+ cursor: pointer
32
+ </style>
@@ -0,0 +1,47 @@
1
+ <template>
2
+ <div class="notif-overlay">
3
+ <transition-group name="fade-top">
4
+ <div :class="[{'alert-success': notification.success, 'alert-danger': notification.error}, 'alert', 'notification-item']" :key="notification" v-for="notification in notifications">
5
+ <p>{{ notification.msg }}</p>
6
+ </div>
7
+ </transition-group>
8
+ </div>
9
+ </template>
10
+
11
+ <script>
12
+ import {mapState} from 'vuex'
13
+
14
+ export default {
15
+ computed: {
16
+ ...mapState('overlayStore', ['notifications'])
17
+ }
18
+ }
19
+ </script>
20
+
21
+ <style media="screen" lang='sass'>
22
+ .notif-overlay
23
+ position: fixed
24
+ bottom: 20px
25
+ right: 20px
26
+
27
+ .notification-item
28
+ width: 300px
29
+ height: 100px
30
+ margin: 5px
31
+
32
+ &.error
33
+ background-color: red
34
+ color: white
35
+ &.success
36
+ background-color: #c3f0cc
37
+ color: #3daa41
38
+
39
+
40
+ .fade-top-enter-active, .fade-top-leave-active
41
+ transition: all 400ms
42
+
43
+ .fade-top-enter, .fade-top-leave-to
44
+ opacity: 0
45
+
46
+
47
+ </style>
@@ -0,0 +1,37 @@
1
+ <template>
2
+ <transition name="fade">
3
+ <div class="progress-overlay progress active" v-if="showProgress" style="height: 6px">
4
+ <div class="progress-bar progress-bar-success progress-bar-striped" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
5
+ </div>
6
+ </transition>
7
+ </template>
8
+
9
+ <script>
10
+ import {mapState} from 'vuex'
11
+
12
+ export default {
13
+ computed: {
14
+ ...mapState('overlayStore', ['showProgress'])
15
+ }
16
+ }
17
+ </script>
18
+
19
+ <style media="screen" lang='sass'>
20
+ .progress-overlay
21
+ position: fixed
22
+ top: 0
23
+ width: 100%
24
+
25
+ .fade-enter-active, .fade-leave-active
26
+ transition: opacity .150s
27
+ .fade-enter, .fade-leave-to
28
+ opacity: 0
29
+
30
+ .image-insert-overlay__close
31
+ position: absolute
32
+ top: 0
33
+ right: 0
34
+ background-color: transparent
35
+ border: none
36
+
37
+ </style>
@@ -0,0 +1,140 @@
1
+ <template>
2
+ <div class="search-autocomplete">
3
+ <div class="search-autocomplete__input">
4
+ <input @keyup.prevent="fuzzySearch" class="form-control" v-model="query" type="text" placeholder="Rechercher par titre ou étiquette ...">
5
+ <div class="search-autocomplete__tags-list">
6
+ <span @click="selectedTagIndex = index; selectTag()" :class="[{'active': isActive(index)}, 'search-autocomplete__tag']" v-for="(tag,index) in filteredTags">{{tag.name}}</span>
7
+ </div>
8
+ </div>
9
+ <span @click="deselectTag(activeTag)" class="label label-primary search-autocomplete__selected-tag" v-for="activeTag in activeFilters.tags">{{getTagFromId(activeTag)}}</span>
10
+ </div>
11
+
12
+ </template>
13
+
14
+ <script>
15
+ import {mapState, mapGetters} from 'vuex'
16
+ import Fuse from '../vendors/fuse.min.js'
17
+ export default {
18
+ data () {
19
+ return {
20
+ query: '',
21
+ fuseSearch: null,
22
+ selectedTagIndex: -1
23
+ }
24
+ },
25
+ computed: {
26
+ ...mapState('mediasStore', ['tags', 'activeFilters']),
27
+ // Autocomplet will search for last string in input (seperated by space)
28
+ searchFor() {
29
+ let lastElem = this.query.split(' ').reverse()[0]
30
+ return lastElem
31
+ },
32
+ filteredTags() {
33
+ if (this.fuseSearch) {
34
+ return this.fuseSearch.search(this.searchFor);
35
+ } else {
36
+ return []
37
+ }
38
+
39
+ }
40
+ },
41
+ methods:{
42
+ fuzzySearch(e) {
43
+ if(e.key == 'ArrowUp' || e.key == 'ArrowDown') {
44
+ this.navigatesTags(e.key)
45
+ } else if (e.key == 'Enter' && this.selectedTagIndex >= 0) {
46
+ this.selectTag()
47
+ } else if (e.key == 'Enter') {
48
+ this.$store.dispatch('mediasStore/setSearchQuery', this.query)
49
+ this.$store.dispatch('mediasStore/clearImgListing')
50
+ this.$store.dispatch('mediasStore/setSearchPage', 1)
51
+ this.$store.dispatch('mediasStore/fetchImage')
52
+ console.log('search');
53
+ this.query = ""
54
+ } else if((e.key == 'Backspace' || e.key == 'Meta') && this.query == '' && this.activeFilters.search != '') {
55
+ this.clearSearch()
56
+ }
57
+ },
58
+ clearSearch() {
59
+ this.$store.dispatch('mediasStore/setSearchQuery', '')
60
+ this.$store.dispatch('mediasStore/clearImgListing')
61
+ this.$store.dispatch('mediasStore/fetchImage')
62
+ },
63
+ navigatesTags(key) {
64
+ if (key == 'ArrowUp') {
65
+ (this.selectedTagIndex > 0) ? this.selectedTagIndex -- : 0
66
+ } else {
67
+ (this.selectedTagIndex < this.filteredTags.length - 1) ? this.selectedTagIndex ++ : this.filteredTags.length
68
+ }
69
+ },
70
+ selectTag() {
71
+ let query = this.query
72
+ let queryArray = query.split(' ').reverse()
73
+ queryArray[0] = this.filteredTags[this.selectedTagIndex].name
74
+ let newQuery = queryArray.reverse().join(' ')
75
+ this.$store.dispatch('mediasStore/setSearchQuery', '')
76
+ this.$store.dispatch('mediasStore/setSearchPage', 1)
77
+ this.$store.dispatch('mediasStore/clearImgListing')
78
+ this.$store.dispatch('mediasStore/addToTagFilter', this.filteredTags[this.selectedTagIndex].id)
79
+ this.$store.dispatch('mediasStore/fetchImage')
80
+ this.selectedTagIndex = -1
81
+ this.query = ""
82
+ },
83
+ deselectTag(id){
84
+ this.$store.dispatch('mediasStore/clearImgListing')
85
+ this.$store.dispatch('mediasStore/removeFromTagFilter', id)
86
+ this.$store.dispatch('mediasStore/fetchImage')
87
+ },
88
+ isActive(index) {
89
+ return index == this.selectedTagIndex;
90
+ },
91
+ getTagFromId(id) {
92
+ let myTag = _.find(this.tags,(tag) => {return tag.id == id})
93
+ return myTag.name
94
+ }
95
+
96
+ },
97
+ mounted() {
98
+ this.$store.dispatch('mediasStore/fetchTags').then(() => {
99
+ this.fuseSearch = new Fuse(this.tags, {keys: ['name']})
100
+ })
101
+ }
102
+ }
103
+ </script>
104
+
105
+ <style media="screen" lang="sass">
106
+ .search-autocomplete__selected-tag
107
+ display: inline-flex
108
+ margin: 3px
109
+ position: relative
110
+ cursor: pointer
111
+ &:first-of-type
112
+ margin-left: 0
113
+
114
+ .search-autocomplete__input
115
+ position: relative
116
+
117
+ .search-autocomplete
118
+ width: 100%
119
+ position: relative
120
+
121
+ .search-autocomplete__tags-list
122
+ position: absolute
123
+ top: 100%
124
+ width: 100%
125
+ z-index: 100
126
+ background-color: white
127
+ box-shadow: 0 5px 8px rgba(0, 0, 0, 0.1)
128
+
129
+ .search-autocomplete__tag
130
+ display: block
131
+ padding: 5px
132
+ transition: all 200ms linear
133
+ cursor: pointer
134
+ &:hover
135
+ background-color: #ededed
136
+
137
+ &.active
138
+ background-color: #5c90d2
139
+ color: white
140
+ </style>