Skip to content

Commit

Permalink
Basic vue-app-setup (#70)
Browse files Browse the repository at this point in the history
* Basic vue-app-setup

* Remove modified api controller

* Add npm-debug.log to gitignore

* Revert to wrong gitignore and ad npm-debug.log to the correct one

* Fix more code style errors
  • Loading branch information
dneukirchen authored and laoneo committed Dec 30, 2016
1 parent c68004d commit a027e11
Show file tree
Hide file tree
Showing 14 changed files with 352 additions and 17 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

# Node modules #
node_modules/
npm-debug.log

# phpDocumentor Logs #
phpdoc-*
Expand Down
3 changes: 3 additions & 0 deletions administrator/components/com_media/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["es2015"]
}
17 changes: 0 additions & 17 deletions administrator/components/com_media/controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,4 @@
*/
class MediaController extends JControllerLegacy
{
/**
* Typical view method for MVC based architecture
*
* This function is provide as a default implementation, in most cases
* you will need to override it in your own controllers.
*
* @param boolean $cachable If true, the view output will be cached
* @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}.
*
* @return JControllerLegacy A JControllerLegacy object to support chaining.
*
* @since __DEPLOY_VERSION__
*/
public function display($cachable = false, $urlparams = false)
{
echo 'Welcome to the new media manager';
}
}
27 changes: 27 additions & 0 deletions administrator/components/com_media/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "com_media",
"version": "3.0.0",
"description": "Component for managing site media",
"author": "",
"license": "GPL-3.0",
"scripts": {
"build": "browserify ./resources/main.js | uglifyjs -c warnings=false -m > ../../../media/media/js/app.js"
},
"dependencies": {
"vue": "^2.0.1"
},
"devDependencies": {
"babel-core": "^6.0.0",
"babel-preset-es2015": "^6.0.0",
"babelify": "^7.2.0",
"browserify": "^13.0.1",
"uglify-js": "^2.5.0",
"vueify": "^9.1.0"
},
"browserify": {
"transform": [
"vueify",
"babelify"
]
}
}
17 changes: 17 additions & 0 deletions administrator/components/com_media/resources/app/Event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Vue from "vue";

class Event {
constructor() {
this.vue = new Vue();
}

fire(event, data = null) {
this.vue.$emit(event, data);
}

listen(event, callback) {
this.vue.$on(event, callback);
}
}

export default Event;
76 changes: 76 additions & 0 deletions administrator/components/com_media/resources/components/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<template>
<div>
<div class="row-fluid">
<div class="span3 media-sidebar">
<media-tree :tree="tree" :dir="dir"></media-tree>
</div>
<div class="span9 media-browser">
<media-browser :content="content"></media-browser>
</div>
</div>
</div>
</template>

