Index: openacs-4/contrib/packages/simulation/lib/sim-template-tasks.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/simulation/lib/Attic/sim-template-tasks.tcl,v diff -u -r1.11 -r1.12 --- openacs-4/contrib/packages/simulation/lib/sim-template-tasks.tcl 11 Dec 2003 13:21:52 -0000 1.11 +++ openacs-4/contrib/packages/simulation/lib/sim-template-tasks.tcl 15 Dec 2003 15:28:20 -0000 1.12 @@ -183,12 +183,11 @@ wa.sort_order, wa.always_enabled_p, wfa.new_state - from workflow_actions wa, - workflow_fsm_actions wfa, - sim_tasks st + from workflow_actions wa left outer join + sim_tasks st on (st.task_id = wa.action_id), + workflow_fsm_actions wfa where wa.workflow_id = :workflow_id - and wfa.action_id = wa.action_id - and st.task_id = wa.action_id + and wfa.action_id = wa.action_id order by wa.sort_order " { set edit_url [export_vars -base "[apm_package_url_from_id $package_id]simbuild/task-edit" { action_id }] Index: openacs-4/contrib/packages/simulation/sql/postgresql/simulation-tables-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/simulation/sql/postgresql/Attic/simulation-tables-create.sql,v diff -u -r1.10 -r1.11 --- openacs-4/contrib/packages/simulation/sql/postgresql/simulation-tables-create.sql 9 Dec 2003 17:23:09 -0000 1.10 +++ openacs-4/contrib/packages/simulation/sql/postgresql/simulation-tables-create.sql 15 Dec 2003 15:28:20 -0000 1.11 @@ -62,7 +62,8 @@ primary key, recipient integer constraint sim_tasks_recipient_fk references workflow_roles - on delete cascade + on delete cascade, + attachment_num integer default 0 ); comment on table sim_tasks is 'A 1-1 extension of workflow_actions. Each record is a task that a role must perform, possibly upon another role.'; @@ -74,10 +75,10 @@ object_id integer constraint stom_object_fk references acs_objects on delete cascade, - order_n integer, relation_tag varchar(100), + order_n integer, constraint stom_pk - primary key (task_id, object_id, relation_tag) + primary key (task_id, object_id, relation_tag, order_n) ); comment on table sim_task_object_map is 'A mapping table to show which tasks use which props. Each record is one prop for one task.'; Index: openacs-4/contrib/packages/simulation/tcl/action-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/simulation/tcl/Attic/action-procs.tcl,v diff -u -r1.4 -r1.5 --- openacs-4/contrib/packages/simulation/tcl/action-procs.tcl 10 Dec 2003 16:06:46 -0000 1.4 +++ openacs-4/contrib/packages/simulation/tcl/action-procs.tcl 15 Dec 2003 15:28:20 -0000 1.5 @@ -8,33 +8,60 @@ namespace eval simulation::action {} + +# TODO: add simulation::action::new + ad_proc -public simulation::action::edit { {-action_id:required} {-workflow_id {}} {-array:required} {-internal:boolean} } { Edit an action. Mostly a wrapper for FSM, plus some simulation-specific stuff. + + Available attributes: recipient (role_id), recipient_role (role short_name), attachment_num } { upvar 1 $array org_row + if { ![array exists org_row] } { + error "Array $array does not exist or is not an array" + } array set row [array get org_row] - + + set set_clauses [list] + + # Handle attributes in sim_tasks table + if { [info exists row(recipient_role)] } { + if { [empty_string_p $row(recipient_role)] } { + set row(recipient) [db_null] + } else { + # Get role_id by short_name + set row(recipient) [workflow::role::get_id \ + -workflow_id $workflow_id \ + -short_name $row(recipient_role)] + } + unset row(recipient_role) + } + + foreach attr { + recipient attachment_num + } { + if { [info exists row($attr)] } { + set varname attr_$attr + # Convert the Tcl value to something we can use in the query + set $varname $row($attr) + # Add the column to the SET clause + lappend set_clauses "$attr = :$varname" + unset row($attr) + } + } + db_transaction { - if { [info exists row(recipient_role)] } { - if { ![empty_string_p $row(recipient_role)] } { - set recipient_role_id [workflow::role::get_id \ - -workflow_id $workflow_id \ - -short_name $row(recipient_role)] - } else { - set recipient_role_id [db_null] - } - db_dml edit_sim_role { + if { [llength $set_clauses] > 0 } { + db_dml edit_sim_role " update sim_tasks - set recipient = :recipient_role_id + set [join $set_clauses ", "] where task_id = :action_id - } - - unset row(recipient_role) + " } workflow::action::fsm::edit \ Index: openacs-4/contrib/packages/simulation/tcl/object-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/simulation/tcl/Attic/object-procs.tcl,v diff -u -r1.6 -r1.7 --- openacs-4/contrib/packages/simulation/tcl/object-procs.tcl 28 Nov 2003 16:55:52 -0000 1.6 +++ openacs-4/contrib/packages/simulation/tcl/object-procs.tcl 15 Dec 2003 15:28:20 -0000 1.7 @@ -49,6 +49,56 @@ return "${package_url}object-content/${name}" } + +ad_proc simulation::object::get_object_type_options { + -object_type:required + {-null_label "--None--"} +} { + Get options for a select/radio widget of available objects of a given object_type. + Deals with content_types as a special-case where it'll provide a drop-down of items, + not revisions. +} { + # We need to know if this is a CR content_type, because in that case we + # want to reference the item corresponding to the revision, not the revision + set content_type_p [db_string content_type_p { + select count(*) + from acs_object_type_supertype_map + where object_type = :object_type + and ancestor_type = 'content_revision' + }] + + # LARS TODO: We need to be able to scope this to a package, + # possibly filter by other things, control the sort order, + # we need to be able to control what the label looks like (e.g. include email for users) + # and it needs to be intelligent about scaling issues + if { $content_type_p } { + set options [db_list_of_lists select_options { + select r.title, + i.item_id + from cr_items i, cr_revisions r + where i.content_type = :object_type + and r.revision_id = i.live_revision + order by r.title + }] + } else { + set options [db_list_of_lists select_options { + select acs_object__name(object_id), + object_id + from acs_objects + where object_type = :object_type + order by acs_object__name(object_id) + }] + } + + if { ![empty_string_p $null_label] } { + set options [concat [list [list $null_label {}]] $options] + } + + return $options +} + + + ############################### # # simulation::object::xml namespace Index: openacs-4/contrib/packages/simulation/www/citybuild/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/simulation/www/citybuild/Attic/index.adp,v diff -u -r1.3 -r1.4 --- openacs-4/contrib/packages/simulation/www/citybuild/index.adp 11 Dec 2003 13:21:52 -0000 1.3 +++ openacs-4/contrib/packages/simulation/www/citybuild/index.adp 15 Dec 2003 15:28:21 -0000 1.4 @@ -3,6 +3,7 @@ @context;noquote@ +

