Added description field to items
A description field has been added to items in the database, form fields have been added to both item creation and modification. Removed some French text that was still around.
This commit is contained in:
parent
55438e6661
commit
b6b5cd982e
8 changed files with 102 additions and 41 deletions
2
arse
2
arse
|
@ -1 +1 @@
|
||||||
Subproject commit b80ac7ee91df3c6aa935e38515907c6f3a0ab63c
|
Subproject commit f80d739f5d7b6241c154e2e38e0b1d5b6325142b
|
|
@ -33,6 +33,7 @@ CREATE TABLE items (
|
||||||
item_name VARCHAR(128) NOT NULL,
|
item_name VARCHAR(128) NOT NULL,
|
||||||
item_id_parent INT,
|
item_id_parent INT,
|
||||||
item_ordering INT NOT NULL,
|
item_ordering INT NOT NULL,
|
||||||
|
item_description TEXT ,
|
||||||
PRIMARY KEY(item_id)
|
PRIMARY KEY(item_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ $$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
|
||||||
-- Insert a item before another
|
-- Insert a item before another
|
||||||
CREATE OR REPLACE FUNCTION insert_item_before( i_name TEXT , i_before INT )
|
CREATE OR REPLACE FUNCTION insert_item_before( i_name TEXT , i_before INT , i_description TEXT )
|
||||||
RETURNS INT
|
RETURNS INT
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY DEFINER
|
SECURITY DEFINER
|
||||||
|
@ -68,9 +68,13 @@ BEGIN
|
||||||
RETURN 2;
|
RETURN 2;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
IF i_description = '' THEN
|
||||||
|
i_description := NULL;
|
||||||
|
END IF;
|
||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
INSERT INTO items ( item_name , item_id_parent , item_ordering )
|
INSERT INTO items ( item_name , item_id_parent , item_ordering , item_description )
|
||||||
VALUES ( i_name , i_parent , i_ordering );
|
VALUES ( i_name , i_parent , i_ordering , i_description );
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN unique_violation THEN
|
WHEN unique_violation THEN
|
||||||
RETURN 1;
|
RETURN 1;
|
||||||
|
@ -80,9 +84,12 @@ BEGIN
|
||||||
END;
|
END;
|
||||||
$insert_item_before$ LANGUAGE plpgsql;
|
$insert_item_before$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
REVOKE EXECUTE ON FUNCTION insert_item_before( TEXT , INT , TEXT ) FROM PUBLIC;
|
||||||
|
GRANT EXECUTE ON FUNCTION insert_item_before( TEXT , INT , TEXT ) TO :webapp_user;
|
||||||
|
|
||||||
|
|
||||||
-- Insert item as the last child of another
|
-- Insert item as the last child of another
|
||||||
CREATE OR REPLACE FUNCTION insert_item_under( i_name TEXT , i_parent INT )
|
CREATE OR REPLACE FUNCTION insert_item_under( i_name TEXT , i_parent INT , i_description TEXT )
|
||||||
RETURNS INT
|
RETURNS INT
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY DEFINER
|
SECURITY DEFINER
|
||||||
|
@ -92,10 +99,14 @@ DECLARE
|
||||||
BEGIN
|
BEGIN
|
||||||
PERFORM 1 FROM items FOR UPDATE;
|
PERFORM 1 FROM items FOR UPDATE;
|
||||||
|
|
||||||
|
IF i_description = '' THEN
|
||||||
|
i_description := NULL;
|
||||||
|
END IF;
|
||||||
|
|
||||||
SELECT INTO i_ordering max( item_ordering ) + 1 FROM items;
|
SELECT INTO i_ordering max( item_ordering ) + 1 FROM items;
|
||||||
BEGIN
|
BEGIN
|
||||||
INSERT INTO items ( item_name , item_id_parent , item_ordering )
|
INSERT INTO items ( item_name , item_id_parent , item_ordering , item_description )
|
||||||
VALUES ( i_name , i_parent , i_ordering );
|
VALUES ( i_name , i_parent , i_ordering , i_description );
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN unique_violation THEN
|
WHEN unique_violation THEN
|
||||||
RETURN 1;
|
RETURN 1;
|
||||||
|
@ -107,9 +118,12 @@ BEGIN
|
||||||
END;
|
END;
|
||||||
$insert_item_under$ LANGUAGE plpgsql;
|
$insert_item_under$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
REVOKE EXECUTE ON FUNCTION insert_item_under( TEXT , INT , TEXT ) FROM PUBLIC;
|
||||||
|
GRANT EXECUTE ON FUNCTION insert_item_under( TEXT , INT , TEXT ) TO :webapp_user;
|
||||||
|
|
||||||
|
|
||||||
-- Add a item as the last root element
|
-- Add a item as the last root element
|
||||||
CREATE OR REPLACE FUNCTION insert_item_last( i_name TEXT )
|
CREATE OR REPLACE FUNCTION insert_item_last( i_name TEXT , i_description TEXT )
|
||||||
RETURNS INT
|
RETURNS INT
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY DEFINER
|
SECURITY DEFINER
|
||||||
|
@ -123,9 +137,14 @@ BEGIN
|
||||||
IF i_ordering IS NULL THEN
|
IF i_ordering IS NULL THEN
|
||||||
i_ordering := 0;
|
i_ordering := 0;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
IF i_description = '' THEN
|
||||||
|
i_description := NULL;
|
||||||
|
END IF;
|
||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
INSERT INTO items ( item_name , item_ordering )
|
INSERT INTO items ( item_name , item_ordering , item_description )
|
||||||
VALUES ( i_name , i_ordering );
|
VALUES ( i_name , i_ordering , i_description );
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN unique_violation THEN
|
WHEN unique_violation THEN
|
||||||
RETURN 1;
|
RETURN 1;
|
||||||
|
@ -135,21 +154,34 @@ BEGIN
|
||||||
END;
|
END;
|
||||||
$insert_item_last$ LANGUAGE plpgsql;
|
$insert_item_last$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
REVOKE EXECUTE ON FUNCTION insert_item_last( TEXT , TEXT ) FROM PUBLIC;
|
||||||
|
GRANT EXECUTE ON FUNCTION insert_item_last( TEXT , TEXT ) TO :webapp_user;
|
||||||
|
|
||||||
-- Rename a item
|
-- Rename a item
|
||||||
CREATE OR REPLACE FUNCTION rename_item( i_id INT , i_name TEXT )
|
CREATE OR REPLACE FUNCTION update_item( i_id INT , i_name TEXT , i_description TEXT )
|
||||||
RETURNS INT
|
RETURNS INT
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY DEFINER
|
SECURITY DEFINER
|
||||||
AS $rename_item$
|
AS $update_item$
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE items SET item_name = $2 WHERE item_id = $1;
|
IF i_description = '' THEN
|
||||||
|
i_description := NULL;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
UPDATE items
|
||||||
|
SET item_name = i_name ,
|
||||||
|
item_description = i_description
|
||||||
|
WHERE item_id = i_id;
|
||||||
|
|
||||||
RETURN 0;
|
RETURN 0;
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN unique_violation THEN
|
WHEN unique_violation THEN
|
||||||
RETURN 1;
|
RETURN 1;
|
||||||
END
|
END
|
||||||
$rename_item$ LANGUAGE plpgsql;
|
$update_item$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
REVOKE EXECUTE ON FUNCTION update_item( INT , TEXT , TEXT ) FROM PUBLIC;
|
||||||
|
GRANT EXECUTE ON FUNCTION update_item( INT , TEXT , TEXT ) TO :webapp_user;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,26 +10,26 @@ class DAO_Items
|
||||||
private $activeTasksCounted = false;
|
private $activeTasksCounted = false;
|
||||||
|
|
||||||
|
|
||||||
public function createBefore( $name , $before )
|
public function createBefore( $name , $before , $description = '' )
|
||||||
{
|
{
|
||||||
$query = $this->query( 'SELECT insert_item_before( $1 , $2 ) AS error' );
|
$query = $this->query( 'SELECT insert_item_before( $1 , $2 , $3 ) AS error' );
|
||||||
$result = $query->execute( $name , $before );
|
$result = $query->execute( $name , $before , $description );
|
||||||
return $result[ 0 ]->error;
|
return $result[ 0 ]->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function createUnder( $name , $under )
|
public function createUnder( $name , $under , $description = '' )
|
||||||
{
|
{
|
||||||
$query = $this->query( 'SELECT insert_item_under( $1 , $2 ) AS error' );
|
$query = $this->query( 'SELECT insert_item_under( $1 , $2 , $3 ) AS error' );
|
||||||
$result = $query->execute( $name , $under );
|
$result = $query->execute( $name , $under , $description );
|
||||||
return $result[ 0 ]->error;
|
return $result[ 0 ]->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function createLast( $name )
|
public function createLast( $name , $description = '' )
|
||||||
{
|
{
|
||||||
$query = $this->query( 'SELECT insert_item_last( $1 ) AS error' );
|
$query = $this->query( 'SELECT insert_item_last( $1 , $2 ) AS error' );
|
||||||
$result = $query->execute( $name );
|
$result = $query->execute( $name , $description );
|
||||||
return $result[ 0 ]->error;
|
return $result[ 0 ]->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,12 +41,13 @@ class DAO_Items
|
||||||
return $this->loaded[ $identifier ];
|
return $this->loaded[ $identifier ];
|
||||||
}
|
}
|
||||||
|
|
||||||
$getNameQuery = $this->query( 'SELECT item_name FROM items WHERE item_id = $1' , true );
|
$getNameQuery = $this->query( 'SELECT item_name , item_description FROM items WHERE item_id = $1' , true );
|
||||||
$result = $getNameQuery->execute( $identifier );
|
$result = $getNameQuery->execute( $identifier );
|
||||||
if ( empty( $result ) ) {
|
if ( empty( $result ) ) {
|
||||||
$rObj = null;
|
$rObj = null;
|
||||||
} else {
|
} else {
|
||||||
$rObj = new Data_Item( $identifier , $result[ 0 ]->item_name );
|
$rObj = new Data_Item( $identifier , $result[ 0 ]->item_name );
|
||||||
|
$rObj->description = $result[ 0 ]->item_description;
|
||||||
}
|
}
|
||||||
$this->loaded[ $identifier ] = $rObj;
|
$this->loaded[ $identifier ] = $rObj;
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ class DAO_Items
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = $this->query(
|
$query = $this->query(
|
||||||
'SELECT p.item_id , p.item_name FROM items_tree pt '
|
'SELECT p.item_id , p.item_name , p.item_description FROM items_tree pt '
|
||||||
. 'INNER JOIN items p '
|
. 'INNER JOIN items p '
|
||||||
. 'ON p.item_id = pt.item_id_parent '
|
. 'ON p.item_id = pt.item_id_parent '
|
||||||
. 'WHERE pt.item_id_child = $1 AND pt.pt_depth > 0 '
|
. 'WHERE pt.item_id_child = $1 AND pt.pt_depth > 0 '
|
||||||
|
@ -74,6 +75,7 @@ class DAO_Items
|
||||||
$object = $this->loaded[ $entry->item_id ];
|
$object = $this->loaded[ $entry->item_id ];
|
||||||
} else {
|
} else {
|
||||||
$object = new Data_Item( $entry->item_id , $entry->item_name );
|
$object = new Data_Item( $entry->item_id , $entry->item_name );
|
||||||
|
$object->description = $entry->item_description;
|
||||||
$this->loaded[ $entry->item_id ] = $object;
|
$this->loaded[ $entry->item_id ] = $object;
|
||||||
}
|
}
|
||||||
$object->lineage = $stack;
|
$object->lineage = $stack;
|
||||||
|
@ -87,7 +89,7 @@ class DAO_Items
|
||||||
private function loadTree( )
|
private function loadTree( )
|
||||||
{
|
{
|
||||||
$query = $this->query(
|
$query = $this->query(
|
||||||
'SELECT p.item_id , p.item_name , MAX( t.pt_depth ) as depth '
|
'SELECT p.item_id , p.item_name , p.item_description , MAX( t.pt_depth ) AS depth '
|
||||||
. 'FROM items p '
|
. 'FROM items p '
|
||||||
. 'INNER JOIN items_tree t ON t.item_id_child = p.item_id '
|
. 'INNER JOIN items_tree t ON t.item_id_child = p.item_id '
|
||||||
. 'GROUP BY p.item_id, p.item_name , p.item_ordering '
|
. 'GROUP BY p.item_id, p.item_name , p.item_ordering '
|
||||||
|
@ -114,6 +116,7 @@ class DAO_Items
|
||||||
$object = $this->loaded[ $entry->item_id ];
|
$object = $this->loaded[ $entry->item_id ];
|
||||||
} else {
|
} else {
|
||||||
$object = new Data_Item( $entry->item_id , $entry->item_name );
|
$object = new Data_Item( $entry->item_id , $entry->item_name );
|
||||||
|
$object->description = $entry->item_description;
|
||||||
$this->loaded[ $entry->item_id ] = $object;
|
$this->loaded[ $entry->item_id ] = $object;
|
||||||
}
|
}
|
||||||
$object->children = array( );
|
$object->children = array( );
|
||||||
|
@ -172,7 +175,7 @@ class DAO_Items
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = $this->query(
|
$query = $this->query(
|
||||||
'SELECT p.item_id , p.item_name , COUNT(*) AS t_count '
|
'SELECT p.item_id , p.item_name , p.item_description , COUNT(*) AS t_count '
|
||||||
. 'FROM items p '
|
. 'FROM items p '
|
||||||
. 'INNER JOIN tasks t USING( item_id ) '
|
. 'INNER JOIN tasks t USING( item_id ) '
|
||||||
. 'LEFT OUTER JOIN completed_tasks c USING( task_id ) '
|
. 'LEFT OUTER JOIN completed_tasks c USING( task_id ) '
|
||||||
|
@ -185,6 +188,7 @@ class DAO_Items
|
||||||
$object = $this->loaded[ $entry->item_id ];
|
$object = $this->loaded[ $entry->item_id ];
|
||||||
} else {
|
} else {
|
||||||
$object = new Data_Item( $entry->item_id , $entry->item_name );
|
$object = new Data_Item( $entry->item_id , $entry->item_name );
|
||||||
|
$object->description = $entry->item_description;
|
||||||
$this->loaded[ $entry->item_id ] = $object;
|
$this->loaded[ $entry->item_id ] = $object;
|
||||||
}
|
}
|
||||||
$object->activeTasks = $entry->t_count;
|
$object->activeTasks = $entry->t_count;
|
||||||
|
@ -325,10 +329,10 @@ class DAO_Items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function rename( $item , $name )
|
public function modify( $item , $name , $description = '' )
|
||||||
{
|
{
|
||||||
$result = $this->query( 'SELECT rename_item( $1 , $2 ) AS error' )
|
$result = $this->query( 'SELECT update_item( $1 , $2 , $3 ) AS error' )
|
||||||
->execute( $item , $name );
|
->execute( $item , $name , $description );
|
||||||
return $result[ 0 ]->error;
|
return $result[ 0 ]->error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ class Data_Item
|
||||||
{
|
{
|
||||||
public $id;
|
public $id;
|
||||||
public $name;
|
public $name;
|
||||||
|
public $description;
|
||||||
public $hasParent;
|
public $hasParent;
|
||||||
public $parent;
|
public $parent;
|
||||||
public $children;
|
public $children;
|
||||||
|
|
|
@ -98,15 +98,16 @@ class Ctrl_AddItem
|
||||||
{
|
{
|
||||||
$name = $this->form->field( 'name' );
|
$name = $this->form->field( 'name' );
|
||||||
$before = $this->form->field( 'before' );
|
$before = $this->form->field( 'before' );
|
||||||
|
$description = $this->form->field( 'description' );
|
||||||
list( $after , $id ) = explode( ':' , $before->value( ) );
|
list( $after , $id ) = explode( ':' , $before->value( ) );
|
||||||
|
|
||||||
$items = Loader::DAO( 'items' );
|
$items = Loader::DAO( 'items' );
|
||||||
if ( $id === '' ) {
|
if ( $id === '' ) {
|
||||||
$error = $items->createLast( $name->value( ) );
|
$error = $items->createLast( $name->value( ) , $description->value( ) );
|
||||||
} elseif ( $after == 1 ) {
|
} elseif ( $after == 1 ) {
|
||||||
$error = $items->createUnder( $name->value( ) , $id );
|
$error = $items->createUnder( $name->value( ) , $id , $description->value( ) );
|
||||||
} else {
|
} else {
|
||||||
$error = $items->createBefore( $name->value( ) , $id );
|
$error = $items->createBefore( $name->value( ) , $id , $description->value( ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( $error ) {
|
switch ( $error ) {
|
||||||
|
@ -234,22 +235,23 @@ class Ctrl_EditItem
|
||||||
$item = $items->get( $id );
|
$item = $items->get( $id );
|
||||||
|
|
||||||
$name = $this->form->field( 'name' );
|
$name = $this->form->field( 'name' );
|
||||||
if ( $name->value( ) === $item->name ) {
|
$description = $this->form->field( 'description' )->value( );
|
||||||
|
if ( $name->value( ) === $item->name && $description == $item->description ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$error = $items->rename( $id , $name->value( ) );
|
$error = $items->modify( $id , $name->value( ) , $description );
|
||||||
switch ( $error ) {
|
switch ( $error ) {
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
$name->putError( 'Ce nom n\'est pas unique' );
|
$name->putError( 'This name is not unique.' );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$name->putError( 'Une erreur inconnue s\'est produite (' . $error . ')' );
|
$name->putError( 'An unknown error occurred (' . $error . ')' );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,12 @@ class Ctrl_AddItemForm
|
||||||
->setMandatory( false )
|
->setMandatory( false )
|
||||||
->setModifier( $locationField )
|
->setModifier( $locationField )
|
||||||
->setValidator( $locationField ) )
|
->setValidator( $locationField ) )
|
||||||
|
->addField( Loader::Create( 'Field' , 'description' , 'textarea' )
|
||||||
|
->setDescription( 'Description:' )
|
||||||
|
->setMandatory( false )
|
||||||
|
->setModifier( Loader::Create( 'Modifier_TrimString' ) )
|
||||||
|
->setValidator( Loader::Create( 'Validator_StringLength' ,
|
||||||
|
'This description' , 10 , null , true ) ) )
|
||||||
->addField( Loader::Create( 'Field' , 'from' , 'hidden' ) )
|
->addField( Loader::Create( 'Field' , 'from' , 'hidden' ) )
|
||||||
->addController( Loader::Ctrl( 'add_item' ) );
|
->addController( Loader::Ctrl( 'add_item' ) );
|
||||||
|
|
||||||
|
@ -269,6 +275,13 @@ class Ctrl_EditItemForm
|
||||||
->setModifier( Loader::Create( 'Modifier_TrimString' ) )
|
->setModifier( Loader::Create( 'Modifier_TrimString' ) )
|
||||||
->setValidator( Loader::Create( 'Validator_StringLength' , 'This name' , 2 , 128 ) )
|
->setValidator( Loader::Create( 'Validator_StringLength' , 'This name' , 2 , 128 ) )
|
||||||
->setDefaultValue( $item->name ) )
|
->setDefaultValue( $item->name ) )
|
||||||
|
->addField( Loader::Create( 'Field' , 'description' , 'textarea' )
|
||||||
|
->setDescription( 'Description:' )
|
||||||
|
->setMandatory( false )
|
||||||
|
->setModifier( Loader::Create( 'Modifier_TrimString' ) )
|
||||||
|
->setValidator( Loader::Create( 'Validator_StringLength' ,
|
||||||
|
'This description' , 10 , null , true ) )
|
||||||
|
->setDefaultValue( $item->description ) )
|
||||||
->addField( Loader::Create( 'Field' , 'id' , 'hidden' )
|
->addField( Loader::Create( 'Field' , 'id' , 'hidden' )
|
||||||
->setDefaultValue( $item->id ) )
|
->setDefaultValue( $item->id ) )
|
||||||
->addController( Loader::Ctrl( 'edit_item' ) )
|
->addController( Loader::Ctrl( 'edit_item' ) )
|
||||||
|
|
|
@ -87,10 +87,18 @@ class View_ItemDetails
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return HTML::make( 'dl' )
|
$details = HTML::make( 'dl' )
|
||||||
->appendElement( HTML::make( 'dt' )->appendText( 'Path:' ) )
|
->appendElement( HTML::make( 'dt' )->appendText( 'Path:' ) )
|
||||||
->appendElement( HTML::make( 'dd' )
|
->appendElement( HTML::make( 'dd' )
|
||||||
->setAttribute( 'style' , 'font-size: 10pt' )
|
->setAttribute( 'style' , 'font-size: 10pt' )
|
||||||
->append( $contents ) );
|
->append( $contents ) );
|
||||||
|
|
||||||
|
if ( $this->item->description !== null ) {
|
||||||
|
$details->appendElement( HTML::make( 'dt' )->appendText( 'Description:' ) )
|
||||||
|
->appendElement( HTML::make( 'dd' )
|
||||||
|
->appendText( $this->item->description ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $details;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue