diff --git a/scm-webapp/src/main/webapp/index.html b/scm-webapp/src/main/webapp/index.html
index d653bfc0a7..308063629b 100644
--- a/scm-webapp/src/main/webapp/index.html
+++ b/scm-webapp/src/main/webapp/index.html
@@ -17,6 +17,7 @@
+
diff --git a/scm-webapp/src/main/webapp/resources/js/layout.js b/scm-webapp/src/main/webapp/resources/js/layout.js
index 97da8879b9..0c94e7eb67 100644
--- a/scm-webapp/src/main/webapp/resources/js/layout.js
+++ b/scm-webapp/src/main/webapp/resources/js/layout.js
@@ -15,13 +15,26 @@ Ext.onReady(function(){
var tabPanel = new Ext.TabPanel({
region: 'center', // a center region is ALWAYS required for border layout
deferredRender: false,
- activeTab: 0, // first tab initially active
+ activeTab: 1, // first tab initially active
items: [{
id: 'welcome',
xtype: 'panel',
title: 'Welcome',
// closable: true,
autoScroll: true
+ },{
+ id: 't_sample',
+ xtype: 'restGrid',
+ title: 'Sample',
+ autoScroll: true,
+ store: groupStore,
+ cm: groupColModel,
+ idField: 'name',
+ searchField: 'name',
+ editForm: 'sampleEditForm',
+ restAddUrl: restUrl + 'groups.json',
+ restEditUrlPattern: restUrl + 'groups/{0}.json',
+ restRemoveUrlPattern: restUrl + 'groups/{0}.json'
}]
});
diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.rest.js b/scm-webapp/src/main/webapp/resources/js/sonia.rest.js
index 84dc797a39..22c1fd46c6 100644
--- a/scm-webapp/src/main/webapp/resources/js/sonia.rest.js
+++ b/scm-webapp/src/main/webapp/resources/js/sonia.rest.js
@@ -29,3 +29,213 @@ Sonia.rest.JsonStore = Ext.extend( Ext.data.JsonStore, {
}
});
+
+Sonia.rest.EditForm = Ext.extend(Ext.form.FormPanel, {
+
+ title: 'Edit REST',
+
+ initComponent: function(){
+
+ var config = {
+ labelWidth: 80,
+ autoHeight: true,
+ frame: true,
+ title: this.title,
+ defaultType:'textfield',
+ monitorValid: true,
+ defaults: {width: 190},
+ buttons:[
+ {text: 'Ok', formBind: true, scope: this, handler: this.submit},
+ {text: 'Cancel', scope: this, handler: this.cancel}
+ ]
+ };
+
+ this.addEvents('submit', 'cancel');
+
+ Ext.apply(this, Ext.apply(this.initialConfig, config));
+ Sonia.rest.EditForm.superclass.initComponent.apply(this, arguments);
+ },
+
+ load: function(item){
+ var data = {success: true, data: item};
+ this.getForm().loadRecord( data );
+ },
+
+ submit: function(){
+ var form = this.getForm();
+ var item = this.getItem( form );
+ this.fireEvent('submit', item);
+ },
+
+ getItem: function(form){
+ // abstract funtion
+ },
+
+ cancel: function(){
+ this.fireEvent('cancel', false);
+ }
+
+});
+
+Ext.reg('restEditForm', Sonia.rest.EditForm);
+
+Sonia.rest.Grid = Ext.extend(Ext.grid.GridPanel, {
+
+ restAddUrl: null,
+ restEditUrlPattern: null,
+ restRemoveUrlPattern: null,
+ idField: null,
+ searchField: null,
+ editForm: null,
+ editWindowWidth: 300,
+
+ initComponent: function(){
+
+ var restSelModel = new Ext.grid.RowSelectionModel({
+ singleSelect: true
+ });
+
+ var restToolbar = new Ext.Toolbar({
+ items: [
+ {xtype: 'tbbutton', text: 'Add', scope: this, handler: this.showAddWindow},
+ {xtype: 'tbbutton', text: 'Edit', scope: this, handler: this.showEditWindow},
+ {xtype: 'tbbutton', text: 'Remove', scope: this, handler: this.remove},
+ {xtype: 'tbbutton', text: 'Reload', scope: this, handler: this.reload},
+ {xtype: 'tbseparator'},
+ {xtype: 'label', text: 'Search: '},
+ {xtype: 'textfield', listeners: {
+ specialkey: {
+ fn: function(field, e){
+ if (e.getKey() == e.ENTER) {
+ this.search(field.getValue());
+ }
+ },
+ scope: this
+ }
+ }}
+ ]
+ });
+
+ var config = {
+ selModel: restSelModel,
+ tbar: restToolbar,
+ viewConfig: {
+ forceFit: true
+ },
+ loadMask: true,
+ listeners: {
+ celldblclick: this.showEditWindow
+ }
+ };
+
+ Ext.apply(this, Ext.apply(this.initialConfig, config));
+ Sonia.rest.Grid.superclass.initComponent.apply(this, arguments);
+
+ // load data
+ this.store.load();
+ },
+
+ showAddWindow: function(){
+ var addWindow = new Sonia.rest.DetailWindow({
+ items: [{
+ id: 'addForm',
+ xtype: this.editForm,
+ listeners: {
+ submit: {
+ fn: function(item){
+
+ var store = this.store;
+
+ Ext.Ajax.request({
+ url: this.restAddUrl,
+ jsonData: item,
+ method: 'POST',
+ success: function(){
+ store.reload();
+ addWindow.close();
+ },
+ failure: function(){
+ alert( 'failure' );
+ }
+ });
+
+ },
+ scope: this
+ },
+ cancel: function(){
+ addWindow.close();
+ }
+ }
+ }]
+ });
+
+ addWindow.show();
+ },
+
+ showEditWindow: function(){
+ if ( this.selModel.hasSelection() ){
+ console.debug( 'showEditWindow' );
+ }
+ },
+
+ remove: function(){
+ if ( this.selModel.hasSelection() ){
+ var id = this.selModel.getSelected().data[this.idField];
+
+ if ( debug ){
+ console.debug( 'remove item ' + id );
+ }
+
+ // TODO show confirmation dialog
+
+ var store = this.store;
+
+ var url = String.format( this.restRemoveUrlPattern, id );
+ Ext.Ajax.request({
+ url: url,
+ method: 'DELETE',
+ success: function(){
+ store.reload();
+ },
+ failure: function(){
+ alert( 'failure' );
+ }
+ });
+ }
+ },
+
+ reload: function(){
+ this.store.reload();
+ },
+
+ search: function(value){
+ if ( this.searchField != null ){
+ this.store.filter(this.searchField, new RegExp('.*' + value + '.*'));
+ }
+ }
+
+});
+
+Ext.reg('restGrid', Sonia.rest.Grid);
+
+Sonia.rest.DetailWindow = Ext.extend(Ext.Window, {
+
+ initComponent: function(){
+ var config = {
+ layout:'fit',
+ width: 300,
+ autoScroll: true,
+ closable: false,
+ resizable: false,
+ plain: true,
+ border: false,
+ modal: true
+ };
+
+ Ext.apply(this, Ext.apply(this.initialConfig, config));
+ Sonia.rest.DetailWindow.superclass.initComponent.apply(this, arguments);
+ }
+
+});
+
+Ext.reg('restDetailWindow', Sonia.rest.DetailWindow);
diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.sample.js b/scm-webapp/src/main/webapp/resources/js/sonia.sample.js
new file mode 100644
index 0000000000..04c5a68650
--- /dev/null
+++ b/scm-webapp/src/main/webapp/resources/js/sonia.sample.js
@@ -0,0 +1,118 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+Ext.ns("Sonia.sample");
+
+Sonia.sample.EditForm = new Ext.extend(Sonia.rest.EditForm, {
+
+ initComponent: function(){
+
+ if ( this.store == null ){
+ this.store = new Ext.data.ArrayStore({
+ fields: [ 'name' ]
+ });
+ }
+
+ var config = {
+ items:[{
+ fieldLabel:'Name',
+ name:'name',
+ anchor: '100%',
+ allowBlank: false
+ },{
+ fieldLabel: 'Members',
+ xtype: 'fieldset',
+ items: [{
+ id: 'addMembersView',
+ name: 'members',
+ xtype: 'listview',
+ columnResize: false,
+ multiSelect: true,
+ hideHeaders: true,
+ store: this.store,
+ columns: [{
+ xtype: 'lvcolumn',
+ header: 'Member',
+ dataIndex: 'name'
+ }]
+ }]
+ },{
+ fieldLabel: 'Add Member',
+ xtype: 'compositefield',
+ items: [{
+ id: 'addMemberField',
+ name: 'addMember',
+ width: '60%',
+ xtype: 'textfield',
+ scope: this,
+ listeners: {
+ specialkey: {
+ fn: function(field, e){
+ if (e.getKey() == e.ENTER) {
+ this.addMember();
+ }
+ },
+ scope: this
+ }
+ }
+ },{
+ xtype: 'button',
+ text: 'Add',
+ scope: this,
+ handler: this.addMember
+ },{
+ xtype: 'button',
+ text: 'Del',
+ scope: this,
+ handler: this.removeSelectedMember
+ }]
+ }]
+ };
+
+ Ext.apply(this, Ext.apply(this.initialConfig, config));
+ Sonia.sample.EditForm.superclass.initComponent.apply(this, arguments);
+ },
+
+ getItem: function(form){
+
+ var memberArray = [];
+ this.store.each(function(data){
+ memberArray.push( data.get('name') );
+ });
+
+ var name = form.findField('name').getValue();
+ var group = { name: name, members: memberArray }
+
+ return group;
+ },
+
+ addMemberBySpecialKey: function(field, e){
+ if (e.getKey() == e.ENTER) {
+ addMember();
+ }
+ },
+
+ addMember: function(){
+ var field = Ext.getCmp('addMemberField');
+ var value = field.getValue();
+ if ( value != '' ){
+ this.store.add( [ new Ext.data.Record( {name: value}) ] );
+ field.setValue('');
+ }
+ },
+
+ removeSelectedMember: function(){
+ var list = Ext.getCmp('addMembersView');
+ var nodes = list.getSelectedIndexes();
+ if ( nodes != null ){
+ Ext.each(nodes, function(data, index){
+ this.store.removeAt(data);
+ }, this);
+ }
+ }
+
+});
+
+Ext.reg('sampleEditForm', Sonia.sample.EditForm);
\ No newline at end of file