Map XML

Index: openacs-4/contrib/packages/simulation/www/citybuild/object-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/simulation/www/citybuild/Attic/object-edit.tcl,v diff -u -r1.7 -r1.8 --- openacs-4/contrib/packages/simulation/www/citybuild/object-edit.tcl 12 Dec 2003 12:05:10 -0000 1.7 +++ openacs-4/contrib/packages/simulation/www/citybuild/object-edit.tcl 15 Dec 2003 15:28:21 -0000 1.8 @@ -262,54 +262,7 @@ return $result } -ad_proc get_object_type_options { - -object_type:required - {-null_label "--None--"} -} { - Get options for a select/radio widget of available objects of a given object_type. - Deals with content_types as a special-case where it'll provide a drop-down of items, - not revisions. -} { - # We need to know if this is a CR content_type, because in that case we - # want to reference the item corresponding to the revision, not the revision - set content_type_p [db_string content_type_p { - select count(*) - from acs_object_type_supertype_map - where object_type = :object_type - and ancestor_type = 'content_revision' - }] - # LARS TODO: We need to be able to scope this to a package, - # possibly filter by other things, control the sort order, - # we need to be able to control what the label looks like (e.g. include email for users) - # and it needs to be intelligent about scaling issues - if { $content_type_p } { - set options [db_list_of_lists select_options { - select r.title, - i.item_id - from cr_items i, cr_revisions r - where i.content_type = :object_type - and r.revision_id = i.live_revision - order by r.title - }] - } else { - set options [db_list_of_lists select_options { - select acs_object__name(object_id), - object_id - from acs_objects - where object_type = :object_type - order by acs_object__name(object_id) - }] - } - - if { ![empty_string_p $null_label] } { - set options [concat [list [list $null_label {}]] $options] - } - - return $options -} - - #--------------------------------------------------------------------- # Content edit/upload method # @@ -455,7 +408,7 @@ set elm_ref_type [get_metadata_property -content_type $content_type -entry_type attributes -entry $attribute_name -property references] if { ![empty_string_p $elm_ref_type] } { set elm_widget select - set options [get_object_type_options -object_type $elm_ref_type] + set options [simulation::object::get_object_type_options -object_type $elm_ref_type] lappend extra { options \$options } } @@ -485,7 +438,7 @@ } { set label [get_metadata_property -content_type $content_type -entry_type relations -entry $relation_tag -property label] set section [get_metadata_property -content_type $content_type -entry_type relations -entry $relation_tag -property section] - set options [get_object_type_options -object_type $target_type] + set options [simulation::object::get_object_type_options -object_type $target_type] # LARS HACK: This only works for a specific hard-coded max_n # We need to generalize so it can be dynamic @@ -693,14 +646,14 @@ -revision_id $revision_id \ -status "live" - # LARS: The way we do this update is not very pretty: Delete all relations and re-add the new ones + # TODO: The way we do this update is not very pretty: Delete all relations and re-add the new ones db_dml delete_all_relations { delete from cr_item_rels where item_id = :item_id } foreach elm $rel_elements { - # LARS HACK ALERT: This isn't a particularly pretty way to find all the related objects in the form + # TODO: LARS HACK ALERT: This isn't a particularly pretty way to find all the related objects in the form regexp {__(.+)__} $elm match relation_tag regexp {__.+__(.+)$} $elm match order_n set related_object_id [set $elm] Index: openacs-4/contrib/packages/simulation/www/simbuild/task-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/simulation/www/simbuild/Attic/task-edit.tcl,v diff -u -r1.8 -r1.9 --- openacs-4/contrib/packages/simulation/www/simbuild/task-edit.tcl 10 Dec 2003 16:06:46 -0000 1.8 +++ openacs-4/contrib/packages/simulation/www/simbuild/task-edit.tcl 15 Dec 2003 15:28:21 -0000 1.9 @@ -106,18 +106,24 @@ {label "New state"} {options $state_options} } + {attachment_num:integer(text) + {label "Number of attachments"} + {help_text "These are placeholders that are matched to props by the case author during SimInst"} + {html {size 2}} + } } -edit_request { set workflow_id $task_array(workflow_id) permission::require_write_permission -object_id $workflow_id set pretty_name $task_array(pretty_name) set description [template::util::richtext::create $task_array(description) $task_array(description_mime_type)] set new_state_id $task_array(new_state_id) - set recipient_role_id [db_string select_recipient { - select recipient + db_1row select_recipient { + select recipient as recipient_role_id, attachment_num from sim_tasks where task_id = :action_id - }] + } + if { ![empty_string_p $recipient_role_id] } { set recipient_role [workflow::role::get_element -role_id $recipient_role_id -element short_name] } else { @@ -144,11 +150,7 @@ permission::require_write_permission -object_id $workflow_id # create the task - # TODO IMPORTANT: - # Set short_name right -- or leave blank and have the workflow API construct a short_name - db_transaction { - set action_id [workflow::action::fsm::new \ -workflow_id $workflow_id \ -pretty_name $pretty_name \ @@ -159,16 +161,19 @@ -assigned_state_ids $assigned_state_ids \ -new_state_id $new_state_id] - # TODO: enabled_states, assigned_states - # TODO - put this stuff into simulation api and change previous call # and then add extra data for simulation # because workflow::action::fsm::new wants role.short_name instead of # role_id, we stay consistent for recipient_role - db_dml set_role_recipient { - insert into sim_tasks - values (:action_id, :recipient_role_id) - } + + array unset row + set row(recipient_role) $recipient_role + set row(attachment_num) $attachment_num + + simulation::action::edit \ + -action_id $action_id \ + -workflow_id $workflow_id \ + -array row } } -edit_data { # We use task_array(workflow_id) here, which is gotten from the DB, and not @@ -181,7 +186,7 @@ # TODO: enabled_states, assigned_states array unset row - foreach col { pretty_name assigned_role recipient_role description description_mime_type enabled_state_ids assigned_state_ids } { + foreach col { pretty_name assigned_role recipient_role description description_mime_type enabled_state_ids assigned_state_ids attachment_num } { set row($col) [set $col] } set row(short_name) {} Index: openacs-4/contrib/packages/simulation/www/siminst/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/simulation/www/siminst/Attic/index.tcl,v diff -u -r1.15 -r1.16 --- openacs-4/contrib/packages/simulation/www/siminst/index.tcl 15 Dec 2003 13:40:22 -0000 1.15 +++ openacs-4/contrib/packages/simulation/www/siminst/index.tcl 15 Dec 2003 15:28:21 -0000 1.16 @@ -37,7 +37,7 @@ label "Tasks" link_url_col sim_tasks_url display_template { - @dev_sims.tasks@ , with @dev_sims.prop_empty_count@ incomplete props + @dev_sims.tasks@, with @dev_sims.prop_empty_count@ incomplete props } } delete { @@ -71,7 +71,7 @@ set sim_in_dev_filter_sql "and ao.creation_user = :user_id" } -db_multirow -extend { cast_url map_roles_url map_props_url sim_tasks_url delete_url } dev_sims select_dev_sims " +db_multirow -extend { cast_url map_roles_url map_props_url sim_tasks_url delete_url prop_empty_count } dev_sims select_dev_sims " select w.workflow_id, w.pretty_name, (select count(*) @@ -85,17 +85,16 @@ where sr.role_id = wr.role_id and wr.workflow_id = w.workflow_id and character_id is null) as role_empty_count, - (select count(*) - from sim_task_object_map stom, + (select sum(coalesce(attachment_num,0)) + from sim_tasks st, workflow_actions wa - where stom.task_id = wa.action_id + where st.task_id = wa.action_id and wa.workflow_id = w.workflow_id) as prop_count, (select count(*) from sim_task_object_map stom, workflow_actions wa where stom.task_id = wa.action_id - and wa.workflow_id = w.workflow_id - and stom.object_id is null) as prop_empty_count, + and wa.workflow_id = w.workflow_id) as prop_not_empty_count, (select count(*) from workflow_actions wa where wa.workflow_id = w.workflow_id) as tasks @@ -108,6 +107,7 @@ and ss.sim_type = 'dev_sim' $sim_in_dev_filter_sql " { + set prop_empty_count [expr $prop_count - $prop_not_empty_count] if { [simulation::template::ready_for_casting_p -role_empty_count $role_empty_count -prop_empty_count $prop_empty_count] } { set cast_url [export_vars -base "${base_url}siminst/simulation-casting" { workflow_id }] } else { Index: openacs-4/contrib/packages/simulation/www/siminst/map-tasks.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/simulation/www/siminst/Attic/map-tasks.adp,v diff -u -r1.3 -r1.4 --- openacs-4/contrib/packages/simulation/www/siminst/map-tasks.adp 11 Dec 2003 13:21:53 -0000 1.3 +++ openacs-4/contrib/packages/simulation/www/siminst/map-tasks.adp 15 Dec 2003 15:28:21 -0000 1.4 @@ -2,8 +2,5 @@ @page_title;noquote@ @context;noquote@ -TODO: show a list of tasks with unmapped sim prop or sim location slots. Set description on for each task. + -

- Complete mapping -

Index: openacs-4/contrib/packages/simulation/www/siminst/map-tasks.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/simulation/www/siminst/Attic/map-tasks.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/contrib/packages/simulation/www/siminst/map-tasks.tcl 28 Nov 2003 16:55:52 -0000 1.2 +++ openacs-4/contrib/packages/simulation/www/siminst/map-tasks.tcl 15 Dec 2003 15:28:21 -0000 1.3 @@ -6,6 +6,45 @@ workflow_id:integer } -set page_title "Map to Tasks" +workflow::get -workflow_id $workflow_id -array workflow_array +set page_title "Tasks for $workflow_array(pretty_name)" set context [list [list "." "SimInst" ] $page_title] +db_multirow -extend { description_html } tasks select_taks { + select a.action_id, + a.short_name, + a.pretty_name, + a.description, + a.description_mime_type, + st.attachment_num, + (select count(*) + from sim_task_object_map stom + where stom.task_id = st.task_id) as prop_not_empty_count + from workflow_actions a, + sim_tasks st + where a.workflow_id = :workflow_id + and st.task_id = a.action_id +} { + set description_html [ad_html_text_convert -maxlen 100 -from $description_mime_type -- $description] +} + +# TODO: Honor description_mime_type, fancy truncate + +template::list::create \ + -name "tasks" \ + -elements { + pretty_name { + label "Name" + link_url_eval {[export_vars -base task-edit { action_id }]} + } + description { + label "Description" + display_template {@tasks.description_html;noquote@} + } + attachment_num { + label "Number of attachments" + } + prop_not_empty_count { + label "Number of attachments populated" + } + } Index: openacs-4/contrib/packages/simulation/www/siminst/task-edit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/simulation/www/siminst/Attic/task-edit.adp,v diff -u -r1.1 -r1.2 --- openacs-4/contrib/packages/simulation/www/siminst/task-edit.adp 12 Dec 2003 15:40:32 -0000 1.1 +++ openacs-4/contrib/packages/simulation/www/siminst/task-edit.adp 15 Dec 2003 15:28:21 -0000 1.2 @@ -1,10 +1,14 @@ @page_title;noquote@ @context;noquote@ - template.pretty_name + task.pretty_name -TODO -show task description body, list of related props (similar to -object-edit and images). end-to-end requires that props can be -associated but not that they can be embedded in the -description body. +

