Added the first work on the administration area.

This commit is contained in:
Loic d'Anterroches 2008-12-01 00:36:27 +01:00
parent 3cacf44605
commit 9c5156e6ef
19 changed files with 847 additions and 86 deletions

View File

@ -0,0 +1,169 @@
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Create a project.
*
* A kind of merge of the member configuration, overview and the
* former source tab.
*
*/
class IDF_Form_Admin_ProjectCreate extends Pluf_Form
{
public function initFields($extra=array())
{
$choices = array();
$options = array(
'git' => __('git'),
'svn' => __('Subversion'),
'mercurial' => __('mercurial'),
);
foreach (Pluf::f('allowed_scm', array()) as $key => $class) {
$choices[$options[$key]] = $key;
}
$this->fields['name'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Name'),
'initial' => '',
));
$this->fields['shortname'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Shortname'),
'initial' => 'myproject',
'help_text' => __('It must be unique for each project and composed only of letters and digits.'),
));
$this->fields['scm'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Repository type'),
'initial' => 'git',
'widget_attrs' => array('choices' => $choices),
'widget' => 'Pluf_Form_Widget_SelectInput',
));
$this->fields['svn_remote_url'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Remote Subversion repository'),
'initial' => '',
'widget_attrs' => array('size' => '30'),
));
$this->fields['svn_username'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Repository username'),
'initial' => '',
'widget_attrs' => array('size' => '15'),
));
$this->fields['svn_password'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Repository password'),
'initial' => '',
'widget' => 'Pluf_Form_Widget_PasswordInput',
));
$this->fields['owners'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Project owners'),
'initial' => $extra['user']->login,
'widget' => 'Pluf_Form_Widget_TextareaInput',
'widget_attrs' => array('rows' => 5,
'cols' => 40),
));
$this->fields['members'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Project members'),
'initial' => '',
'widget_attrs' => array('rows' => 7,
'cols' => 40),
'widget' => 'Pluf_Form_Widget_TextareaInput',
));
}
public function clean_svn_remote_url()
{
$url = trim($this->cleaned_data['svn_remote_url']);
if (strlen($url) == 0) return $url;
// we accept only starting with http(s):// to avoid people
// trying to access the local filesystem.
if (!preg_match('#^(http|https)://#', $url)) {
throw new Pluf_Form_Invalid(__('Only a remote repository available throught http or https are allowed. For example "http://somewhere.com/svn/trunk".'));
}
return $url;
}
public function clean_shortname()
{
$shortname = $this->cleaned_data['shortname'];
if (preg_match('/[^A-Za-z0-9]/', $shortname)) {
throw new Pluf_Form_Invalid(__('This shortname contains illegal characters, please use only letters and digits.'));
}
$sql = new Pluf_SQL('shortname=%s', array($shortname));
$l = Pluf::factory('IDF_Project')->getList(array('filter'=>$sql->gen()));
if ($l->count() > 0) {
throw new Pluf_Form_Invalid(__('This shortname is already used. Please select another one.'));
}
return $shortname;
}
public function clean()
{
if ($this->cleaned_data['scm'] != 'svn') {
foreach (array('svn_remote_url', 'svn_username', 'svn_password')
as $key) {
$this->cleaned_data[$key] = '';
}
}
return $this->cleaned_data;
}
public function save($commit=true)
{
if (!$this->isValid()) {
throw new Exception(__('Cannot save the model from an invalid form.'));
}
$project = new IDF_Project();
$project->name = $this->cleaned_data['name'];
$project->shortname = $this->cleaned_data['shortname'];
$project->description = __('Write your project description here.');
$project->create();
$conf = new IDF_Conf();
$conf->setProject($project);
$keys = array('scm', 'svn_remote_url',
'svn_username', 'svn_password');
foreach ($keys as $key) {
$conf->setVal($key, $this->cleaned_data[$key]);
}
$project->created();
IDF_Form_MembersConf::updateMemberships($project,
$this->cleaned_data);
$project->membershipsUpdated();
return $project;
}
}

View File

