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

Commit

Permalink
Create folder modal (#90)
Browse files Browse the repository at this point in the history
* First draft: create a reusable modal component

with the look and feel of b2 modals

* Add modal sm size

* Create create-folder-modal

* Implement create folder function

* Update adapter and api to return single resources

* Implement create folders

* Changed Upload to New string

* Changed Upload to New string
  • Loading branch information
dneukirchen authored and laoneo committed Feb 23, 2017
1 parent 87e8b2f commit 24d1cdb
Show file tree
Hide file tree
Showing 13 changed files with 310 additions and 23 deletions.
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>
<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';
Loading

0 comments on commit 24d1cdb

Please sign in to comment.