mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-10-26 08:06:09 +01:00
start improving user interface
This commit is contained in:
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.api.rest.resources;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import sonia.scm.group.Group;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@Path("groups")
|
||||
@Singleton
|
||||
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
|
||||
public class GroupResource extends AbstractResource<Group>
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
public static final String PATH_PART = "groups";
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public GroupResource()
|
||||
{
|
||||
groupStore = new LinkedHashMap<String, Group>();
|
||||
groupStore.put("csit",
|
||||
new Group("static", "csit", "th", "merlec", "hopper",
|
||||
"oelkersd", "sdorra", "gollnict"));
|
||||
groupStore.put("devel",
|
||||
new Group("static", "devel", "sdorra", "th", "merlec",
|
||||
"oelkersd"));
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
@Override
|
||||
protected void addItem(Group item)
|
||||
{
|
||||
groupStore.put(item.getName(), item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
@Override
|
||||
protected void removeItem(Group item)
|
||||
{
|
||||
groupStore.remove(item.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param name
|
||||
* @param item
|
||||
*/
|
||||
@Override
|
||||
protected void updateItem(String name, Group item)
|
||||
{
|
||||
Group group = groupStore.get(name);
|
||||
|
||||
group.setMembers(item.getMembers());
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected Group[] getAllItems()
|
||||
{
|
||||
Collection<Group> groupCollection = groupStore.values();
|
||||
|
||||
return groupCollection.toArray(new Group[groupCollection.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param item
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected String getId(Group item)
|
||||
{
|
||||
return item.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected Group getItem(String name)
|
||||
{
|
||||
return groupStore.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected String getPathPart()
|
||||
{
|
||||
return PATH_PART;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private LinkedHashMap<String, Group> groupStore;
|
||||
}
|
||||
@@ -19,7 +19,6 @@
|
||||
<script type="text/javascript" src="resources/js/sonia.rest.js"></script>
|
||||
<script type="text/javascript" src="resources/js/sonia.navigation.js"></script>
|
||||
<script type="text/javascript" src="resources/js/sonia.login.js"></script>
|
||||
<script type="text/javascript" src="resources/js/sonia.group.js"></script>
|
||||
<script type="text/javascript" src="resources/js/sonia.repository.js"></script>
|
||||
<script type="text/javascript" src="resources/js/sonia.config.js"></script>
|
||||
<script type="text/javascript" src="resources/js/layout.js"></script>
|
||||
|
||||
@@ -62,12 +62,14 @@ Ext.onReady(function(){
|
||||
tabPanel.setActiveTab(id);
|
||||
}
|
||||
|
||||
function addGroupPanel(){
|
||||
addTabPanel('t_group', 'groupGrid', 'Groups');
|
||||
}
|
||||
|
||||
function addRepositoryPanel(){
|
||||
addTabPanel('t_repository', 'repositoryGrid', 'Repositories');
|
||||
tabPanel.add({
|
||||
id: 't_repository',
|
||||
title: 'Repositories',
|
||||
xtype: 'restPanel',
|
||||
grid: {xtype: 'repositoryGrid'}
|
||||
});
|
||||
tabPanel.setActiveTab('t_repository');
|
||||
}
|
||||
|
||||
function addConfigPanel(){
|
||||
@@ -79,9 +81,6 @@ Ext.onReady(function(){
|
||||
panel.addSections([{
|
||||
title: 'Main',
|
||||
items: [{
|
||||
label: 'Groups',
|
||||
fn: addGroupPanel
|
||||
},{
|
||||
label: 'Repositories',
|
||||
fn: addRepositoryPanel
|
||||
}]
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
Ext.ns('Sonia.group');
|
||||
|
||||
Sonia.group.EditForm = new Ext.extend(Sonia.rest.EditForm, {
|
||||
|
||||
initComponent: function(){
|
||||
this.store = new Ext.data.ArrayStore({
|
||||
fields: [ 'name' ]
|
||||
});
|
||||
|
||||
var update = this.data != null;
|
||||
|
||||
var config = {
|
||||
title: 'Edit Group',
|
||||
focusField: 'groupName',
|
||||
items:[{
|
||||
id: 'groupName',
|
||||
fieldLabel:'Name',
|
||||
name:'name',
|
||||
anchor: '100%',
|
||||
allowBlank: false,
|
||||
readOnly: update
|
||||
},{
|
||||
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.group.EditForm.superclass.initComponent.apply(this, arguments);
|
||||
},
|
||||
|
||||
load: function(item){
|
||||
var members = item.members;
|
||||
for (var i=0; i<members.length; i++){
|
||||
this.store.add( [ new Ext.data.Record( {name: members[i]}) ] );
|
||||
}
|
||||
this.getForm().loadRecord({success: true, data: item});
|
||||
},
|
||||
|
||||
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('groupEditForm', Sonia.group.EditForm);
|
||||
|
||||
Sonia.group.Grid = Ext.extend(Sonia.rest.Grid, {
|
||||
|
||||
initComponent: function(){
|
||||
|
||||
var groupColModel = new Ext.grid.ColumnModel({
|
||||
columns: [
|
||||
{header: 'Name', sortable: true, width: 200, dataIndex: 'name'},
|
||||
{header: 'Members', sortable: true, dataIndex: 'members'}
|
||||
]
|
||||
});
|
||||
|
||||
var groupStore = new Sonia.rest.JsonStore({
|
||||
url: restUrl + 'groups.json',
|
||||
root: 'groups',
|
||||
fields: [
|
||||
'name', 'members'
|
||||
],
|
||||
sortInfo: {
|
||||
field: 'name'
|
||||
}
|
||||
});
|
||||
|
||||
var config = {
|
||||
store: groupStore,
|
||||
colModel: groupColModel,
|
||||
idField: 'name',
|
||||
searchField: 'name',
|
||||
editForm: 'groupEditForm',
|
||||
restAddUrl: restUrl + 'groups.json',
|
||||
restEditUrlPattern: restUrl + 'groups/{0}.json',
|
||||
restRemoveUrlPattern: restUrl + 'groups/{0}.json'
|
||||
};
|
||||
|
||||
Ext.apply(this, Ext.apply(this.initialConfig, config));
|
||||
Sonia.group.Grid.superclass.initComponent.apply(this, arguments);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Ext.reg('groupGrid', Sonia.group.Grid);
|
||||
@@ -79,7 +79,10 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
|
||||
idField: 'id',
|
||||
nameField: 'name',
|
||||
searchField: 'name',
|
||||
editForm: 'repositoryEditForm',
|
||||
editForm: {
|
||||
id: 'repositoryForm',
|
||||
xtype: 'repositoryEditForm'
|
||||
},
|
||||
restAddUrl: restUrl + 'repositories.json',
|
||||
restEditUrlPattern: restUrl + 'repositories/{0}.json',
|
||||
restRemoveUrlPattern: restUrl + 'repositories/{0}.json'
|
||||
|
||||
@@ -42,13 +42,13 @@ Sonia.rest.EditForm = Ext.extend(Ext.form.FormPanel, {
|
||||
initComponent: function(){
|
||||
|
||||
var config = {
|
||||
labelWidth: 80,
|
||||
labelWidth: 100,
|
||||
autoHeight: true,
|
||||
frame: true,
|
||||
title: this.title,
|
||||
defaultType:'textfield',
|
||||
monitorValid: true,
|
||||
defaults: {width: 190},
|
||||
defaults: {width: 240},
|
||||
listeners: {
|
||||
afterrender: {
|
||||
fn: function(){
|
||||
@@ -59,6 +59,7 @@ Sonia.rest.EditForm = Ext.extend(Ext.form.FormPanel, {
|
||||
scope: this
|
||||
}
|
||||
},
|
||||
buttonAlign: 'center',
|
||||
buttons:[
|
||||
{text: 'Ok', formBind: true, scope: this, handler: this.submit},
|
||||
{text: 'Cancel', scope: this, handler: this.cancel}
|
||||
@@ -117,7 +118,7 @@ Sonia.rest.Grid = Ext.extend(Ext.grid.GridPanel, {
|
||||
|
||||
var restToolbar = new Ext.Toolbar({
|
||||
items: [
|
||||
{xtype: 'tbbutton', text: 'Add', scope: this, handler: this.showAddWindow},
|
||||
{xtype: 'tbbutton', text: 'Add', scope: this, handler: this.showAddForm},
|
||||
{xtype: 'tbbutton', text: 'Edit', scope: this, handler: this.showEditWindow},
|
||||
{xtype: 'tbbutton', text: 'Remove', scope: this, handler: this.removeItem},
|
||||
{xtype: 'tbbutton', text: 'Reload', scope: this, handler: this.reload},
|
||||
@@ -137,6 +138,8 @@ Sonia.rest.Grid = Ext.extend(Ext.grid.GridPanel, {
|
||||
});
|
||||
|
||||
var config = {
|
||||
region: 'center',
|
||||
autoHeight: true,
|
||||
selModel: restSelModel,
|
||||
tbar: restToolbar,
|
||||
viewConfig: {
|
||||
@@ -155,95 +158,101 @@ Sonia.rest.Grid = Ext.extend(Ext.grid.GridPanel, {
|
||||
this.store.load();
|
||||
},
|
||||
|
||||
showAddWindow: function(){
|
||||
var addWindow = new Sonia.rest.DetailWindow({
|
||||
items: [{
|
||||
id: 'addForm',
|
||||
xtype: this.editForm,
|
||||
listeners: {
|
||||
submit: {
|
||||
fn: function(item){
|
||||
showPanel: function(pn){
|
||||
var panel = Ext.getCmp('southpanel');
|
||||
panel.removeAll();
|
||||
panel.add( pn );
|
||||
panel.doLayout();
|
||||
},
|
||||
|
||||
var store = this.store;
|
||||
|
||||
if ( debug ){
|
||||
console.debug( 'add item ' + item[this.idField] );
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}]
|
||||
resetPanel: function(){
|
||||
this.showPanel({
|
||||
xtype: 'panel',
|
||||
html: 'select or add'
|
||||
});
|
||||
},
|
||||
|
||||
addWindow.show();
|
||||
showAddForm: function(){
|
||||
var form = this.editForm;
|
||||
form.listeners = {
|
||||
submit: {
|
||||
fn: function(item){
|
||||
|
||||
var store = this.store;
|
||||
|
||||
if ( debug ){
|
||||
console.debug( 'add item ' + item[this.nameField] );
|
||||
}
|
||||
Ext.Ajax.request({
|
||||
url: this.restAddUrl,
|
||||
jsonData: item,
|
||||
method: 'POST',
|
||||
scope: this,
|
||||
success: function(){
|
||||
store.reload();
|
||||
this.resetPanel();
|
||||
},
|
||||
failure: function(){
|
||||
alert( 'failure' );
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
scope: this
|
||||
},
|
||||
cancel: {
|
||||
fn: this.resetPanel,
|
||||
scope: this
|
||||
}
|
||||
};
|
||||
|
||||
this.showPanel( form );
|
||||
},
|
||||
|
||||
showEditWindow: function(){
|
||||
if ( this.selModel.hasSelection() ){
|
||||
|
||||
var data = this.selModel.getSelected().data;
|
||||
|
||||
var editWindow = new Sonia.rest.DetailWindow({
|
||||
items: [{
|
||||
id: 'editForm',
|
||||
xtype: this.editForm,
|
||||
data: data,
|
||||
listeners: {
|
||||
submit: {
|
||||
fn: function(item){
|
||||
var form = this.editForm;
|
||||
form.data = data;
|
||||
form.listeners = {
|
||||
submit: {
|
||||
fn: function(item){
|
||||
|
||||
item = Ext.apply(data, item);
|
||||
item = Ext.apply(data, item);
|
||||
|
||||
var store = this.store;
|
||||
var id = data[this.idField];
|
||||
var url = String.format(this.restEditUrlPattern, id);
|
||||
var store = this.store;
|
||||
var id = data[this.idField];
|
||||
var url = String.format(this.restEditUrlPattern, id);
|
||||
|
||||
if ( debug ){
|
||||
console.debug( 'update item ' + id );
|
||||
}
|
||||
|
||||
Ext.Ajax.request({
|
||||
url: url,
|
||||
jsonData: item,
|
||||
method: 'PUT',
|
||||
success: function(){
|
||||
store.reload();
|
||||
editWindow.close();
|
||||
},
|
||||
failure: function(){
|
||||
alert( 'failure' );
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
scope: this
|
||||
},
|
||||
cancel: function(){
|
||||
editWindow.close();
|
||||
if ( debug ){
|
||||
console.debug( 'update item ' + id );
|
||||
}
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
editWindow.show();
|
||||
Ext.Ajax.request({
|
||||
url: url,
|
||||
jsonData: item,
|
||||
method: 'PUT',
|
||||
scope: this,
|
||||
success: function(){
|
||||
store.reload();
|
||||
this.resetPanel();
|
||||
},
|
||||
failure: function(){
|
||||
alert( 'failure' );
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
scope: this
|
||||
},
|
||||
cancel: {
|
||||
fn: this.resetPanel,
|
||||
scope: this
|
||||
}
|
||||
}
|
||||
|
||||
this.showPanel( form );
|
||||
}
|
||||
},
|
||||
|
||||
@@ -264,7 +273,7 @@ Sonia.rest.Grid = Ext.extend(Ext.grid.GridPanel, {
|
||||
if ( result == 'ok' ){
|
||||
|
||||
if ( debug ){
|
||||
console.debug( 'remove item' );
|
||||
console.debug( 'remove item ' + id );
|
||||
}
|
||||
|
||||
Ext.Ajax.request({
|
||||
@@ -299,6 +308,42 @@ Sonia.rest.Grid = Ext.extend(Ext.grid.GridPanel, {
|
||||
|
||||
Ext.reg('restGrid', Sonia.rest.Grid);
|
||||
|
||||
Sonia.rest.RestPanel = Ext.extend(Ext.Panel,{
|
||||
|
||||
grid: null,
|
||||
title: null,
|
||||
|
||||
initComponent: function(){
|
||||
var config = {
|
||||
title: this.title,
|
||||
layout: 'border',
|
||||
border: false,
|
||||
closable: true,
|
||||
autoScroll: true,
|
||||
items:[
|
||||
this.grid,{
|
||||
id: 'southpanel',
|
||||
xtype: 'panel',
|
||||
region: 'south',
|
||||
split: true,
|
||||
frame: true,
|
||||
height: 200,
|
||||
items:[{
|
||||
xtype: 'panel',
|
||||
html: 'Select or add'
|
||||
}]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
Ext.apply(this, Ext.apply(this.initialConfig, config));
|
||||
Sonia.rest.RestPanel.superclass.initComponent.apply(this, arguments);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Ext.reg('restPanel', Sonia.rest.RestPanel);
|
||||
|
||||
Sonia.rest.DetailWindow = Ext.extend(Ext.Window, {
|
||||
|
||||
initComponent: function(){
|
||||
|
||||
Reference in New Issue
Block a user