<script>
export default {
name: 'media-app',
data() {
return {
// The current selected directory
dir: '/',
// The content of the selected directory
content: [],
// The tree structure
tree: {path: '/', children: []},
// The api base url
baseUrl: 'https://github.com/gitapi/repos/joomla/joomla-cms/contents'
}
},
methods: {
getContent() {
let url = this.baseUrl + this.dir;
jQuery.getJSON(url, (content) => {
// Update the current directory content
this.content = content;
// Find the directory node by path and update its children
this._updateLeafByPath(this.tree, this.dir, content);
}).error(() => {
alert("Error loading directory content.");
})
},
// TODO move to a mixin
_updateLeafByPath(obj, path, data) {
// Set the node children
if (obj.path && obj.path === path) {
this.$set(obj, 'children', data);
return true;
}
// Loop over the node children
if (obj.children && obj.children.length) {
for(let i=0; i < obj.children.length; i++) {
if(this._updateLeafByPath(obj.children[i], path, data)) {
return true;
}
}
}
return false;
}
},
created() {
// Listen to the directory changed event
Media.Event.listen('dirChanged', (dir) => {
this.dir = dir;
});
},
mounted() {
// Load the tree data
this.getContent();
},
watch: {
dir: function () {
this.getContent();
}
}
}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<template>
<ul class="media-browser">
<media-browser-item v-for="item in content" :item="item"></media-browser-item>
</ul>
</template>
<script>
export default {
name: 'media-browser',
props: ['content'],
computed: {
contents: function () {
return this.content
.filter((item) => {
// Hide hidden files
return item.name.indexOf('.') !== 0;
})
.sort((a, b) => {
// Sort by type and alphabetically
if (a.type !== b.type) {
return (a.type === 'dir') ? -1 : 1;
} else {
return (a.name.toUpperCase() < b.name.toUpperCase()) ? -1 : 1;
}
})
}
}
}
</script>
<style>
/** TODO: move styles to dedicated css file **/
.media-browser ul {
margin: 0;
padding: 0;
list-style: none;
}
.media-browser ul li {
display: inline-block;
float: left;
width: 100px;
height: 100px;
margin-bottom: 9px;
margin-right: 9px;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<template>
<li class="media-browser-item">
{{ item.name }}
</li>
</template>

<script>
export default {
name: 'media-browser-item',
props: ['item'],
}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template>
<li class="media-tree-item" v-bind:class="{active: isActive }">
<a @click.stop.prevent="toggleItem(item)">{{ item.name }}</a>
<media-tree v-if="item.children && item.children.length" :tree="item" :dir="dir"></media-tree>
</li>
</template>

<script>
export default {
name: 'media-tree-item',
props: ['item', 'dir'],
computed: {
isActive: function() {
return (this.item.path === this.dir);
}
},
methods: {
toggleItem(item) {
Media.Event.fire('dirChanged', item.path);
}
},
}
</script>

<style>
.media-tree-item.active > a {
font-weight: bold;
}
.media-tree-item a {
cursor: pointer;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<template>
<ul class="media-tree">
<media-tree-item v-for="item in directories" :item="item" :dir="dir"></media-tree-item>
</ul>
</template>

<script>
export default {
name: 'media-tree',
props: ['tree', 'dir'],
computed: {
directories: function () {
return this.tree.children
.filter((item) => {
// Hide hidden files
return item.name.indexOf('.') !== 0;
})
.filter((item) => {
// Show only directories
return item.type === "dir";
})
.sort((a, b) => {
// Sort alphabetically
return (a.name.toUpperCase() < b.name.toUpperCase()) ? -1 : 1;
})
}
}
}
</script>
27 changes: 27 additions & 0 deletions administrator/components/com_media/resources/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Vue from "vue";
import App from "./components/app.vue";
import Tree from "./components/tree/tree.vue";
import TreeItem from "./components/tree/item.vue";
import Browser from "./components/browser/browser.vue";
import BrowserItem from "./components/browser/item.vue";
import Event from "./app/Event";

// Media Manager namespace
window.Media = window.Media || {};

// Register the Event Bus
window.Media.Event = new Event();

// Register the vue components
Vue.component('media-tree', Tree);
Vue.component('media-tree-item', TreeItem);
Vue.component('media-browser', Browser);
Vue.component('media-browser-item', BrowserItem);

// Create the root Vue instance
document.addEventListener("DOMContentLoaded",
(e) => new Vue({
el: '#com-media',
render: h => h(App)
})
)
11 changes: 11 additions & 0 deletions administrator/components/com_media/views/media/tmpl/default.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_media
*
* @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
?>
<div id="com-media"></div>
69 changes: 69 additions & 0 deletions administrator/components/com_media/views/media/view.html.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_media
*
* @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;

/**
* Media List View
*
* @since __DEPLOY_VERSION__
*/
class MediaViewMedia extends JViewLegacy
{
/**
* Execute and display a template script.
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @since __DEPLOY_VERSION__
*/
public function display($tpl = null)
{
// Prepare the document
$this->prepareDocument();

// Prepare the toolbar
$this->prepareToolbar();

parent::display($tpl);
}

/**
* Prepare the document.
*
* @return void
*
* @since __DEPLOY_VERSION__
*/
protected function prepareDocument()
{
$doc = JFactory::getDocument();

// Add javascripts
$doc->addScript(JUri::root() . 'media/media/js/app.js');

// TODO Add stylesheets
}

/**
* Prepare the toolbar.
*
* @return void
*
* @since __DEPLOY_VERSION__
*/
protected function prepareToolbar()
{
// Set the title
JToolbarHelper::title(JText::_('COM_MEDIA'), 'images mediamanager');

// TODO add the toolbar buttons
}
}
3 changes: 3 additions & 0 deletions media/media/js/app.js

Large diffs are not rendered by default.

0 comments on commit a027e11

Please sign in to comment.