Skip to content
This repository has been archived by the owner on May 26, 2020. It is now read-only.

Feature/create folder modal #90

Merged
merged 10 commits into from
Feb 23, 2017
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public function files()
$this->adapter->createFolder($name, $path);
}

$data = $this->adapter->getFiles($path . '/' . $name);
$data = $this->adapter->getFile($path . '/' . $name);
break;
case 'put':
$content = $this->input->json;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,42 @@ public function __construct($rootPath)
$this->rootPath = $rootPath;
}

/**
* Returns the requested file or folder. The returned object
* has the following properties available:
* - type: The type can be file or dir
* - name: The name of the file
* - path: The relative path to the root
* - extension: The file extension
* - size: The size of the file
* - create_date: The date created
* - modified_date: The date modified
* - mime_type: The mime type
* - width: The width, when available
* - height: The height, when available
*
* @param string $path The folder
*
* @return stdClass[]
*
* @since __DEPLOY_VERSION__
* @throws Exception
*/
public function getFile($path = '/')
{
// Set up the path correctly
$path = JPath::clean('/' . $path);
$basePath = JPath::clean($this->rootPath . $path);

// Check if file exists
if (!file_exists($basePath))
{
return array();
}

return $this->getPathInformation($basePath);
}

/**
* Returns the folders and files for the given path. The returned objects
* have the following properties available:
Expand Down
55 changes: 42 additions & 13 deletions administrator/components/com_media/resources/app/Api.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,46 @@ class Api {
}).catch(this._handleError);
}

/**
* Create a directory
* @param name
* @param parent
* @returns {Promise.<T>}
*/
createDirectory(name, parent) {
// Wrap the jquery call into a real promise
return new Promise((resolve, reject) => {
const url = this._baseUrl + '&task=api.files&path=' + parent;
jQuery.ajax({
url: url,
type: "POST",
data: JSON.stringify({'name': name}),
contentType: "application/json",
})
.done((json) => resolve(this._normalizeItem(json.data)))
.fail((xhr, status, error) => {
reject(xhr)
})
}).catch(this._handleError);
}

/**
* Normalize a single item
* @param item
* @returns {*}
* @private
*/
_normalizeItem(item) {
if(item.type === 'dir') {
item.directories = [];
item.files = [];
}

item.directory = path.dirname(item.path);

return item;
}

/**
* Normalize array data
* @param data
Expand All @@ -42,21 +82,10 @@ class Api {
*/
_normalizeArray(data) {

// Directories
const directories = data.filter(item => (item.type === 'dir'))
.map(directory => {
directory.directory = path.dirname(directory.path);
directory.directories = [];
directory.files = [];
return directory;
});

// Files
.map(directory => this._normalizeItem(directory));
const files = data.filter(item => (item.type === 'file'))
.map(file => {
file.directory = path.dirname(file.path);
return file;
});
.map(file => this._normalizeItem(file));

return {
directories: directories,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
</div>
<media-browser></media-browser>
</div>
<create-folder-modal></create-folder-modal>
</div>
</template>

Expand Down Expand Up @@ -37,7 +38,7 @@
});
},
beforeDestroy() {
// Add the global resize event listener
// Remove the global resize event listener
window.removeEventListener('resize', this.setFullHeight)
},
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<media-modal v-if="$store.state.showCreateFolderModal" :size="'sm'" @close="close()">
<h3 slot="header">Create a new folder</h3>
<div slot="body">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="folder">Folder</label>
<div class="controls">
<input type="text" id="folder" placeholder="Folder" v-model="folder">
</div>
</div>
</form>
</div>
<div slot="footer">
<button class="btn btn-danger" @click="close()">Cancel</button>
<button class="btn btn-success" @click="save()">Save</button>
</div>
</media-modal>
</template>

<script>
import * as types from "./../../store/mutation-types";
export default {
name: 'create-folder-modal',
methods: {
/* Close the modal instance */
close() {
this.$store.commit(types.HIDE_CREATE_FOLDER_MODAL);
},
/* Save the form and create the folder */
save() {
this.$store.dispatch('createDirectory', {
name: this.folder,
parent: this.$store.state.selectedDirectory,
});
this.folder = '';
}
}
}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<template>
<div class="media-modal-backdrop" @click="close()">
<div class="modal" :class="modalClass" @click.stop>
<div class="modal-header">
<button v-if="showCloseButton" type="button" class="close" @click="close()">×</button>
<slot name="header"></slot>
</div>
<div class="modal-body">
<slot name="body"></slot>
</div>
<div class="modal-footer">
<slot name="footer"></slot>
</div>
</div>
</div>
</template>

<style>
/** TODO DN extract styles **/