@ -0,0 +1,77 @@
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Update a project.
*
* A kind of merge of the member configuration and overview in the
* project administration area.
*
*/
class IDF_Form_Admin_ProjectUpdate extends Pluf_Form
{
public $project = null;
public function initFields($extra=array())
{
$this->project = $extra['project'];
$members = $this->project->getMembershipData('string');
$this->fields['name'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Name'),
'initial' => $this->project->name,
));
$this->fields['owners'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Project owners'),
'initial' => $members['owners'],
'widget' => 'Pluf_Form_Widget_TextareaInput',
'widget_attrs' => array('rows' => 5,
'cols' => 40),
));
$this->fields['members'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Project members'),
'initial' => $members['members'],
'widget_attrs' => array('rows' => 7,
'cols' => 40),
'widget' => 'Pluf_Form_Widget_TextareaInput',
));
}
public function save($commit=true)
{
if (!$this->isValid()) {
throw new Exception(__('Cannot save the model from an invalid form.'));
}
IDF_Form_MembersConf::updateMemberships($this->project,
$this->cleaned_data);
$this->project->membershipsUpdated();
$this->project->name = $this->cleaned_data['name'];
$this->project->update();
}
}

View File

@ -63,20 +63,33 @@ class IDF_Form_MembersConf extends Pluf_Form
if (!$this->isValid()) { if (!$this->isValid()) {
throw new Exception(__('Cannot save the model from an invalid form.')); throw new Exception(__('Cannot save the model from an invalid form.'));
} }
self::updateMemberships($this->project, $this->cleaned_data);
$this->project->membershipsUpdated();
}
/**
* The update of the memberships is done in different places. This
* avoids duplicating code.
*
* @param IDF_Project The project
* @param array The new memberships data in 'owners' and 'members' keys
*/
public static function updateMemberships($project, $cleaned_data)
{
// remove all the permissions // remove all the permissions
$cm = $this->project->getMembershipData(); $cm = $project->getMembershipData();
$def = array('owners' => Pluf_Permission::getFromString('IDF.project-owner'), $def = array('owners' => Pluf_Permission::getFromString('IDF.project-owner'),
'members' => Pluf_Permission::getFromString('IDF.project-member')); 'members' => Pluf_Permission::getFromString('IDF.project-member'));
$guser = new Pluf_User(); $guser = new Pluf_User();
foreach ($def as $key=>$perm) { foreach ($def as $key=>$perm) {
foreach ($cm[$key] as $user) { foreach ($cm[$key] as $user) {
Pluf_RowPermission::remove($user, $this->project, $perm); Pluf_RowPermission::remove($user, $project, $perm);
} }
foreach (preg_split("/\015\012|\015|\012|\,/", $this->cleaned_data[$key], -1, PREG_SPLIT_NO_EMPTY) as $login) { foreach (preg_split("/\015\012|\015|\012|\,/", $cleaned_data[$key], -1, PREG_SPLIT_NO_EMPTY) as $login) {
$sql = new Pluf_SQL('login=%s', array(trim($login))); $sql = new Pluf_SQL('login=%s', array(trim($login)));
$users = $guser->getList(array('filter'=>$sql->gen())); $users = $guser->getList(array('filter'=>$sql->gen()));
if ($users->count() == 1) { if ($users->count() == 1) {
Pluf_RowPermission::add($users[0], $this->project, $perm); Pluf_RowPermission::add($users[0], $project, $perm);
} }
} }
} }

View File

@ -24,6 +24,9 @@
/** /**
* Configuration of the source. * Configuration of the source.
*
* Only the modification of the login/password for subversion is
* authorized.
*/ */
class IDF_Form_SourceConf extends Pluf_Form class IDF_Form_SourceConf extends Pluf_Form
{ {
@ -31,26 +34,7 @@ class IDF_Form_SourceConf extends Pluf_Form
public function initFields($extra=array()) public function initFields($extra=array())
{ {
$this->conf = $extra['conf']; $this->conf = $extra['conf'];
$this->fields['scm'] = new Pluf_Form_Field_Varchar( if ($this->conf->getVal('scm', 'git') == 'svn') {
array('required' => true,
'label' => __('Repository type'),
'initial' => $this->conf->getVal('scm', 'git'),
'widget_attrs' => array('choices' =>
array(
__('git') => 'git',
__('Subversion') => 'svn',
__('mercurial') => 'mercurial',
)
),
'widget' => 'Pluf_Form_Widget_SelectInput',
));
$this->fields['svn_remote_url'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Remote Subversion repository'),
'initial' => $this->conf->getVal('svn_remote_url', ''),
'widget_attrs' => array('size' => '30'),
));
$this->fields['svn_username'] = new Pluf_Form_Field_Varchar( $this->fields['svn_username'] = new Pluf_Form_Field_Varchar(
array('required' => false, array('required' => false,
'label' => __('Repository username'), 'label' => __('Repository username'),
@ -65,28 +49,6 @@ class IDF_Form_SourceConf extends Pluf_Form
'widget' => 'Pluf_Form_Widget_PasswordInput', 'widget' => 'Pluf_Form_Widget_PasswordInput',
)); ));
} }
public function clean_svn_remote_url()
{
$url = trim($this->cleaned_data['svn_remote_url']);
if (strlen($url) == 0) return $url;
// we accept only starting with http(s):// to avoid people
// trying to access the local filesystem.
if (!preg_match('#^(http|https)://#', $url)) {
throw new Pluf_Form_Invalid(__('Only a remote repository available throught http or https are allowed. For example "http://somewhere.com/svn/trunk".'));
}
return $url;
}
public function clean()
{
if ($this->cleaned_data['scm'] == 'git') {
foreach (array('svn_remote_url', 'svn_username', 'svn_password')
as $key) {
$this->cleaned_data[$key] = '';
}
}
return $this->cleaned_data;
} }
} }