+ TODO + show task description body, list of related props (similar to + object-edit and images). end-to-end requires that props can be + associated but not that they can be embedded in the + description body. +

+ + Index: openacs-4/contrib/packages/simulation/www/siminst/task-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/simulation/www/siminst/Attic/task-edit.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/contrib/packages/simulation/www/siminst/task-edit.tcl 12 Dec 2003 15:40:32 -0000 1.1 +++ openacs-4/contrib/packages/simulation/www/siminst/task-edit.tcl 15 Dec 2003 15:28:21 -0000 1.2 @@ -3,21 +3,141 @@ @author Joel Aufrecht } { - workflow_id:integer + action_id:integer } set user_id [auth::require_login] -set page_title "Edit Task" -set context [list [list "." "SimInst"] $page_title] -set old_name [workflow::get_element -workflow_id $workflow_id -element pretty_name] -acs_user::get -user_id $user_id -array user_array +workflow::action::fsm::get -action_id $action_id -array task_array -###################################################################### -# -# tasks -# -# a list showing description for all tasks in a sim -# -###################################################################### +# TODO: Move into simulation::action::get API +db_1row select_recipient { + select recipient as recipient_role_id, attachment_num + from sim_tasks + where task_id = :action_id +} -column_array task_array2 +array set task_array [array get task_array2] +set workflow_id $task_array(workflow_id) +permission::require_write_permission -object_id $workflow_id + +workflow::get -workflow_id $workflow_id -array workflow_array +set role_options [workflow::role::get_options -workflow_id $workflow_id] + +set page_title "Edit $task_array(pretty_name)" +set return_url [export_vars -base map-tasks { workflow_id }] +set context [list [list "." "SimInst"] [list $return_url "Tasks for $workflow_array(pretty_name)"] $page_title] + + + +ad_form -name task -export { workflow_id } -edit_buttons [list [list [ad_decode [ad_form_new_p -key action_id] 1 [_ acs-kernel.common_add] [_ acs-kernel.common_edit]] ok]] -form { + {action_id:key} + {pretty_name:text + {label "Task Name"} + {html {size 20}} + {mode display} + } + {assigned_role:text(select),optional + {label "Assigned To"} + {options $role_options} + {mode display} + } + {recipient_role:text(select),optional + {label "Recipient"} + {options $role_options} + {mode display} + } + {description:richtext,optional + {label "Task Description"} + {html {cols 60 rows 8}} + } + {attachment_num:integer(text) + {label "Number of attachments"} + {help_text "These are placeholders that are matched to props by the case author during SimInst"} + {html {size 2}} + {mode display} + } +} + +set prop_options [simulation::object::get_object_type_options -object_type "sim_prop"] + +for { set i 1 } { $i <= $task_array(attachment_num) } { incr i } { + ad_form -extend -name task -form [list [list attachment_$i:integer(select),optional [list label "Attachment $i"] [list options \$prop_options]]] + +} + + +ad_form -extend -name task -edit_request { + set pretty_name $task_array(pretty_name) + set description [template::util::richtext::create $task_array(description) $task_array(description_mime_type)] + set new_state_id $task_array(new_state_id) + set attachment_num $task_array(attachment_num) + + if { ![empty_string_p $task_array(recipient_role_id)] } { + set recipient_role [workflow::role::get_element -role_id $task_array(recipient_role_id) -element short_name] + } else { + set recipient_role {} + } + set assigned_role $task_array(assigned_role) + + db_foreach attachments { + select object_id, + order_n + from sim_task_object_map + where task_id = :action_id + and relation_tag = 'attachment' + } { + if { $order_n >= 1 && $order_n <= $task_array(attachment_num) } { + set attachment_$order_n $object_id + } + } +} -on_submit { + + set description_mime_type [template::util::richtext::get_property format $description] + set description [template::util::richtext::get_property contents $description] + + if { ![empty_string_p $recipient_role] } { + set recipient_role_id [workflow::role::get_id -workflow_id $workflow_id -short_name $recipient_role] + } else { + set recipient_role_id [db_null] + } +} -edit_data { + # We use task_array(workflow_id) here, which is gotten from the DB, and not + # workflow_id, which is gotten from the form, because the workflow_id from the form + # could be spoofed + permission::require_write_permission -object_id $task_array(workflow_id) + + array unset row + foreach col { description description_mime_type } { + set row($col) [set $col] + } + + db_transaction { + simulation::action::edit \ + -action_id $action_id \ + -workflow_id $task_array(workflow_id) \ + -array row + + # TODO: The way we do this update is not very pretty: Delete all relations and re-add the new ones + db_dml delete_all_relations { + delete from sim_task_object_map + where task_id = :action_id + } + + for { set i 1 } { $i <= $task_array(attachment_num) } { incr i } { + set elm "attachment_$i" + set related_object_id [set $elm] + + if { ![empty_string_p $related_object_id] } { + db_dml insert_rel { + insert into sim_task_object_map (task_id, object_id, order_n, relation_tag) + values (:action_id, :related_object_id, :i, 'attachment') + } + } + } + + } +} -after_submit { + ad_returnredirect $return_url + ad_script_abort +} Index: openacs-4/packages/simulation/lib/sim-template-tasks.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/simulation/lib/sim-template-tasks.tcl,v diff -u -r1.11 -r1.12 --- openacs-4/packages/simulation/lib/sim-template-tasks.tcl 11 Dec 2003 13:21:52 -0000 1.11 +++ openacs-4/packages/simulation/lib/sim-template-tasks.tcl 15 Dec 2003 15:28:20 -0000 1.12 @@ -183,12 +183,11 @@ wa.sort_order, wa.always_enabled_p, wfa.new_state - from workflow_actions wa, - workflow_fsm_actions wfa, - sim_tasks st + from workflow_actions wa left outer join + sim_tasks st on (st.task_id = wa.action_id), + workflow_fsm_actions wfa where wa.workflow_id = :workflow_id - and wfa.action_id = wa.action_id - and st.task_id = wa.action_id + and wfa.action_id = wa.action_id order by wa.sort_order " { set edit_url [export_vars -base "[apm_package_url_from_id $package_id]simbuild/task-edit" { action_id }] Index: openacs-4/packages/simulation/sql/postgresql/simulation-tables-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/simulation/sql/postgresql/simulation-tables-create.sql,v diff -u -r1.10 -r1.11 --- openacs-4/packages/simulation/sql/postgresql/simulation-tables-create.sql 9 Dec 2003 17:23:09 -0000 1.10 +++ openacs-4/packages/simulation/sql/postgresql/simulation-tables-create.sql 15 Dec 2003 15:28:20 -0000 1.11 @@ -62,7 +62,8 @@ primary key, recipient integer constraint sim_tasks_recipient_fk references workflow_roles - on delete cascade + on delete cascade, + attachment_num integer default 0 ); comment on table sim_tasks is 'A 1-1 extension of workflow_actions. Each record is a task that a role must perform, possibly upon another role.'; @@ -74,10 +75,10 @@ object_id integer constraint stom_object_fk references acs_objects on delete cascade, - order_n integer, relation_tag varchar(100), + order_n integer, constraint stom_pk - primary key (task_id, object_id, relation_tag) + primary key (task_id, object_id, relation_tag, order_n) ); comment on table sim_task_object_map is 'A mapping table to show which tasks use which props. Each record is one prop for one task.'; Index: openacs-4/packages/simulation/tcl/action-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/simulation/tcl/Attic/action-procs.tcl,v diff -u -r1.4 -r1.5 --- openacs-4/packages/simulation/tcl/action-procs.tcl 10 Dec 2003 16:06:46 -0000 1.4 +++ openacs-4/packages/simulation/tcl/action-procs.tcl 15 Dec 2003 15:28:20 -0000 1.5 @@ -8,33 +8,60 @@ namespace eval simulation::action {} + +# TODO: add simulation::action::new + ad_proc -public simulation::action::edit { {-action_id:required} {-workflow_id {}} {-array:required} {-internal:boolean} } { Edit an action. Mostly a wrapper for FSM, plus some simulation-specific stuff. + + Available attributes: recipient (role_id), recipient_role (role short_name), attachment_num } { upvar 1 $array org_row + if { ![array exists org_row] } { + error "Array $array does not exist or is not an array" + } array set row [array get org_row] - + + set set_clauses [list] + + # Handle attributes in sim_tasks table + if { [info exists row(recipient_role)] } { + if { [empty_string_p $row(recipient_role)] } { + set row(recipient) [db_null] + } else { + # Get role_id by short_name + set row(recipient) [workflow::role::get_id \ + -workflow_id $workflow_id \ + -short_name $row(recipient_role)] + } + unset row(recipient_role) + } + + foreach attr { + recipient attachment_num + } { + if { [info exists row($attr)] } { + set varname attr_$attr + # Convert the Tcl value to something we can use in the query + set $varname $row($attr) + # Add the column to the SET clause + lappend set_clauses "$attr = :$varname" + unset row($attr) + } + } + db_transaction { - if { [info exists row(recipient_role)] } { - if { ![empty_string_p $row(recipient_role)] } { - set recipient_role_id [workflow::role::get_id \ - -workflow_id $workflow_id \ - -short_name $row(recipient_role)] - } else { - set recipient_role_id [db_null] - } - db_dml edit_sim_role { + if { [llength $set_clauses] > 0 } { + db_dml edit_sim_role " update sim_tasks - set recipient = :recipient_role_id + set [join $set_clauses ", "] where task_id = :action_id - } - - unset row(recipient_role) + " } workflow::action::fsm::edit \ Index: openacs-4/packages/simulation/tcl/object-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/simulation/tcl/object-procs.tcl,v diff -u -r1.6 -r1.7 --- openacs-4/packages/simulation/tcl/object-procs.tcl 28 Nov 2003 16:55:52 -0000 1.6 +++ openacs-4/packages/simulation/tcl/object-procs.tcl 15 Dec 2003 15:28:20 -0000 1.7 @@ -49,6 +49,56 @@ return "${package_url}object-content/${name}" } + +ad_proc simulation::object::get_object_type_options { + -object_type:required + {-null_label "--None--"} +} { + Get options for a select/radio widget of available objects of a given object_type. + Deals with content_types as a special-case where it'll provide a drop-down of items, + not revisions. +} { + # We need to know if this is a CR content_type, because in that case we + # want to reference the item corresponding to the revision, not the revision + set content_type_p [db_string content_type_p { + select count(*) + from acs_object_type_supertype_map + where object_type = :object_type + and ancestor_type = 'content_revision' + }] + + # LARS TODO: We need to be able to scope this to a package, + # possibly filter by other things, control the sort order, + # we need to be able to control what the label looks like (e.g. include email for users) + # and it needs to be intelligent about scaling issues + if { $content_type_p } { + set options [db_list_of_lists select_options { + select r.title, + i.item_id + from cr_items i, cr_revisions r + where i.content_type = :object_type + and r.revision_id = i.live_revision + order by r.title + }] + } else { + set options [db_list_of_lists select_options { + select acs_object__name(object_id), + object_id + from acs_objects + where object_type = :object_type + order by acs_object__name(object_id) + }] + } + + if { ![empty_string_p $null_label] } { + set options [concat [list [list $null_label {}]] $options] + } + + return $options +} + + + ############################### # # simulation::object::xml namespace Index: openacs-4/packages/simulation/www/citybuild/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/simulation/www/citybuild/index.adp,v diff -u -r1.3 -r1.4 --- openacs-4/packages/simulation/www/citybuild/index.adp 11 Dec 2003 13:21:52 -0000 1.3 +++ openacs-4/packages/simulation/www/citybuild/index.adp 15 Dec 2003 15:28:21 -0000 1.4 @@ -3,6 +3,7 @@ @context;noquote@ +

Map XML

Index: openacs-4/packages/simulation/www/citybuild/object-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/simulation/www/citybuild/object-edit.tcl,v diff -u -r1.7 -r1.8 --- openacs-4/packages/simulation/www/citybuild/object-edit.tcl 12 Dec 2003 12:05:10 -0000 1.7 +++ openacs-4/packages/simulation/www/citybuild/object-edit.tcl 15 Dec 2003 15:28:21 -0000 1.8 @@ -262,54 +262,7 @@ return $result } -ad_proc get_object_type_options { - -object_type:required - {-null_label "--None--"} -} { - Get options for a select/radio widget of available objects of a given object_type. - Deals with content_types as a special-case where it'll provide a drop-down of items, - not revisions. -} { - # We need to know if this is a CR content_type, because in that case we - # want to reference the item corresponding to the revision, not the revision - set content_type_p [db_string content_type_p { - select count(*) - from acs_object_type_supertype_map - where object_type = :object_type - and ancestor_type = 'content_revision' - }] - # LARS TODO: We need to be able to scope this to a package, - # possibly filter by other things, control the sort order, - # we need to be able to control what the label looks like (e.g. include email for users) - # and it needs to be intelligent about scaling issues - if { $content_type_p } { - set options [db_list_of_lists select_options { - select r.title, - i.item_id - from cr_items i, cr_revisions r - where i.content_type = :object_type - and r.revision_id = i.live_revision - order by r.title - }] - } else { - set options [db_list_of_lists select_options { - select acs_object__name(object_id), - object_id - from acs_objects - where object_type = :object_type - order by acs_object__name(object_id) - }] - } - - if { ![empty_string_p $null_label] } { - set options [concat [list [list $null_label {}]] $options] - } - - return $options -} - - #--------------------------------------------------------------------- # Content edit/upload method # @@ -455,7 +408,7 @@ set elm_ref_type [get_metadata_property -content_type $content_type -entry_type attributes -entry $attribute_name -property references] if { ![empty_string_p $elm_ref_type] } { set elm_widget select - set options [get_object_type_options -object_type $elm_ref_type] + set options [simulation::object::get_object_type_options -object_type $elm_ref_type] lappend extra { options \$options } } @@ -485,7 +438,7 @@ } { set label [get_metadata_property -content_type $content_type -entry_type relations -entry $relation_tag -property label] set section [get_metadata_property -content_type $content_type -entry_type relations -entry $relation_tag -property section] - set options [get_object_type_options -object_type $target_type] + set options [simulation::object::get_object_type_options -object_type $target_type] # LARS HACK: This only works for a specific hard-coded max_n # We need to generalize so it can be dynamic @@ -693,14 +646,14 @@ -revision_id $revision_id \ -status "live" - # LARS: The way we do this update is not very pretty: Delete all relations and re-add the new ones + # TODO: The way we do this update is not very pretty: Delete all relations and re-add the new ones db_dml delete_all_relations { delete from cr_item_rels where item_id = :item_id } foreach elm $rel_elements { - # LARS HACK ALERT: This isn't a particularly pretty way to find all the related objects in the form + # TODO: LARS HACK ALERT: This isn't a particularly pretty way to find all the related objects in the form regexp {__(.+)__} $elm match relation_tag regexp {__.+__(.+)$} $elm match order_n set related_object_id [set $elm] Index: openacs-4/packages/simulation/www/simbuild/task-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/simulation/www/simbuild/task-edit.tcl,v diff -u -r1.8 -r1.9 --- openacs-4/packages/simulation/www/simbuild/task-edit.tcl 10 Dec 2003 16:06:46 -0000 1.8 +++ openacs-4/packages/simulation/www/simbuild/task-edit.tcl 15 Dec 2003 15:28:21 -0000 1.9 @@ -106,18 +106,24 @@ {label "New state"} {options $state_options} } + {attachment_num:integer(text) + {label "Number of attachments"} + {help_text "These are placeholders that are matched to props by the case author during SimInst"} + {html {size 2}} + } } -edit_request { set workflow_id $task_array(workflow_id) permission::require_write_permission -object_id $workflow_id set pretty_name $task_array(pretty_name) set description [template::util::richtext::create $task_array(description) $task_array(description_mime_type)] set new_state_id $task_array(new_state_id) - set recipient_role_id [db_string select_recipient { - select recipient + db_1row select_recipient { + select recipient as recipient_role_id, attachment_num from sim_tasks where task_id = :action_id - }] + } + if { ![empty_string_p $recipient_role_id] } { set recipient_role [workflow::role::get_element -role_id $recipient_role_id -element short_name] } else { @@ -144,11 +150,7 @@ permission::require_write_permission -object_id $workflow_id # create the task - # TODO IMPORTANT: - # Set short_name right -- or leave blank and have the workflow API construct a short_name - db_transaction { - set action_id [workflow::action::fsm::new \ -workflow_id $workflow_id \ -pretty_name $pretty_name \ @@ -159,16 +161,19 @@ -assigned_state_ids $assigned_state_ids \ -new_state_id $new_state_id] - # TODO: enabled_states, assigned_states - # TODO - put this stuff into simulation api and change previous call # and then add extra data for simulation # because workflow::action::fsm::new wants role.short_name instead of # role_id, we stay consistent for recipient_role - db_dml set_role_recipient { - insert into sim_tasks - values (:action_id, :recipient_role_id) - } + + array unset row + set row(recipient_role) $recipient_role + set row(attachment_num) $attachment_num + + simulation::action::edit \ + -action_id $action_id \ + -workflow_id $workflow_id \ + -array row } } -edit_data { # We use task_array(workflow_id) here, which is gotten from the DB, and not @@ -181,7 +186,7 @@ # TODO: enabled_states, assigned_states array unset row - foreach col { pretty_name assigned_role recipient_role description description_mime_type enabled_state_ids assigned_state_ids } { + foreach col { pretty_name assigned_role recipient_role description description_mime_type enabled_state_ids assigned_state_ids attachment_num } { set row($col) [set $col] } set row(short_name) {} Index: openacs-4/packages/simulation/www/siminst/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/simulation/www/siminst/index.tcl,v diff -u -r1.15 -r1.16 --- openacs-4/packages/simulation/www/siminst/index.tcl 15 Dec 2003 13:40:22 -0000 1.15 +++ openacs-4/packages/simulation/www/siminst/index.tcl 15 Dec 2003 15:28:21 -0000 1.16 @@ -37,7 +37,7 @@ label "Tasks" link_url_col sim_tasks_url display_template { - @dev_sims.tasks@ , with @dev_sims.prop_empty_count@ incomplete props + @dev_sims.tasks@, with @dev_sims.prop_empty_count@ incomplete props } } delete { @@ -71,7 +71,7 @@ set sim_in_dev_filter_sql "and ao.creation_user = :user_id" } -db_multirow -extend { cast_url map_roles_url map_props_url sim_tasks_url delete_url } dev_sims select_dev_sims " +db_multirow -extend { cast_url map_roles_url map_props_url sim_tasks_url delete_url prop_empty_count } dev_sims select_dev_sims " select w.workflow_id, w.pretty_name, (select count(*) @@ -85,17 +85,16 @@ where sr.role_id = wr.role_id and wr.workflow_id = w.workflow_id and character_id is null) as role_empty_count, - (select count(*) - from sim_task_object_map stom, + (select sum(coalesce(attachment_num,0)) + from sim_tasks st, workflow_actions wa - where stom.task_id = wa.action_id + where st.task_id = wa.action_id and wa.workflow_id = w.workflow_id) as prop_count, (select count(*) from sim_task_object_map stom, workflow_actions wa where stom.task_id = wa.action_id - and wa.workflow_id = w.workflow_id - and stom.object_id is null) as prop_empty_count, + and wa.workflow_id = w.workflow_id) as prop_not_empty_count, (select count(*) from workflow_actions wa where wa.workflow_id = w.workflow_id) as tasks @@ -108,6 +107,7 @@ and ss.sim_type = 'dev_sim' $sim_in_dev_filter_sql " { + set prop_empty_count [expr $prop_count - $prop_not_empty_count] if { [simulation::template::ready_for_casting_p -role_empty_count $role_empty_count -prop_empty_count $prop_empty_count] } { set cast_url [export_vars -base "${base_url}siminst/simulation-casting" { workflow_id }] } else { Index: openacs-4/packages/simulation/www/siminst/map-tasks.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/simulation/www/siminst/map-tasks.adp,v diff -u -r1.3 -r1.4 --- openacs-4/packages/simulation/www/siminst/map-tasks.adp 11 Dec 2003 13:21:53 -0000 1.3 +++ openacs-4/packages/simulation/www/siminst/map-tasks.adp 15 Dec 2003 15:28:21 -0000 1.4 @@ -2,8 +2,5 @@ @page_title;noquote@ @context;noquote@ -TODO: show a list of tasks with unmapped sim prop or sim location slots. Set description on for each task. + -

- Complete mapping -

Index: openacs-4/packages/simulation/www/siminst/map-tasks.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/simulation/www/siminst/map-tasks.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/simulation/www/siminst/map-tasks.tcl 28 Nov 2003 16:55:52 -0000 1.2 +++ openacs-4/packages/simulation/www/siminst/map-tasks.tcl 15 Dec 2003 15:28:21 -0000 1.3 @@ -6,6 +6,45 @@ workflow_id:integer } -set page_title "Map to Tasks" +workflow::get -workflow_id $workflow_id -array workflow_array +set page_title "Tasks for $workflow_array(pretty_name)" set context [list [list "." "SimInst" ] $page_title] +db_multirow -extend { description_html } tasks select_taks { + select a.action_id, + a.short_name, + a.pretty_name, + a.description, + a.description_mime_type, + st.attachment_num, + (select count(*) + from sim_task_object_map stom + where stom.task_id = st.task_id) as prop_not_empty_count + from workflow_actions a, + sim_tasks st + where a.workflow_id = :workflow_id + and st.task_id = a.action_id +} { + set description_html [ad_html_text_convert -maxlen 100 -from $description_mime_type -- $description] +} + +# TODO: Honor description_mime_type, fancy truncate + +template::list::create \ + -name "tasks" \ + -elements { + pretty_name { + label "Name" + link_url_eval {[export_vars -base task-edit { action_id }]} + } + description { + label "Description" + display_template {@tasks.description_html;noquote@} + } + attachment_num { + label "Number of attachments" + } + prop_not_empty_count { + label "Number of attachments populated" + } + } Index: openacs-4/packages/simulation/www/siminst/task-edit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/simulation/www/siminst/Attic/task-edit.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/simulation/www/siminst/task-edit.adp 12 Dec 2003 15:40:32 -0000 1.1 +++ openacs-4/packages/simulation/www/siminst/task-edit.adp 15 Dec 2003 15:28:21 -0000 1.2 @@ -1,10 +1,14 @@ @page_title;noquote@ @context;noquote@ - template.pretty_name + task.pretty_name -TODO -show task description body, list of related props (similar to -object-edit and images). end-to-end requires that props can be -associated but not that they can be embedded in the -description body. +