/** modal-sm styles **/
.modal.modal-sm {
width: 450px;
margin-left: -225px;
}
@media (max-width: 767px) {
.modal.modal-sm {
width: auto;
margin: 0;
}
}
.modal-body {
width: auto;
padding: 15px;
overflow-y: auto;
}
.media-modal-backdrop {
position: fixed;
z-index: 1040;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .8);
display: table;
transition: opacity .3s ease;
}
</style>

<script>
// TODO DN: transition and advanced styling
// TODO DN: perhaps use a better modal than the b2 modal
import * as types from "./../../store/mutation-types";
export default {
name: 'media-modal',
props: {
/* Whether or not the close button in the header should be shown */
showClose: {
type: Boolean,
default: true,
},
/* The size of the modal */
size: {
type: String,
}
},
computed: {
/* Get the modal css class */
modalClass() {
return {
'modal-sm': this.size === 'sm',
}
},
},
methods: {
/* Close the modal instance */
close() {
this.$emit('close');
},
/* Handle keydown events */
onKeyDown(event) {
if (event.keyCode == 27) {
this.close();
}
}
},
mounted() {
// Listen to keydown events on the document
document.addEventListener("keydown", this.onKeyDown);
},
beforeDestroy() {
// Remove the keydown event listener
document.removeEventListener('keydown', this.onKeyDown);
},
}
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
<div class="media-toolbar">
<div class="create-wrapper">
<div class="btn-group">
<button class="btn btn-success">Upload</button>
<button class="btn btn-success">New</button>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No translation planed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#73

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<button class="btn dropdown-toggle btn-success" data-toggle="dropdown">
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#">Create Folder</a></li>
<li><a href="#" @click.prevent="showCreateFolderModal()">Create Folder</a></li>
<li class="divider"></li>
<li><a href="#">Upload File</a></li>
<li><a href="#">Upload Folder</a></li>
Expand All @@ -25,7 +25,20 @@
</template>

<script>
import * as types from "./../../store/mutation-types";
export default {
name: 'media-toolbar',
methods: {
/* Close the modal instance */
showCreateFolderModal() {
this.$store.commit(types.SHOW_CREATE_FOLDER_MODAL);
},
/* Handle keydown events */
onKeyDown(event) {
if (this.show && event.keyCode == 27) {
this.close();
}
}
},
}
</script>
4 changes: 4 additions & 0 deletions administrator/components/com_media/resources/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import Toolbar from "./components/toolbar/toolbar.vue";
import Breadcrumb from "./components/breadcrumb/breadcrumb.vue";
import Browser from "./components/browser/browser.vue";
import BrowserItem from "./components/browser/items/item";
import MediaModal from "./components/modals/modal.vue";
import CreateFolderModal from "./components/modals/create-folder-modal.vue";
import store from './store/store'

// Register the vue components
Expand All @@ -15,6 +17,8 @@ Vue.component('media-toolbar', Toolbar);
Vue.component('media-breadcrumb', Breadcrumb);
Vue.component('media-browser', Browser);
Vue.component('media-browser-item', BrowserItem);
Vue.component('media-modal', MediaModal);
Vue.component('create-folder-modal', CreateFolderModal);

// Create the root Vue instance
document.addEventListener("DOMContentLoaded",
Expand Down
19 changes: 18 additions & 1 deletion administrator/components/com_media/resources/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import * as types from "./mutation-types";
*/
export const getContents = ({commit}, dir) => {
api.getContents(dir)
.then((contents) => {
.then(contents => {
commit(types.LOAD_CONTENTS_SUCCESS, contents);
commit(types.SELECT_DIRECTORY, dir);
})
Expand All @@ -22,3 +22,20 @@ export const getContents = ({commit}, dir) => {
});
}

/**
* Create a new folder
* @param commit
* @param payload object with the new folder name and its parent directory
*/
export const createDirectory = ({commit}, payload) => {
api.createDirectory(payload.name, payload.parent)
.then(folder => {
commit(types.CREATE_DIRECTORY_SUCCESS, folder);
commit(types.HIDE_CREATE_FOLDER_MODAL);
})
.catch(error => {
// TODO error handling
console.log("error", error);
})
}

Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
export const SELECT_DIRECTORY = 'SELECT_DIRECTORY';
export const LOAD_CONTENTS_SUCCESS = 'LOAD_CONTENTS_SUCCESS';

// Api handlers
export const LOAD_CONTENTS_SUCCESS = 'LOAD_CONTENTS_SUCCESS';
export const CREATE_DIRECTORY_SUCCESS = 'CREATE_DIRECTORY_SUCCESS';

// Create folder modal
export const SHOW_CREATE_FOLDER_MODAL = 'SHOW_CREATE_FOLDER_MODAL';
export const HIDE_CREATE_FOLDER_MODAL = 'HIDE_CREATE_FOLDER_MODAL';