Skip to content

Commit

Permalink
Merge pull request #577 from motchju/3.0
Browse files Browse the repository at this point in the history
Vuejs component: Multiple file selector clean up of 523
  • Loading branch information
nWidart authored Aug 30, 2018
2 parents 62eeb8c + a6d7454 commit b0d48e0
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 0 deletions.
123 changes: 123 additions & 0 deletions Modules/Media/Assets/js/components/MultipleMedia.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<template>
<div>
<label class="el-form-item__label">{{ getFieldLabel() }}</label>
<div class="jsThumbnailImageWrapper jsSingleThumbnailWrapper" v-if="hasSelectedMedia" >
<figure v-for="media in this.selectedMedia" :key="media.id">
<img :src="media.small_thumb" alt="" v-if="media.is_image"/>
<i :class="`fa ${media.fa_icon}`" style="font-size: 60px;" v-if="! media.is_image"></i>
<span v-if="! media.is_image" style="display:block;">{{ media.filename }}</span>
<span class="el-icon-error remove-media" @click="unSelectMedia(media.id)"></span>
</figure>
<div class="clearfix"></div>
</div>
<div>
<el-button type="button" @click="dialogVisible = true">{{ trans('media.Browse') }}</el-button>
</div>
<el-dialog
:visible.sync="dialogVisible"
fullscreen
:before-close="handleClose">

<media-list single-modal :event-name="this.eventName"></media-list>

<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">{{ trans('core.button.cancel') }}</el-button>
</span>
</el-dialog>
</div>
</template>

<script>
import axios from 'axios';
import UploadZone from '../../../../Media/Assets/js/components/UploadZone.vue';
import MediaList from '../../../../Media/Assets/js/components/MediaList.vue';
import StringHelpers from '../../../../Core/Assets/js/mixins/StringHelpers.vue';
export default {
mixins: [StringHelpers],
props: {
zone: { type: String, required: true },
entity: { type: String, required: true },
entityId: { default: null },
label: { type: String },
},
components: {
'upload-zone': UploadZone,
'media-list': MediaList,
},
watch: {
entityId() {
if (this.entityId) {
this.fetchMedia();
}
},
},
data() {
return {
dialogVisible: false,
selectedMedia: [],
eventName: '',
};
},
computed: {
hasSelectedMedia() {
return this.selectedMedia !== undefined && !_.isEmpty(this.selectedMedia);
},
},
methods: {
handleClose(done) {
done();
},
unSelectMedia(id) {
this.selectedMedia = _.reject(this.selectedMedia, media => media.id === id);
this.$emit('fileUnselected', { id, zone: this.zone });
},
fetchMedia() {
axios.get(route('api.media.get-by-zone-and-entity', {
zone: this.zone,
entity: this.entity,
entity_id: this.entityId,
}))
.then((response) => {
this.selectedMedia = response.data.data;
_.forEach(this.selectedMedia, (file) => {
this.$emit('multipleFileSelected', { id: file.id, zone: this.zone });
});
});
},
getFieldLabel() {
return this.label || this.ucwords(this.zone.replace('_', ' '));
},
makeId() {
let text = '';
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < 5; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)); }
return text;
},
},
mounted() {
if (this.entityId) {
this.fetchMedia();
}
this.eventName = `fileWasSelected${this.makeId()}${Math.floor(Math.random() * 999999)}`;
this.$events.listen(this.eventName, (mediaData) => {
if (_.find(this.selectedMedia, mediaData) === undefined) {
if (!this.selectedMedia) this.selectedMedia = [];
this.selectedMedia.push(mediaData);
this.$emit('multipleFileSelected', _.merge(mediaData, { zone: this.zone }));
}
});
},
};
</script>
<style>
.remove-media{
position: absolute;
top: 5px;
left: 5px;
color: #FA5555;
}
</style>
27 changes: 27 additions & 0 deletions Modules/Media/Assets/js/mixins/MultipleFileSelector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export default {
methods: {
selectMultipleFile(event, model) {
if (!this[model].medias_multi) {
this[model].medias_multi = {};
}
if (!this[model].medias_multi[event.zone]) {
this[model].medias_multi[event.zone] = { files: [] };
}
this[model].medias_multi[event.zone].files.push(event.id);
},
unselectFile(event, model) {
if (!this[model].medias_multi) {
this[model].medias_multi = {};
}
if (!this[model].medias_multi[event.zone]) {
this[model].medias_multi[event.zone] = { files: [] };
if (this.$refs['multiple-media'] !== undefined && this.$refs['multiple-media'].selectedMedia !== undefined && !_.isEmpty(this.$refs['multiple-media'].selectedMedia)) {
_.forEach(this.$refs['multiple-media'].selectedMedia, (file, key) => {
this[model].medias_multi[event.zone].files.push(file.id);
});
}
}
this[model].medias_multi[event.zone].files = _.reject(this[model].medias_multi[event.zone].files, media => media === event.id);
},
},
};
18 changes: 18 additions & 0 deletions Modules/Media/Http/Controllers/Api/MediaController.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,24 @@ public function findFirstByZoneEntity(Request $request)
return new MediaTransformer($file);
}

/**
* Get a media collection by zone and entity object. Require some params that were passed to request: entity (Full class name of entity), entity_id and zone
*
* @param Request $request
* @return JsonResponse|\Illuminate\Http\Resources\Json\AnonymousResourceCollection
*/
public function getByZoneEntity(Request $request)
{
$entityName = (string)$request->get('entity');
$entityModel = new $entityName;
$entity = $entityModel::find($request->get('entity_id'));
if ($entity && in_array('Modules\Media\Support\Traits\MediaRelation', class_uses($entity)) && $entity->files()->count()) {
$files = $this->file->findMultipleFilesByZoneForEntity($request->get('zone'), $entity);
return MediaTransformer::collection($files);
}
return response()->json(['data' => null]);
}

/**
* Store a newly created resource in storage.
*
Expand Down
5 changes: 5 additions & 0 deletions Modules/Media/Http/apiRoutes.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@
'as' => 'api.media.find-first-by-zone-and-entity',
]);

$router->get('media/get-by-zone-and-entity', [
'uses' => 'MediaController@getByZoneEntity',
'as' => 'api.media.get-by-zone-and-entity',
]);

$router->get('media/{media}', [
'uses' => 'MediaController@find',
'as' => 'api.media.media.find',
Expand Down

0 comments on commit b0d48e0

Please sign in to comment.