+ TODO + show task description body, list of related props (similar to + object-edit and images). end-to-end requires that props can be + associated but not that they can be embedded in the + description body. +

+ + Index: openacs-4/packages/simulation/www/siminst/task-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/simulation/www/siminst/Attic/task-edit.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/simulation/www/siminst/task-edit.tcl 12 Dec 2003 15:40:32 -0000 1.1 +++ openacs-4/packages/simulation/www/siminst/task-edit.tcl 15 Dec 2003 15:28:21 -0000 1.2 @@ -3,21 +3,141 @@ @author Joel Aufrecht } { - workflow_id:integer + action_id:integer } set user_id [auth::require_login] -set page_title "Edit Task" -set context [list [list "." "SimInst"] $page_title] -set old_name [workflow::get_element -workflow_id $workflow_id -element pretty_name] -acs_user::get -user_id $user_id -array user_array +workflow::action::fsm::get -action_id $action_id -array task_array -###################################################################### -# -# tasks -# -# a list showing description for all tasks in a sim -# -###################################################################### +# TODO: Move into simulation::action::get API +db_1row select_recipient { + select recipient as recipient_role_id, attachment_num + from sim_tasks + where task_id = :action_id +} -column_array task_array2 +array set task_array [array get task_array2] +set workflow_id $task_array(workflow_id) +permission::require_write_permission -object_id $workflow_id + +workflow::get -workflow_id $workflow_id -array workflow_array +set role_options [workflow::role::get_options -workflow_id $workflow_id] + +set page_title "Edit $task_array(pretty_name)" +set return_url [export_vars -base map-tasks { workflow_id }] +set context [list [list "." "SimInst"] [list $return_url "Tasks for $workflow_array(pretty_name)"] $page_title] + + + +ad_form -name task -export { workflow_id } -edit_buttons [list [list [ad_decode [ad_form_new_p -key action_id] 1 [_ acs-kernel.common_add] [_ acs-kernel.common_edit]] ok]] -form { + {action_id:key} + {pretty_name:text + {label "Task Name"} + {html {size 20}} + {mode display} + } + {assigned_role:text(select),optional + {label "Assigned To"} + {options $role_options} + {mode display} + } + {recipient_role:text(select),optional + {label "Recipient"} + {options $role_options} + {mode display} + } + {description:richtext,optional + {label "Task Description"} + {html {cols 60 rows 8}} + } + {attachment_num:integer(text) + {label "Number of attachments"} + {help_text "These are placeholders that are matched to props by the case author during SimInst"} + {html {size 2}} + {mode display} + } +} + +set prop_options [simulation::object::get_object_type_options -object_type "sim_prop"] + +for { set i 1 } { $i <= $task_array(attachment_num) } { incr i } { + ad_form -extend -name task -form [list [list attachment_$i:integer(select),optional [list label "Attachment $i"] [list options \$prop_options]]] + +} + + +ad_form -extend -name task -edit_request { + set pretty_name $task_array(pretty_name) + set description [template::util::richtext::create $task_array(description) $task_array(description_mime_type)] + set new_state_id $task_array(new_state_id) + set attachment_num $task_array(attachment_num) + + if { ![empty_string_p $task_array(recipient_role_id)] } { + set recipient_role [workflow::role::get_element -role_id $task_array(recipient_role_id) -element short_name] + } else { + set recipient_role {} + } + set assigned_role $task_array(assigned_role) + + db_foreach attachments { + select object_id, + order_n + from sim_task_object_map + where task_id = :action_id + and relation_tag = 'attachment' + } { + if { $order_n >= 1 && $order_n <= $task_array(attachment_num) } { + set attachment_$order_n $object_id + } + } +} -on_submit { + + set description_mime_type [template::util::richtext::get_property format $description] + set description [template::util::richtext::get_property contents $description] + + if { ![empty_string_p $recipient_role] } { + set recipient_role_id [workflow::role::get_id -workflow_id $workflow_id -short_name $recipient_role] + } else { + set recipient_role_id [db_null] + } +} -edit_data { + # We use task_array(workflow_id) here, which is gotten from the DB, and not + # workflow_id, which is gotten from the form, because the workflow_id from the form + # could be spoofed + permission::require_write_permission -object_id $task_array(workflow_id) + + array unset row + foreach col { description description_mime_type } { + set row($col) [set $col] + } + + db_transaction { + simulation::action::edit \ + -action_id $action_id \ + -workflow_id $task_array(workflow_id) \ + -array row + + # TODO: The way we do this update is not very pretty: Delete all relations and re-add the new ones + db_dml delete_all_relations { + delete from sim_task_object_map + where task_id = :action_id + } + + for { set i 1 } { $i <= $task_array(attachment_num) } { incr i } { + set elm "attachment_$i" + set related_object_id [set $elm] + + if { ![empty_string_p $related_object_id] } { + db_dml insert_rel { + insert into sim_task_object_map (task_id, object_id, order_n, relation_tag) + values (:action_id, :related_object_id, :i, 'attachment') + } + } + } + + } +} -after_submit { + ad_returnredirect $return_url + ad_script_abort +}