View File

@ -71,6 +71,7 @@ function IDF_Middleware_ContextPreProcessor($request)
{ {
$c = array(); $c = array();
$c['request'] = $request; $c['request'] = $request;
$c['isAdmin'] = ($request->user->administrator or $request->user->staff);
if (isset($request->project)) { if (isset($request->project)) {
$c['project'] = $request->project; $c['project'] = $request->project;
$c['isOwner'] = $request->user->hasPerm('IDF.project-owner', $c['isOwner'] = $request->user->hasPerm('IDF.project-owner',

View File

@ -401,4 +401,69 @@ class IDF_Project extends Pluf_Model
return $this->_pconf; return $this->_pconf;
} }
/**
* Needs to be called when you update the memberships of a
* project.
*
* This will allow a plugin to, for example, update some access
* rights to a repository.
*/
public function membershipsUpdated()
{
/**
* [signal]
*
* IDF_Project::membershipsUpdated
*
* [sender]
*
* IDF_Project
*
* [description]
*
* This signal allows an application to update the some access
* rights to a repository when the project memberships is
* updated.
*
* [parameters]
*
* array('project' => $project)
*
*/
$params = array('project' => $this);
Pluf_Signal::send('IDF_Project::membershipsUpdated',
'IDF_Project', $params);
}
/**
* Needs to be called when you create a project.
*
* We cannot put it into the postSave call as the configuration of
* the project is not defined at that time.
*/
function created()
{
/**
* [signal]
*
* IDF_Project::created
*
* [sender]
*
* IDF_Project
*
* [description]
*
* This signal allows an application to perform special
* operations at the creation of a project.
*
* [parameters]
*
* array('project' => $project)
*
*/
$params = array('project' => $this);
Pluf_Signal::send('IDF_Project::created',
'IDF_Project', $params);
}
} }

145
src/IDF/Views/Admin.php Normal file
View File

@ -0,0 +1,145 @@
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
Pluf::loadFunction('Pluf_Shortcuts_RenderToResponse');
Pluf::loadFunction('Pluf_Shortcuts_GetObjectOr404');
Pluf::loadFunction('Pluf_Shortcuts_GetFormForModel');
/**
* Administration's views.
*/
class IDF_Views_Admin
{
/**
* Home page of the administration.
*
* It should provide an overview of the forge status.
*/
public $home_precond = array('Pluf_Precondition::staffRequired');
public function home($request, $match)
{
$title = __('Administer');
return Pluf_Shortcuts_RenderToResponse('idf/gadmin/home.html',
array(
'page_title' => $title,
),
$request);
}
/**
* Projects overview.
*
*/
public $projects_precond = array('Pluf_Precondition::staffRequired');
public function projects($request, $match)
{
$title = __('Projects');
$pag = new Pluf_Paginator(new IDF_Project());
$pag->class = 'recent-issues';
$pag->summary = __('This table shows the projects in the forge.');
$pag->action = 'IDF_Views_Admin::projects';
$pag->edit_action = array('IDF_Views_Admin::projectUpdate', 'id');
$pag->sort_order = array('shortname', 'ASC');
$list_display = array(
'shortname' => __('Short Name'),
'name' => __('Name'),
);
$pag->configure($list_display, array(),
array('shortname'));
$pag->items_per_page = 25;
$pag->no_results_text = __('No projects were found.');
$pag->setFromRequest($request);
return Pluf_Shortcuts_RenderToResponse('idf/gadmin/projects/index.html',
array(
'page_title' => $title,
'projects' => $pag,
),
$request);
}
/**
* Edition of a project.
*
* One cannot switch from one source backend to another.
*/
public $projectUpdate_precond = array('Pluf_Precondition::staffRequired');
public function projectUpdate($request, $match)
{
$project = Pluf_Shortcuts_GetObjectOr404('IDF_Project', $match[1]);
$title = sprintf(__('Update %s'), $project->name);
$params = array(
'project' => $project,
);
if ($request->method == 'POST') {
$form = new IDF_Form_Admin_ProjectUpdate($request->POST, $params);
if ($form->isValid()) {
$form->save();
$request->user->setMessage(__('The project has been updated.'));
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Admin::projectUpdate',
array($project->id));
return new Pluf_HTTP_Response_Redirect($url);
}
} else {
$form = new IDF_Form_Admin_ProjectUpdate(null, $params);
}
return Pluf_Shortcuts_RenderToResponse('idf/gadmin/projects/update.html',
array(
'page_title' => $title,
'project' => $project,
'form' => $form,
),
$request);
}
/**
* Creation of a project.
*
*/
public $projectCreate_precond = array('Pluf_Precondition::staffRequired');
public function projectCreate($request, $match)
{
$title = __('Create Project');
$extra = array('user' => $request->user);
if ($request->method == 'POST') {
$form = new IDF_Form_Admin_ProjectCreate($request->POST, $extra);
if ($form->isValid()) {
$project = $form->save();
$request->user->setMessage(__('The project has been created.'));
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Admin::projects');
return new Pluf_HTTP_Response_Redirect($url);
}
} else {
$form = new IDF_Form_Admin_ProjectCreate(null, $extra);
}
$base = Pluf::f('url_base').Pluf::f('idf_base').'/p/';
return Pluf_Shortcuts_RenderToResponse('idf/gadmin/projects/create.html',
array(
'page_title' => $title,
'form' => $form,
'base_url' => $base,
),
$request);
}
}

View File

@ -378,6 +378,11 @@ class IDF_Views_Project
{ {
$prj = $request->project; $prj = $request->project;
$title = sprintf(__('%s Source'), (string) $prj); $title = sprintf(__('%s Source'), (string) $prj);
$form = null;
$remote_svn = false;
if ($request->conf->getVal('scm') == 'svn' and
strlen($request->conf->getVal('svn_remote_url')) > 0) {
$remote_svn = true;
$extra = array( $extra = array(
'conf' => $request->conf, 'conf' => $request->conf,
); );
@ -394,9 +399,7 @@ class IDF_Views_Project
} }
} else { } else {
$params = array(); $params = array();
$keys = array('scm', 'svn_remote_url', foreach (array('svn_username', 'svn_password') as $key) {
'svn_username', 'svn_password');
foreach ($keys as $key) {
$_val = $request->conf->getVal($key, false); $_val = $request->conf->getVal($key, false);
if ($_val !== false) { if ($_val !== false) {
$params[$key] = $_val; $params[$key] = $_val;
@ -407,8 +410,19 @@ class IDF_Views_Project
} }
$form = new IDF_Form_SourceConf($params, $extra); $form = new IDF_Form_SourceConf($params, $extra);
} }
}
$scm = $request->conf->getVal('scm', 'git');
$options = array(
'git' => __('git'),
'svn' => __('Subversion'),
'mercurial' => __('mercurial'),
);
$repository_type = $options[$scm];
return Pluf_Shortcuts_RenderToResponse('idf/admin/source.html', return Pluf_Shortcuts_RenderToResponse('idf/admin/source.html',
array( array(
'remote_svn' => $remote_svn,
'repository_access' => $prj->getRemoteAccessUrl(),
'repository_type' => $repository_type,
'page_title' => $title, 'page_title' => $title,
'form' => $form, 'form' => $form,
), ),

View File

@ -374,4 +374,31 @@ $ctl[] = array('regex' => '#^/api/p/([\-\w]+)/issues/create/$#',
'model' => 'IDF_Views_Api', 'model' => 'IDF_Views_Api',
'method' => 'issueCreate'); 'method' => 'issueCreate');
// ---------- FORGE ADMIN --------------------------------
$ctl[] = array('regex' => '#^/admin/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Admin',
'method' => 'home');
$ctl[] = array('regex' => '#^/admin/projects/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Admin',
'method' => 'projects');
$ctl[] = array('regex' => '#^/admin/projects/(\d+)/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Admin',
'method' => 'projectUpdate');
$ctl[] = array('regex' => '#^/admin/projects/create/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Admin',
'method' => 'projectCreate');
return $ctl; return $ctl;

View File

@ -1,7 +1,7 @@
{extends "idf/admin/base.html"} {extends "idf/admin/base.html"}
{block docclass}yui-t1{assign $inSource = true}{/block} {block docclass}yui-t1{assign $inSource = true}{/block}
{block body} {block body}
{if $form.errors} {if $remote_svn and $form.errors}
<div class="px-message-error"> <div class="px-message-error">
<p>{trans 'The form contains some errors. Please correct them to update the source configuration.'}</p> <p>{trans 'The form contains some errors. Please correct them to update the source configuration.'}</p>
{if $form.get_top_errors} {if $form.get_top_errors}
@ -12,17 +12,15 @@
<form method="post" action="."> <form method="post" action=".">
<table class="form" summary=""> <table class="form" summary="">
<tr> <tr>
<th><strong>{$form.f.scm.labelTag}:</strong></th> <th>{trans 'Repository type:'}</th>
<td>{if $form.f.scm.errors}{$form.f.scm.fieldErrors}{/if} <td>{$repository_type}
{$form.f.scm|unsafe}
</td> </td>
</tr> </tr>
<tr> <tr>
<th>{$form.f.svn_remote_url.labelTag}:</th> <th>{trans 'Repository access:'}</th>
<td>{if $form.f.svn_remote_url.errors}{$form.f.svn_remote_url.fieldErrors}{/if} <td>{$repository_access}
{$form.f.svn_remote_url|unsafe}
</td> </td>
</tr> </tr>{if $remote_svn}
<tr> <tr>
<th>{$form.f.svn_username.labelTag}:</th> <th>{$form.f.svn_username.labelTag}:</th>
<td>{if $form.f.svn_username.errors}{$form.f.svn_username.fieldErrors}{/if} <td>{if $form.f.svn_username.errors}{$form.f.svn_username.fieldErrors}{/if}
@ -40,13 +38,12 @@
<td> <td>
<input type="submit" value="{trans 'Save Changes'}" name="submit" /> <input type="submit" value="{trans 'Save Changes'}" name="submit" />
</td> </td>
</tr> </tr>{/if}
</table> </table>
</form> </form>
{/block} {/block}
{block context} {block context}
<div class="issue-submit-info"> <div class="issue-submit-info">
<p><strong>{trans 'Instructions:'}</strong></p> <p>{blocktrans}You can find here the current repository configuration of your project.{/blocktrans}</p>
<p>{blocktrans}You can select the type of repository you want. In the case of subversion, you can use optionally a remote repository instead of the local one.{/blocktrans}</p>
</div> </div>
{/block} {/block}

View File

@ -35,10 +35,10 @@
<div id="hd"> <div id="hd">
<p class="top"><a href="#title" accesskey="2"></a> <p class="top"><a href="#title" accesskey="2"></a>
{if !$user.isAnonymous()}{aurl 'url', 'IDF_Views_User::myAccount'}{blocktrans}Welcome, <strong><a class="userw" href="{$url}">{$user}</a></strong>.{/blocktrans} <a href="{url 'IDF_Views::logout'}">{trans 'Sign Out'}</a>{else}<a href="{url 'IDF_Views::login'}">{trans 'Sign in or create your account'}</a>{/if} {if !$user.isAnonymous()}{aurl 'url', 'IDF_Views_User::myAccount'}{blocktrans}Welcome, <strong><a class="userw" href="{$url}">{$user}</a></strong>.{/blocktrans} <a href="{url 'IDF_Views::logout'}">{trans 'Sign Out'}</a>{else}<a href="{url 'IDF_Views::login'}">{trans 'Sign in or create your account'}</a>{/if}
{if $isAdmin}| <a href="{url 'IDF_Views_Admin::home'}">{trans 'Administer'}</a>{/if}
| <a href="{url 'IDF_Views::faq'}" title="{trans 'Help and accessibility features'}">{trans 'Help'}</a> | <a href="{url 'IDF_Views::faq'}" title="{trans 'Help and accessibility features'}">{trans 'Help'}</a>
</p> </p>
<h1 id="title" class="title">{block title}{$page_title}{/block}</h1> <h1 id="title" class="title">{block title}{$page_title}{/block}</h1>
</div> </div>
<div id="bd"> <div id="bd">
<div id="yui-main"> <div id="yui-main">

View File

@ -37,6 +37,7 @@
<p class="top"><a href="#title" accesskey="2"></a> <p class="top"><a href="#title" accesskey="2"></a>
{if !$user.isAnonymous()}{aurl 'url', 'IDF_Views_User::myAccount'}{blocktrans}Welcome, <strong><a class="userw" href="{$url}">{$user}</a></strong>.{/blocktrans} <a href="{url 'IDF_Views::logout'}">{trans 'Sign Out'}</a>{else}<a href="{url 'IDF_Views::login'}">{trans 'Sign in or create your account'}</a>{/if} {if !$user.isAnonymous()}{aurl 'url', 'IDF_Views_User::myAccount'}{blocktrans}Welcome, <strong><a class="userw" href="{$url}">{$user}</a></strong>.{/blocktrans} <a href="{url 'IDF_Views::logout'}">{trans 'Sign Out'}</a>{else}<a href="{url 'IDF_Views::login'}">{trans 'Sign in or create your account'}</a>{/if}
{if $project} | <a href="{url 'IDF_Views::index'}">{trans 'Project List'}</a>{/if} {if $project} | <a href="{url 'IDF_Views::index'}">{trans 'Project List'}</a>{/if}
{if $isAdmin}| <a href="{url 'IDF_Views_Admin::home'}">{trans 'Administer'}</a>{/if}
| <a href="{url 'IDF_Views::faq'}" title="{trans 'Help and accessibility features'}">{trans 'Help'}</a> | <a href="{url 'IDF_Views::faq'}" title="{trans 'Help and accessibility features'}">{trans 'Help'}</a>
</p> </p>
<div id="header"> <div id="header">

View File

@ -0,0 +1,67 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
{*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK *****
*}<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/yui.css'}" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/style.css'}" />
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="{media '/idf/css/ie6.css'}" />
<![endif]-->
{block extraheader}{/block}
<title>{block pagetitle}{$page_title|strip_tags}{/block}</title>
</head>
<body>
<div id="{block docid}doc3{/block}" class="{block docclass}yui-t3{/block}">
<div id="hd">
<p class="top"><a href="#title" accesskey="2"></a>
{aurl 'url', 'IDF_Views_User::myAccount'}{blocktrans}Welcome, <strong><a class="userw" href="{$url}">{$user}</a></strong>.{/blocktrans} <a href="{url 'IDF_Views::logout'}">{trans 'Sign Out'}</a>
| <a href="{url 'IDF_Views::index'}">{trans 'Project List'}</a>
| <a href="{url 'IDF_Views::faq'}" title="{trans 'Help and accessibility features'}">{trans 'Help'}</a>
</p>
<div id="header">
<div id="main-tabs">
<a accesskey="1" href="{url 'IDF_Views_Admin::home'}"{block tabhome}{/block}>{trans 'Administer'}</a>
<a href="{url 'IDF_Views_Admin::projects'}"{block tabprojects}{/block}>{trans 'Projects'}</a>
</div>
<div id="sub-tabs">{block subtabs}{/block}</div>
</div>
<h1 id="title" class="title">{block title}{$page_title}{/block}</h1>
</div>
<div id="bd">
<div id="yui-main">
<div class="yui-b">
<div class="yui-g">
{if $user and $user.id}{getmsgs $user}{/if}
<div class="content">{block body}{/block}</div>
</div>
</div>
</div>
<div class="yui-b context">{block context}{/block}</div>
</div>
<div id="ft">{block foot}{/block}</div>
</div>
<script type="text/javascript" src="{media '/idf/js/jquery-1.2.6.min.js'}"></script>
{include 'idf/js-hotkeys.html'}
{block javascript}{/block}
</body>
</html>

View File

@ -0,0 +1,14 @@
{extends "idf/gadmin/base.html"}
{block docclass}yui-t2{/block}
{block tabhome} class="active"{/block}
{block subtabs}
{trans 'Welcome'}
{/block}
{block body}
<p>{blocktrans}You have here access to the administration of the forge.{/blocktrans}</p>
{/block}
{block context}
{/block}
{block foot}<div id="branding">Powered by <a href="http://www.indefero.net" title="InDefero, bug tracking and more">InDefero</a>,<br />a <a href="http://www.ceondo.com">Céondo Ltd</a> initiative.</div>{/block}

View File

@ -0,0 +1,6 @@
{extends "idf/gadmin/base.html"}
{block tabprojects} class="active"{/block}
{block subtabs}
<a {if $inIndex}class="active" {/if}href="{url 'IDF_Views_Admin::projects'}">{trans 'Project List'}</a> |
<a {if $inCreate}class="active" {/if}href="{url 'IDF_Views_Admin::projectCreate'}">{trans 'Create Project'}</a>
{/block}

View File

@ -0,0 +1,130 @@
{extends "idf/gadmin/projects/base.html"}
{block docclass}yui-t3{assign $inCreate=true}{/block}
{block body}
{if $form.errors}
<div class="px-message-error">
<p>{trans 'The form contains some errors. Please correct them to create the project.'}</p>
{if $form.get_top_errors}
{$form.render_top_errors|unsafe}
{/if}
</div>
{/if}
<form method="post" action=".">
<table class="form" summary="">
<tr>
<th><strong>{$form.f.name.labelTag}:</strong></th>
<td>
{if $form.f.name.errors}{$form.f.name.fieldErrors}{/if}
{$form.f.name|unsafe}
</td>
</tr>
<tr>
<th><strong>{$form.f.shortname.labelTag}:</strong></th>
<td>
{if $form.f.shortname.errors}{$form.f.shortname.fieldErrors}{/if}
{$base_url}{$form.f.shortname|unsafe}/<br />
<span class="helptext">{$form.f.shortname.help_text}</span>
</td>
</tr>
<tr>
<th><strong>{$form.f.scm.labelTag}:</strong></th>
<td>{if $form.f.scm.errors}{$form.f.scm.fieldErrors}{/if}
{$form.f.scm|unsafe}
</td>
</tr>
<tr class="svn-form">
<th>{$form.f.svn_remote_url.labelTag}:</th>
<td>{if $form.f.svn_remote_url.errors}{$form.f.svn_remote_url.fieldErrors}{/if}
{$form.f.svn_remote_url|unsafe}
</td>
</tr>
<tr class="svn-form">
<th>{$form.f.svn_username.labelTag}:</th>
<td>{if $form.f.svn_username.errors}{$form.f.svn_username.fieldErrors}{/if}
{$form.f.svn_username|unsafe}
</td>
</tr>
<tr class="svn-form">
<th>{$form.f.svn_password.labelTag}:</th>
<td>{if $form.f.svn_password.errors}{$form.f.svn_password.fieldErrors}{/if}
{$form.f.svn_password|unsafe}
</td>
</tr>
<tr>
<th><strong>{$form.f.owners.labelTag}:</strong></th>
<td>
{if $form.f.owners.errors}{$form.f.owners.fieldErrors}{/if}
{$form.f.owners|unsafe}<br />
<span class="helptext">{trans 'Provide at least one owner for the project.'}</span>
</td>
</tr>
<tr>
<th>{$form.f.members.labelTag}:</th>
<td>
{if $form.f.members.errors}{$form.f.members.fieldErrors}{/if}
{$form.f.members|unsafe}
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
<input type="submit" value="{trans 'Create Project'}" name="submit" />
</td>
</tr>
</table>
</form>
{/block}
{block context}
<div class="issue-submit-info">
<p><strong>{trans 'Instructions:'}</strong></p>
<p>{blocktrans}You can select the type of repository you want. In the case of subversion, you can use optionally a remote repository instead of the local one.{/blocktrans}</p>
<p>{blocktrans}<strong>Once you have defined the repository type, you cannot change it</strong>.{/blocktrans}</p>
</div>
<div class="issue-submit-info">
{blocktrans}
<p>Specify each person by its login. Each person must have already registered with the given login.</p>
<p>Separate the logins with commas and/or new lines.</p>
{/blocktrans}
</div>
<div class="issue-submit-info">
{blocktrans}
<p><strong>Notes:</strong></p>
<p>A project owner may make any change to this project, including removing other project owners. You need to be carefull when you give owner rights.</p>
<p>A project member will not have access to the administration area but will have more options available in the use of the project.</p>
{/blocktrans}
</div>
{/block}
{block javascript}{literal}
<script type="text/javascript">
$(document).ready(function() {
// Hide if not svn
if ($("#id_scm option:selected").val() != "svn") {
$(".svn-form").hide();
}
$("#id_scm").change(function () {
if ($("#id_scm option:selected").val() == "svn") {
$(".svn-form").show();
} else {
$(".svn-form").hide();
}
});
});
</script>
{/literal}{/block}
{*
$("select").change(function () {
var str = "";
$("select option:selected").each(function () {
str += $(this).text() + " ";
});
$("div").text(str);
})
.trigger('change');
*}

View File

@ -0,0 +1,8 @@
{extends "idf/gadmin/projects/base.html"}
{block docclass}yui-t2{assign $inIndex=true}{/block}
{block body}
{$projects.render}
{/block}

View File

@ -0,0 +1,63 @@
{extends "idf/gadmin/projects/base.html"}
{block body}
{if $form.errors}
<div class="px-message-error">
<p>{trans 'The form contains some errors. Please correct them to update the project.'}</p>
{if $form.get_top_errors}
{$form.render_top_errors|unsafe}
{/if}
</div>
{/if}
<form method="post" action=".">
<table class="form" summary="">
<tr>
<th><strong>{$form.f.name.labelTag}:</strong></th>
<td>
{if $form.f.name.errors}{$form.f.name.fieldErrors}{/if}
{$form.f.name|unsafe}
</td>
</tr>
<tr>
<th><strong>{$form.f.owners.labelTag}:</strong></th>
<td>
{if $form.f.owners.errors}{$form.f.owners.fieldErrors}{/if}
{$form.f.owners|unsafe}<br />
<span class="helptext">{trans 'Provide at least one owner for the project.'}</span>
</td>
</tr>
<tr>
<th>{$form.f.members.labelTag}:</th>
<td>
{if $form.f.members.errors}{$form.f.members.fieldErrors}{/if}
{$form.f.members|unsafe}
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
<input type="submit" value="{trans 'Update Project'}" name="submit" />
| <a href="{url 'IDF_Views_Admin::projects'}">{trans 'Cancel'}</a>
</td>
</tr>
</table>
</form>
{/block}
{block context}
<div class="issue-submit-info">
{blocktrans}
<p><strong>Instructions:</strong></p>
<p>Specify each person by its login. Each person must have already registered with the given login.</p>
<p>Separate the logins with commas and/or new lines.</p>
{/blocktrans}
</div>
<div class="issue-submit-info">
{blocktrans}
<p><strong>Notes:</strong></p>
<p>A project owner may make any change to this project, including removing other project owners. You need to be carefull when you give owner rights.</p>
<p>A project member will not have access to the administration area but will have more options available in the use of the project.</p>
{/blocktrans}
</div>
{/block}

View File

@ -1,5 +1,7 @@
{extends "idf/base-simple.html"} {extends "idf/base-simple.html"}
{block docclass}yui-t1{/block} {block docclass}yui-t1{/block}
{block tabhome} class="active"{/block}
{block subtabs}<a href="{url 'IDF_Views::index'}" class="active">{trans 'Projects'}</a>{/block}
{block body} {block body}
{if $projects.count() == 0} {if $projects.count() == 0}
<p>{trans 'No projects managed with InDefero were found.'}</p> <p>{trans 'No projects managed with InDefero were found.'}</p>