mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-14 01:15:44 +01:00
improve user interface
This commit is contained in:
@@ -48,18 +48,11 @@
|
|||||||
<script type="text/javascript" src="resources/extjs/adapter/ext/ext-base.js"></script>
|
<script type="text/javascript" src="resources/extjs/adapter/ext/ext-base.js"></script>
|
||||||
<script type="text/javascript" src="resources/extjs/ext-all-debug.js"></script>
|
<script type="text/javascript" src="resources/extjs/ext-all-debug.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript" src="resources/js/global.js"></script>
|
<script type="text/javascript" src="resources/js/sonia.global.js"></script>
|
||||||
<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.navigation.js"></script>
|
||||||
<script type="text/javascript" src="resources/js/sonia.login.js"></script>
|
<script type="text/javascript" src="resources/js/sonia.login.js"></script>
|
||||||
<script type="text/javascript" src="resources/js/sonia.repository.js"></script>
|
<script type="text/javascript" src="resources/js/sonia.scm.js"></script>
|
||||||
<script type="text/javascript" src="resources/js/sonia.config.js"></script>
|
|
||||||
<script type="text/javascript" src="resources/js/layout.js"></script>
|
|
||||||
<script type="text/javascript" src="plugins/sonia.plugin.js"></script>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
|
|
||||||
-->
|
|
||||||
<title>SCM-WebAPP</title>
|
<title>SCM-WebAPP</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -1,134 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from this
|
|
||||||
* software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* http://bitbucket.org/sdorra/scm-manager
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
Ext.ns("Sonia.config");
|
|
||||||
|
|
||||||
Sonia.config.ConfigPanel = Ext.extend(Ext.Panel, {
|
|
||||||
|
|
||||||
initComponent: function(){
|
|
||||||
|
|
||||||
var config = {
|
|
||||||
region: 'center',
|
|
||||||
bodyCssClass: 'x-panel-mc',
|
|
||||||
trackResetOnLoad: true,
|
|
||||||
autoScroll: true,
|
|
||||||
border: false,
|
|
||||||
frame: false,
|
|
||||||
collapsible: false,
|
|
||||||
collapsed: false,
|
|
||||||
items: repositoryConfigPanels
|
|
||||||
}
|
|
||||||
|
|
||||||
Ext.apply(this, Ext.apply(this.initialConfig, config));
|
|
||||||
Sonia.config.ConfigPanel.superclass.initComponent.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
Ext.reg("configPanel", Sonia.config.ConfigPanel);
|
|
||||||
|
|
||||||
Sonia.config.ConfigForm = Ext.extend(Ext.form.FormPanel, {
|
|
||||||
|
|
||||||
title: 'Config Form',
|
|
||||||
items: null,
|
|
||||||
onSubmit: null,
|
|
||||||
getValues: null,
|
|
||||||
|
|
||||||
initComponent: function(){
|
|
||||||
|
|
||||||
var config = {
|
|
||||||
title: null,
|
|
||||||
style: 'margin: 10px',
|
|
||||||
trackResetOnLoad : true,
|
|
||||||
autoScroll : true,
|
|
||||||
border : false,
|
|
||||||
frame : false,
|
|
||||||
collapsible : false,
|
|
||||||
collapsed : false,
|
|
||||||
layoutConfig : {
|
|
||||||
labelSeparator : ''
|
|
||||||
},
|
|
||||||
items : [{
|
|
||||||
xtype : 'fieldset',
|
|
||||||
checkboxToggle : false,
|
|
||||||
title : this.title,
|
|
||||||
collapsible : true,
|
|
||||||
autoHeight : true,
|
|
||||||
labelWidth : 140,
|
|
||||||
buttonAlign: 'left',
|
|
||||||
layoutConfig : {
|
|
||||||
labelSeparator : ''
|
|
||||||
},
|
|
||||||
listeners: {
|
|
||||||
render: function(){
|
|
||||||
if ( this.onLoad != null && Ext.isFunction( this.onLoad ) ){
|
|
||||||
this.onLoad(this.el);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scope: this
|
|
||||||
},
|
|
||||||
items: this.items,
|
|
||||||
buttons: [{
|
|
||||||
text: 'Save',
|
|
||||||
scope: this,
|
|
||||||
formBind: true,
|
|
||||||
handler: this.submitForm
|
|
||||||
},{
|
|
||||||
text: 'Reset',
|
|
||||||
scope: this,
|
|
||||||
handler: function(){
|
|
||||||
this.getForm().reset();
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
|
|
||||||
Ext.apply(this, Ext.apply(this.initialConfig, config));
|
|
||||||
Sonia.config.ConfigForm.superclass.initComponent.apply(this, arguments);
|
|
||||||
},
|
|
||||||
|
|
||||||
load: function(values){
|
|
||||||
this.getForm().loadRecord({
|
|
||||||
success: true,
|
|
||||||
data: values
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
submitForm: function(){
|
|
||||||
var form = this.getForm();
|
|
||||||
if ( this.onSubmit != null && Ext.isFunction( this.onSubmit ) ){
|
|
||||||
this.onSubmit( form.getValues() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
Ext.reg("configForm", Sonia.config.ConfigForm);
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
* Copyright (c) 2009, Sebastian Sdorra
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -29,19 +29,17 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
var debug = true;
|
var debug = true;
|
||||||
var state = null;
|
var state = null;
|
||||||
|
|
||||||
// functions called after login
|
// functions called after login
|
||||||
var authCallbacks = [];
|
var loginCallbacks = [];
|
||||||
|
|
||||||
// config form panels
|
// function called after logout
|
||||||
var repositoryConfigPanels = [];
|
var logoutCallbacks = [];
|
||||||
|
|
||||||
function registerConfigPanel(panel){
|
|
||||||
repositoryConfigPanels.push( panel );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// TODO: move to sonia.repository.js
|
||||||
var repositoryTypeStore = new Ext.data.JsonStore({
|
var repositoryTypeStore = new Ext.data.JsonStore({
|
||||||
id: 1,
|
id: 1,
|
||||||
fields: [ 'displayName', 'name' ]
|
fields: [ 'displayName', 'name' ]
|
||||||
@@ -50,12 +48,51 @@ var repositoryTypeStore = new Ext.data.JsonStore({
|
|||||||
var restUrl = "api/rest/";
|
var restUrl = "api/rest/";
|
||||||
|
|
||||||
function loadState(s){
|
function loadState(s){
|
||||||
state = s;
|
if ( debug ){
|
||||||
console.debug( s );
|
console.debug( s );
|
||||||
|
}
|
||||||
|
state = s;
|
||||||
|
// load repository types from callback
|
||||||
repositoryTypeStore.loadData(state.repositoryTypes);
|
repositoryTypeStore.loadData(state.repositoryTypes);
|
||||||
Ext.each(authCallbacks, function(callback){
|
// call login callback functions
|
||||||
|
Ext.each(loginCallbacks, function(callback){
|
||||||
if ( Ext.isFunction(callback) ){
|
if ( Ext.isFunction(callback) ){
|
||||||
callback(state);
|
callback(state);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function logout(){
|
||||||
|
Ext.Ajax.request({
|
||||||
|
url: restUrl + 'authentication/logout.json',
|
||||||
|
method: 'GET',
|
||||||
|
success: function(){
|
||||||
|
if ( debug ){
|
||||||
|
console.debug('logout success');
|
||||||
|
}
|
||||||
|
// clear state
|
||||||
|
state = null;
|
||||||
|
// clear repository store
|
||||||
|
repositoryTypeStore.removeAll();
|
||||||
|
// remove all tabs
|
||||||
|
Ext.getCmp('mainTabPanel').removeAll();
|
||||||
|
// remove navigation items
|
||||||
|
Ext.getCmp('navigationPanel').removeAll();
|
||||||
|
// call logout callback functions
|
||||||
|
Ext.each(logoutCallbacks, function(callback){
|
||||||
|
if ( Ext.isFunction(callback) ){
|
||||||
|
callback(state);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// show login window
|
||||||
|
var loginWin = new Sonia.login.Window();
|
||||||
|
loginWin.show();
|
||||||
|
},
|
||||||
|
failure: function(){
|
||||||
|
if ( debug ){
|
||||||
|
console.debug('logout failed');
|
||||||
|
}
|
||||||
|
Ext.Msg.alert('Logout Failed!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -50,7 +50,7 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{
|
|||||||
items:[{
|
items:[{
|
||||||
id: 'username',
|
id: 'username',
|
||||||
fieldLabel:'Username',
|
fieldLabel:'Username',
|
||||||
name:'username',
|
name: 'username',
|
||||||
allowBlank:false,
|
allowBlank:false,
|
||||||
listeners: {
|
listeners: {
|
||||||
specialkey: {
|
specialkey: {
|
||||||
@@ -60,9 +60,9 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{
|
|||||||
}
|
}
|
||||||
},{
|
},{
|
||||||
fieldLabel:'Password',
|
fieldLabel:'Password',
|
||||||
name:'password',
|
name: 'password',
|
||||||
inputType:'password',
|
inputType: 'password',
|
||||||
allowBlank:false,
|
allowBlank: false,
|
||||||
listeners: {
|
listeners: {
|
||||||
specialkey: {
|
specialkey: {
|
||||||
fn: this.specialKeyPressed,
|
fn: this.specialKeyPressed,
|
||||||
@@ -71,7 +71,7 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{
|
|||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
buttons:[{
|
buttons:[{
|
||||||
text:'Login',
|
text: 'Login',
|
||||||
formBind: true,
|
formBind: true,
|
||||||
scope: this,
|
scope: this,
|
||||||
handler: this.authenticate
|
handler: this.authenticate
|
||||||
@@ -90,11 +90,17 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{
|
|||||||
waitMsg:'Sending data...',
|
waitMsg:'Sending data...',
|
||||||
|
|
||||||
success: function(form, action){
|
success: function(form, action){
|
||||||
|
if ( debug ){
|
||||||
|
console.debug( 'login success' );
|
||||||
|
}
|
||||||
loadState( action.result );
|
loadState( action.result );
|
||||||
},
|
},
|
||||||
|
|
||||||
failure: function(form, action){
|
failure: function(form, action){
|
||||||
Ext.Msg.alert('Login Failure!');
|
if ( debug ){
|
||||||
|
console.debug( 'login failed' );
|
||||||
|
}
|
||||||
|
Ext.Msg.alert('Login failed!');
|
||||||
form.reset();
|
form.reset();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -116,7 +122,6 @@ Ext.reg('soniaLoginForm', Sonia.login.Form);
|
|||||||
Sonia.login.Window = Ext.extend(Ext.Window,{
|
Sonia.login.Window = Ext.extend(Ext.Window,{
|
||||||
|
|
||||||
initComponent: function(){
|
initComponent: function(){
|
||||||
|
|
||||||
var form = new Sonia.login.Form();
|
var form = new Sonia.login.Form();
|
||||||
form.on('actioncomplete', function(){
|
form.on('actioncomplete', function(){
|
||||||
this.fireEvent('success');
|
this.fireEvent('success');
|
||||||
@@ -139,7 +144,6 @@ Sonia.login.Window = Ext.extend(Ext.Window,{
|
|||||||
|
|
||||||
Ext.apply(this, Ext.apply(this.initialConfig, config));
|
Ext.apply(this, Ext.apply(this.initialConfig, config));
|
||||||
Sonia.login.Window.superclass.initComponent.apply(this, arguments);
|
Sonia.login.Window.superclass.initComponent.apply(this, arguments);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,137 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from this
|
|
||||||
* software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* http://bitbucket.org/sdorra/scm-manager
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
Ext.ns('Sonia.repository');
|
|
||||||
|
|
||||||
Sonia.repository.EditForm = Ext.extend(Sonia.rest.EditForm, {
|
|
||||||
|
|
||||||
initComponent: function(){
|
|
||||||
|
|
||||||
var update = this.data != null;
|
|
||||||
|
|
||||||
var config = {
|
|
||||||
title: 'Edit Repository',
|
|
||||||
focusField: 'repositoryName',
|
|
||||||
items:[
|
|
||||||
{ id: 'repositoryName', fieldLabel: 'Name', name: 'name', readOnly: update, allowBlank: false},
|
|
||||||
{
|
|
||||||
fieldLabel: 'Type',
|
|
||||||
name: 'type',
|
|
||||||
xtype: 'combo',
|
|
||||||
readOnly: update,
|
|
||||||
hiddenName : 'type',
|
|
||||||
typeAhead: true,
|
|
||||||
triggerAction: 'all',
|
|
||||||
lazyRender: true,
|
|
||||||
mode: 'local',
|
|
||||||
editable: false,
|
|
||||||
store: repositoryTypeStore,
|
|
||||||
valueField: 'name',
|
|
||||||
displayField: 'displayName',
|
|
||||||
allowBlank: false
|
|
||||||
},
|
|
||||||
|
|
||||||
{fieldLabel: 'Contact', name: 'contact'},
|
|
||||||
{fieldLabel: 'Description', name: 'description', xtype: 'textarea'}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
Ext.apply(this, Ext.apply(this.initialConfig, config));
|
|
||||||
Sonia.repository.EditForm.superclass.initComponent.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
Ext.reg('repositoryEditForm', Sonia.repository.EditForm);
|
|
||||||
|
|
||||||
Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
|
|
||||||
|
|
||||||
urlTemplate: '<a href="{0}" target="_blank">{0}</a>',
|
|
||||||
mailtoTemplate: '<a href="mailto: {0}">{0}</a>',
|
|
||||||
|
|
||||||
initComponent: function(){
|
|
||||||
|
|
||||||
var repositoryStore = new Sonia.rest.JsonStore({
|
|
||||||
url: restUrl + 'repositories.json',
|
|
||||||
root: 'repositories',
|
|
||||||
fields: [ 'id', 'name', 'type', 'contact', 'description', 'creationDate', 'url' ],
|
|
||||||
sortInfo: {
|
|
||||||
field: 'name'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var repositoryColModel = new Ext.grid.ColumnModel({
|
|
||||||
columns: [
|
|
||||||
{header: 'Name', sortable: true, width: 100, dataIndex: 'name'},
|
|
||||||
{header: 'Type', sortable: true, width: 50, dataIndex: 'type', renderer: this.renderRepositoryType},
|
|
||||||
{header: 'Contact', sortable: true, width: 80, dataIndex: 'contact', scope: this, renderer: this.renderMailto},
|
|
||||||
{header: 'Description', sortable: true, dataIndex: 'description'},
|
|
||||||
{header: 'Creation date', sortable: true, width: 60, dataIndex: 'creationDate'},
|
|
||||||
{header: 'Url', sortable: true, dataIndex: 'url', width: 120, scope: this, renderer: this.renderUrl}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
var config = {
|
|
||||||
store: repositoryStore,
|
|
||||||
colModel: repositoryColModel,
|
|
||||||
idField: 'id',
|
|
||||||
nameField: 'name',
|
|
||||||
searchField: 'name',
|
|
||||||
editForm: {
|
|
||||||
id: 'repositoryForm',
|
|
||||||
xtype: 'repositoryEditForm'
|
|
||||||
},
|
|
||||||
restAddUrl: restUrl + 'repositories.json',
|
|
||||||
restEditUrlPattern: restUrl + 'repositories/{0}.json',
|
|
||||||
restRemoveUrlPattern: restUrl + 'repositories/{0}.json'
|
|
||||||
};
|
|
||||||
|
|
||||||
Ext.apply(this, Ext.apply(this.initialConfig, config));
|
|
||||||
Sonia.repository.Grid.superclass.initComponent.apply(this, arguments);
|
|
||||||
},
|
|
||||||
|
|
||||||
renderRepositoryType: function(repositoryType){
|
|
||||||
return repositoryTypeStore.queryBy(function(rec){
|
|
||||||
return rec.data.name == repositoryType;
|
|
||||||
}).itemAt(0).data.displayName;
|
|
||||||
},
|
|
||||||
|
|
||||||
renderUrl: function(url){
|
|
||||||
return String.format( this.urlTemplate, url );
|
|
||||||
},
|
|
||||||
|
|
||||||
renderMailto: function(mail){
|
|
||||||
return String.format( this.mailtoTemplate, mail );
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
Ext.reg('repositoryGrid', Sonia.repository.Grid);
|
|
||||||
@@ -1,371 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of SCM-Manager; nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from this
|
|
||||||
* software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* http://bitbucket.org/sdorra/scm-manager
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
Ext.ns("Sonia.rest");
|
|
||||||
|
|
||||||
Sonia.rest.JsonStore = Ext.extend( Ext.data.JsonStore, {
|
|
||||||
|
|
||||||
constructor: function(config) {
|
|
||||||
var baseConfig = {
|
|
||||||
autoLoad: false,
|
|
||||||
listeners: {
|
|
||||||
// fix jersey empty array problem
|
|
||||||
exception: {
|
|
||||||
fn: function(proxy, type, action, options, response, arg){
|
|
||||||
var status = response.status;
|
|
||||||
if ( status == 200 && action == 'read' && response.responseText == 'null' ){
|
|
||||||
if ( debug ){
|
|
||||||
console.debug( 'empty array, clear whole store' );
|
|
||||||
}
|
|
||||||
this.removeAll();
|
|
||||||
} else {
|
|
||||||
alert( action + "(" + status + "): " + response.responseText );
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scope: this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Sonia.rest.JsonStore.superclass.constructor.call(this, Ext.apply(config, baseConfig));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
Sonia.rest.EditForm = Ext.extend(Ext.form.FormPanel, {
|
|
||||||
|
|
||||||
title: 'Edit REST',
|
|
||||||
data: null,
|
|
||||||
focusField: null,
|
|
||||||
|
|
||||||
initComponent: function(){
|
|
||||||
|
|
||||||
var config = {
|
|
||||||
labelWidth: 100,
|
|
||||||
autoHeight: true,
|
|
||||||
frame: true,
|
|
||||||
title: this.title,
|
|
||||||
defaultType:'textfield',
|
|
||||||
monitorValid: true,
|
|
||||||
defaults: {width: 240},
|
|
||||||
listeners: {
|
|
||||||
afterrender: {
|
|
||||||
fn: function(){
|
|
||||||
if ( this.focusField != null && this.data == null ){
|
|
||||||
Ext.getCmp(this.focusField).focus(true, 500);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scope: this
|
|
||||||
}
|
|
||||||
},
|
|
||||||
buttonAlign: 'center',
|
|
||||||
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);
|
|
||||||
|
|
||||||
if ( this.data != null ){
|
|
||||||
this.load(this.data);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
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){
|
|
||||||
return form.getFieldValues();
|
|
||||||
},
|
|
||||||
|
|
||||||
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,
|
|
||||||
nameField: 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.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},
|
|
||||||
{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 = {
|
|
||||||
region: 'center',
|
|
||||||
autoHeight: true,
|
|
||||||
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();
|
|
||||||
},
|
|
||||||
|
|
||||||
showPanel: function(pn){
|
|
||||||
var panel = Ext.getCmp('southpanel');
|
|
||||||
panel.removeAll();
|
|
||||||
panel.add( pn );
|
|
||||||
panel.doLayout();
|
|
||||||
},
|
|
||||||
|
|
||||||
resetPanel: function(){
|
|
||||||
this.showPanel({
|
|
||||||
xtype: 'panel',
|
|
||||||
html: 'select or add'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
showAddForm: function(){
|
|
||||||
var form = this.editForm;
|
|
||||||
form.data = null;
|
|
||||||
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 form = this.editForm;
|
|
||||||
form.data = data;
|
|
||||||
form.listeners = {
|
|
||||||
submit: {
|
|
||||||
fn: function(item){
|
|
||||||
|
|
||||||
item = Ext.apply(data, item);
|
|
||||||
|
|
||||||
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',
|
|
||||||
scope: this,
|
|
||||||
success: function(){
|
|
||||||
store.reload();
|
|
||||||
this.resetPanel();
|
|
||||||
},
|
|
||||||
failure: function(){
|
|
||||||
alert( 'failure' );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
scope: this
|
|
||||||
},
|
|
||||||
cancel: {
|
|
||||||
fn: this.resetPanel,
|
|
||||||
scope: this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.showPanel( form );
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
removeItem: function(){
|
|
||||||
if ( this.selModel.hasSelection() ){
|
|
||||||
var selected = this.selModel.getSelected();
|
|
||||||
var id = selected.data[this.idField]
|
|
||||||
var store = this.store;
|
|
||||||
var url = String.format( this.restRemoveUrlPattern, id );
|
|
||||||
var name = this.nameField != null ? selected.data[this.nameField] : id;
|
|
||||||
|
|
||||||
Ext.MessageBox.show({
|
|
||||||
title: 'Remove Item',
|
|
||||||
msg: 'Remove Item "' + name + '"?',
|
|
||||||
buttons: Ext.MessageBox.OKCANCEL,
|
|
||||||
icon: Ext.MessageBox.QUESTION,
|
|
||||||
fn: function(result){
|
|
||||||
if ( result == 'ok' ){
|
|
||||||
|
|
||||||
if ( debug ){
|
|
||||||
console.debug( 'remove item ' + 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.RestPanel = Ext.extend(Ext.Panel,{
|
|
||||||
|
|
||||||
grid: null,
|
|
||||||
title: null,
|
|
||||||
|
|
||||||
initComponent: function(){
|
|
||||||
var config = {
|
|
||||||
title: this.title,
|
|
||||||
layout: 'border',
|
|
||||||
border: false,
|
|
||||||
items:[
|
|
||||||
this.grid,{
|
|
||||||
id: 'southpanel',
|
|
||||||
xtype: 'panel',
|
|
||||||
region: 'south',
|
|
||||||
autoScroll: true,
|
|
||||||
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);
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -29,22 +29,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
Ext.onReady(function(){
|
Ext.onReady(function(){
|
||||||
|
|
||||||
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
|
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
|
||||||
|
|
||||||
var tabPanel = new Ext.TabPanel({
|
var mainTabPanel = new Ext.TabPanel({
|
||||||
|
id: 'mainTabPanel',
|
||||||
region: 'center',
|
region: 'center',
|
||||||
deferredRender: false,
|
deferredRender: false
|
||||||
activeTab: 0,
|
|
||||||
items: [{
|
|
||||||
id: 'welcome',
|
|
||||||
xtype: 'panel',
|
|
||||||
title: 'Welcome',
|
|
||||||
// closable: true,
|
|
||||||
autoScroll: true
|
|
||||||
}]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
new Ext.Viewport({
|
new Ext.Viewport({
|
||||||
@@ -57,7 +49,7 @@ Ext.onReady(function(){
|
|||||||
height: 75
|
height: 75
|
||||||
}), {
|
}), {
|
||||||
region: 'west',
|
region: 'west',
|
||||||
id: 'west',
|
id: 'navigationPanel',
|
||||||
title: 'Navigation',
|
title: 'Navigation',
|
||||||
xtype: 'navPanel',
|
xtype: 'navPanel',
|
||||||
split: true,
|
split: true,
|
||||||
@@ -74,70 +66,54 @@ Ext.onReady(function(){
|
|||||||
height: 16,
|
height: 16,
|
||||||
margins: '2 2 2 5'
|
margins: '2 2 2 5'
|
||||||
}),
|
}),
|
||||||
tabPanel
|
mainTabPanel
|
||||||
]});
|
]
|
||||||
|
|
||||||
function addTabPanel(id, xtype, title){
|
|
||||||
tabPanel.add({
|
|
||||||
id: id,
|
|
||||||
xtype: xtype,
|
|
||||||
title: title,
|
|
||||||
closable: true,
|
|
||||||
autoScroll: true
|
|
||||||
});
|
});
|
||||||
tabPanel.setActiveTab(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addRepositoryPanel(){
|
// check login
|
||||||
tabPanel.add({
|
|
||||||
id: 't_repository',
|
|
||||||
title: 'Repositories',
|
|
||||||
xtype: 'restPanel',
|
|
||||||
closable: true,
|
|
||||||
grid: {xtype: 'repositoryGrid'}
|
|
||||||
});
|
|
||||||
tabPanel.setActiveTab('t_repository');
|
|
||||||
}
|
|
||||||
|
|
||||||
function addConfigPanel(){
|
|
||||||
addTabPanel('t_config', 'configPanel', 'Repository Config');
|
|
||||||
}
|
|
||||||
|
|
||||||
function logout(){
|
|
||||||
Ext.Ajax.request({
|
Ext.Ajax.request({
|
||||||
url: restUrl + 'authentication/logout.json',
|
url: restUrl + 'authentication.json',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
success: function(response){
|
success: function(response){
|
||||||
tabPanel.removeAll();
|
if ( debug ){
|
||||||
Ext.getCmp('west').removeAll();
|
console.debug('login success');
|
||||||
var loginWin = new Sonia.login.Window();
|
}
|
||||||
loginWin.show();
|
var s = Ext.decode(response.responseText);
|
||||||
|
loadState(s);
|
||||||
},
|
},
|
||||||
failure: function(){
|
failure: function(){
|
||||||
alert("logout failed");
|
if ( debug ){
|
||||||
|
console.debug('login failed');
|
||||||
|
}
|
||||||
|
var loginWin = new Sonia.login.Window();
|
||||||
|
loginWin.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
// methods called after login
|
||||||
|
|
||||||
function createMainMenu(){
|
function createMainMenu(){
|
||||||
var panel = Ext.getCmp('west');
|
if ( debug ){
|
||||||
|
console.debug('create main menu');
|
||||||
|
}
|
||||||
|
var panel = Ext.getCmp('navigationPanel');
|
||||||
panel.addSections([{
|
panel.addSections([{
|
||||||
title: 'Main',
|
title: 'Main',
|
||||||
items: [{
|
items: [{
|
||||||
label: 'Repositories',
|
label: 'Repositories',
|
||||||
fn: addRepositoryPanel
|
fn: function(){console.debug( 'Repositories' );}
|
||||||
}]
|
}]
|
||||||
},{
|
},{
|
||||||
title: 'Config',
|
title: 'Config',
|
||||||
items: [{
|
items: [{
|
||||||
label: 'General',
|
label: 'General',
|
||||||
fn: function(){ console.debug( 'General Config' ); }
|
fn: function(){console.debug( 'General Config' );}
|
||||||
},{
|
},{
|
||||||
label: 'Repository Types',
|
label: 'Repository Types',
|
||||||
fn: addConfigPanel
|
fn: function(){console.debug( 'RepositoryType Config' );}
|
||||||
},{
|
},{
|
||||||
label: 'Server',
|
label: 'Server',
|
||||||
fn: function(){ console.debug( 'Server Config' ); }
|
fn: function(){console.debug( 'Server Config' );}
|
||||||
}]
|
}]
|
||||||
},{
|
},{
|
||||||
title: 'Abmelden',
|
title: 'Abmelden',
|
||||||
@@ -148,20 +124,27 @@ Ext.onReady(function(){
|
|||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create menu after login
|
function createWelcomePanel(){
|
||||||
authCallbacks.push( createMainMenu );
|
if ( debug ){
|
||||||
|
console.debug('create welcome tab');
|
||||||
Ext.Ajax.request({
|
|
||||||
url: restUrl + 'authentication.json',
|
|
||||||
method: 'GET',
|
|
||||||
success: function(response){
|
|
||||||
var s = Ext.decode(response.responseText);
|
|
||||||
loadState(s);
|
|
||||||
},
|
|
||||||
failure: function(){
|
|
||||||
var loginWin = new Sonia.login.Window();
|
|
||||||
loginWin.show();
|
|
||||||
}
|
}
|
||||||
|
mainTabPanel.add({
|
||||||
|
id: 'welcomeTab',
|
||||||
|
xtype: 'panel',
|
||||||
|
title: 'Welcome',
|
||||||
|
hideMode: 'offsets',
|
||||||
|
bodyCssClass: 'x-panel-mc',
|
||||||
|
enableTabScroll: true,
|
||||||
|
autoScroll: true
|
||||||
});
|
});
|
||||||
|
mainTabPanel.setActiveTab('welcomeTab');
|
||||||
|
}
|
||||||
|
|
||||||
|
// register login callbacks
|
||||||
|
|
||||||
|
// create menu
|
||||||
|
loginCallbacks.push( createMainMenu );
|
||||||
|
// add welcome tab
|
||||||
|
loginCallbacks.push( createWelcomePanel );
|
||||||
|
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user