In this chapter we will cover Team Development features. Team Development is an APEX application within the Application Express development environment itself and was introduced in version 4.0 of APEX. Figure 4-1 shows the Team Development main menu.
Team Development can be used to track features, bugs, milestones, and other elements, but the most striking functionality is the Feedback feature. Using Feedback you can support the reporting and communication of bugs and enhancement requests from your end users, from a test or a production environment to your development environment and vice versa. This chapter will cover the setup of this built-in functionality and give some examples of how to use it. You'll also see how to use APEX views and packages to enhance Team Development's functionality to meet your specific needs.
The different parts of Team Development, pictured in Figure 4-1, are discussed in more detail later in the chapter. Each section ends with some tips and tricks on how to extend the usability of the standard features. As an example, we'll use the development of an application you are familiar with: Oracle Application Express itself.
Although Milestones is the second option in the menu shown in Figure 4-1, defining milestones is usually the first thing you'll want to do when you start with Team Development. A milestone is a project management term, marking the end of a stage, like the delivery of a work package. Milestones are used to determine whether or not a project is on schedule. For this reason, milestones are usually the first thing to define. The milestones in our example are the delivery of APEX Early Adopter Release 1, Release 2, and the final production versions of APEX 4.0 and 4.1.
Figure 4-2 shows the high-level data model used to record milestones. A milestone is categorized by a Milestone Type, associated with a Release, and owned by an Owner. The Milestone Type, Release, and Owner entities are not implemented as actual tables, but as a list of used values, like 'select distinct milestone_type of milestones
'.
The advantage of the non-normalized implementation in Figure 4-2 is that you can create milestones very quickly, without defining most related master data beforehand. All information regarding milestones is exposed through the APEX_TEAM_MILESTONES
view. That view is mainly based on the WWV_FLOW_EVENTS
table.
To create a milestone, as shown in Figure 4-3, you have to set the milestone date and add some additional information. When entering this additional information you might notice there is a feature in the user interface that differs from the other parts of APEX, but is generally implemented in Team Development. For some kinds of fields you have the option to select a value from a select list or enter a new value. Be aware that the new value supersedes the value in the select list. So if you enter a new value, that one will be used, regardless of whatever you selected in the select list.
Following are some descriptions of the fields shown in Figure 4-3:
The Type field can be used to differentiate the type of the milestone, such as, Early Adopter, Major Release, or Patch Release.
The Owner field indicates who is responsible for the milestone. The select list is populated from all fields within Team Development where you can enter names, like assigned to, contributor, and others, so you are not restricted to previous entered milestone owners. Note that the names you enter will be converted to lowercase.
The Release field defines the version of the software you set the milestone for. In our example you can expect releases like 4.0, 4.0.1, 4.0.2, and 4.1.
The Selectable for Features field gives you the option to hide milestones when adding a Feature. This can be used for milestones that are tentative and not yet ready for use. Note that switching this off for a milestone doesn't impact the features that are currently assigned to that milestone. Furthermore, you can add a full description of the milestone and add tags to it.
In the current version (4.0.2) of APEX there are some minor defects regarding milestones. In the Team Development dashboard, only the future milestones you've defined show up. And you have to be careful when deleting milestones, because there is no check that a milestone is not used somewhere else.
From the Team Development dashboard you can create a milestone with one click by using the plus icon in the upper-right corner of the milestone region on that page.
Later in this chapter you will learn how to display the information you entered in a Gantt chart, but first you have to set up your own Team Development Enhancement application. For this new application you can pick any schema owner you like, because you will only use the standard APEX views and packages within this application. Set the Application Alias to TDE (for "Team Development Enhancement") and create an empty home page in that application with HOME as Page Alias.
Once you've done that, create a link to that application via the menu Team Development Links. Click Create Link, give the link a meaningful name and set the Target to f?p=TDE:HOME
. Now you can access your newly created application from within Team Development using the Manage Links action from the Team Actions menu region on the right side of the Team Development main page.
An even nicer tweak is to add an image with a link to the Team Development main page. To do this you need to access your APEX Administration tool. Then navigate to Manage Instance and pick Define System Message. Now create a new Custom Message like this:
<script type="text/javascript"> $(function(){ if ( $v('pFlowStepId')=='4000') { // Create Image + Link to Team Development Enhancement on this page" $('.apex-list-horizontal') .append(' <div class="noncurrent"> <div class="image"> <a title = "Team Development Enhancement" href = "f?p=TDE:HOME" target = "_blank" > <img width ="128" height ="128" alt ="Team Development Enhancement" title ="Team Development Enhancement" src ="/i/apex/builder/apex_sample_app_128.png"> </a> </div> <div class="label"> <a title="Team Development Enhancement" href="f?p=TDE:HOME" target="_blank" > Team Development Enhancement </a> </div> </div>
'), } }); </script>
This code adds an image with a link to your application to the Team Development main page, just like in Figure 4-4. You have to adapt the href
and src
attribute to your liking. Please note that all HTML text used as a parameter to the append
function should be on one line, without additional carriage returns. In the listing above the code is formatted just to improve readability.
Using Features you describe the functionality you want to add to or change in your application. You can assign a Feature to an Owner and a Feature can have a Contributor. You can also make a distinction based on Focus Areas, like Charts, Interactive Reports, or Themes. Once you've decided when to implement a feature, you can assign it to a certain Release and Milestone. Although earlier on you might have defined a milestone as set for a certain release, that relationship isn't used in the feature functionality. You can break down features into subfeatures, adding detail to your planning and making different people responsible for different subfeatures.
In Figure 4-5 you can see how the data model used for the Features functionality is implemented. In addition to the select lists for the Owner, Contributor, Focus Area, and Release fields, there are three other select lists you'll encounter when defining a feature: Status, Desirability, and Priority. Unlike the other select items, these last three contain predefined and fixed values, and cannot be customized.
Values in the Status, Desirability, and Priority lists are defined using the following views in the APEX schema: WWV_FLOW_FEATURE_DEF_ST_CODES, WWV_FLOW_FEATURE_DESIRABLITY
, and WWV_FLOW_FEATURE_PRIORITIES
. The same holds for the other "status" views. In a future version of APEX you will probably be able to change these values to meet your own standards.
In Figure 4-6 you'll find an example of the Feature functionality. You can begin to get an idea of what is available to you by looking at the various fields in the figure.
There is some date information that you can add to a feature, like start and due date. The latter is defaulted to the date of the corresponding milestone. You can also add more details like a description, a justification, and a progress log. You can use these fields to create your own reports.
Although the standard options already offer you a lot of functionality, you can even expand the amount of data you can enter. If you click on the Team Development Settings in the task list on the right side of the Team Development home page, you can enable the tracking of attributes for all aspects of application development, like user interface, testing, security, and the like. Figure 4-7 shows the drop-down menu items to enable this level of tracking.
For each of these tracking attributes you enable, a new region within your features screen appears at the bottom, as shown in Figure 4-8.
So now you know what all these fields are for, you can use the standard functionality of APEX to customize the display of the features interactive report to fit—more or less—your specific needs. Figure 4-9 shows a customized report.
Starting from the standard features interactive report you can achieve the result, as shown in Figure 4-9, by applying these steps using the Action menu:
Set Control Break to Parent Feature.
Filter on "Parent Feature is not null".
Select the Columns you want to display. You have to select the Control Break column as well or the break won't work.
Compute the "Remaining" by entering a computation like BA * (100-BG), where BA refers to the Effort and BG to the Status Percent.
Aggregate the Effort—and maybe the Remaining as well.
Now that you've entered some project information it would be nice to see this information in a way you're used to when running projects: in a Gantt chart.
Create a new Chart Page in your Team Development Enhancement application, pick a Project Gantt chart as the type to display, set the other settings as you like them, and enter this SQL query:
SELECT NULL link , FEATURE_NAME task_name , FEATURE_ID task_id , PARENT_FEATURE_ID parent_id , NVL(START_DATE,SYSDATE) actual_start , NVL(DUE_DATE,SYSDATE) actual_end , FEATURE_STATUS progress FROM APEX_TEAM_FEATURES START WITH PARENT_FEATURE_ID IS NULL CONNECT BY PRIOR FEATURE_ID = PARENT_FEATURE_ID
With the data presented in Figure 4-9, you'll get a Gantt chart when you run the page. You'll notice that the start and end dates of the parent features don't match the dates of the subfeatures. You can solve that by including the calculation of those dates in the SQL using analytic functions. Later in the chapter, you'll learn how to let Anychart do the calculation, when you'll generate the XML used by the Chart by yourself.
To enable the collapse functionality in this Anychart Gantt, you have to set the Show Datagrid property to Yes and disable all Include on Datagrid items, as shown in Figure 4-10.
Now, let's create a link from the Gantt chart back into Team Development. Notice we didn't include a link in the SQL query, because that solution doesn't work anymore. Instead, go to the Chart Series and add an Action Link to a custom URL target where the URL is set to: f?p=4800:9001:&SESSION.::NO:9001:P9001_ID:#ID#
. If you run the page again you'll see something like what's shown in Figure 4-11. Now click on a bar in the charts and you will be redirected to the page where you can view and edit the feature you clicked. Notice the parameter used is #ID#
and not the actual column name you provided in the SQL.
To Do's are small pieces of work, or actions, you assign to your co-workers and want to track. As with features, you can create a multilevel breakdown of To Do's. But if you really want to keep track of things, creating a multilevel breakdown might not be the wisest thing to do, because if you have a lot of To Do's defined, it can be rather difficult to keep oversight of them all. Also, since Team Development is not a real planning tool (compared to Microsoft Project, for example), all the figures you enter, like dates and estimated effort, are not accumulated to the higher level. So you cannot simply rely on those figures; you'll need some additional reports to get closer to the real situation.
The data model for the To Do part is shown in Figure 4-12. This gives you an idea of how the tables and views are related and where the fields on the page in Figure 4-13 come from.
A To Do (also known as a Task) is assigned to someone and can have a contributor, or an additional contributor. A To Do has a certain status. Similar to Features, this status is hard coded using a view: WWV_FLOW_TASK_DEF_STATUS_CODES
. You can add more details to a To Do by specifying a Category, a Release, a Feature, and a Milestone. Figure 4-13 shows an example of a To Do item.
All information regarding To Do's is exposed through the APEX_TEAM_TODOS
view, which is mainly based on the WWV_FLOW_TASKS
table. And, similar to features progress, all information entered in the progress area is recorded as Task Progress and represented as a list of activities carried out.
Now that you've explored the planning and activities aspects of Team Development, it would be nice to present Milestones, Features, and To Do's in one Gantt chart. Following are some of the details you'll need to attend to in order to accomplish that goal:
The roll-up of start and end dates from lower-level Features to higher-level Features or from To Do's to Features—defined as the Parent Feature of a Feature or the Feature of a To Do
Defining, and showing in the Gantt chart, a predecessor for a To Do—defined as the Parent To Do of a To Do
Defining, and showing in the Gantt chart, what To Do is the last step for a Milestone—defined as the Milestone property of a To Do
First create a new Project Gantt Chart. You can use the SQL query provided earlier in "Extending the Features Functionality," or any other valid query for the chart, because you won't use the results of that query anyway.
Once the region is created, you can delete the generated chart series. Now, create a (dummy) HTML region before the Chart region with a hidden field, named P3_XML_PG
. Next, edit the Chart XML by providing this custom XML:
<?xml version = "1.0" encoding="utf-8" standalone = "yes"?> <anygantt> <settings> <background enabled="false" /> <navigation enabled="true" position="Top" size="30"> <buttons collapse_expand_button="false" align="Far"/> <text>Project Gantt</text> </navigation> </settings> <datagrid enabled="true" width="400" /> <styles> <task_styles> <task_style name="defaultStyle"> <actual> <bar_style> <middle> <fill enabled="true" type="Gradient"> <gradient angle="−90"> <key color="#689663" position="0"/> <key color="#6B9866" position="0.38"/> <key color="#B4FFAB" position="1"/> </gradient> </fill> </middle> </bar_style> </actual> </task_style> </task_styles> </styles> &P3_XML_PG. </anygantt>
See Figure 4-14 for where to put these lines of code.
Instead of using the standard #DATA#
replacement, the chart will use the contents of the P3_XML_PG
field to generate the chart. So define a On Load – After Header page process to load data into that field using a function you will create shortly:
begin :P3_XML_PG := GenerateProjectXML; end;
See Figure 4-15 for where to put this code.
For now you have to disable the validation of the PL/SQL code, because the function is not available yet. Next switch to APEX's SQL Workshop and define that function:
create or replace function GenerateProjectXML return varchar2 is l_chart_data_xml varchar2(32767); l_task_xml varchar2(32767); l_connector_xml varchar2(32767); cursor tasks is select link , task_type , name , id
, parent_id , predecessor , milestone_id , to_char(actual_start,'YYYY.MM.DD') start_date , to_char(actual_end,'YYYY.MM.DD') end_date , progress from ( select null link , 'T' task_type , todo_name name , todo_id id , feature_id parent_id , parent_todo_id predecessor , milestone_id milestone_id , start_date actual_start , due_date actual_end , todo_status progress from apex_team_todos union select null link , 'F' task_type , feature_name name , feature_id id , parent_feature_id parent_id , null predecessor , null milestone_id , null actual_start , null actual_end , feature_status progress from apex_team_features union select null link , 'M' task_type , milestone name , milestone_id id , null parent_id , null predecessor , null milestone_id , milestone_date actual_start , null actual_end , null progress from apex_team_milestones order by 5 ) start with parent_id is null connect by prior id = parent_id ; begin -- Project Chart Opening Tag -- Define "auto_summary" so Anycharts does the calculations l_chart_data_xml := '<project_chart>'||
'<auto_summary enabled="True" />' ; -- Task & Connectors Opening Tags l_task_xml := '<tasks>'; l_connector_xml := '<connectors>'; -- Loop through series data for c1 in tasks loop if c1.task_type ='T' -- ToDo then -- Task Tag l_task_xml := l_task_xml || '<task id="' ||c1.id ||'" '|| 'name="' ||c1.name ||'" '|| 'parent="' ||c1.parent_id ||'" '|| 'actual_start="' ||c1.start_date ||'" '|| 'actual_end="' ||c1.end_date ||'" '|| 'progress="' ||c1.progress ||'" '|| 'style="Gantt" />' ; l_connector_xml := l_connector_xml || '<connector ' || 'type="FinishStart" ' || 'from="'||c1.predecessor ||'" '|| 'to="' ||c1.id ||'" '|| ' />' ; if c1.milestone_id is not null then l_connector_xml := l_connector_xml || '<connector ' || 'type="FinishStart" ' || 'from="'||c1.id ||'" '|| 'to="' ||c1.milestone_id||'" '|| ' />' ; end if; elsif c1.task_type = 'F' -- Feature then -- Start / End / Progress are auto-calculated l_task_xml := l_task_xml || '<task id="' ||c1.id ||'" '|| 'name="' ||c1.name ||'" '|| 'parent="' ||c1.parent_id ||'" '|| '/>' ; elsif c1.task_type = 'M' -- Milestone then -- A Milestone has no End date l_task_xml := l_task_xml || '<task id="' ||c1.id ||'" '||
'name="' ||c1.name ||'" '|| 'actual_start="'||c1.start_date||'" '|| '/>' ; end if; end loop; -- Task Closing Tag l_task_xml := l_task_xml||'</tasks>'; -- Periods Closing Tag l_connector_xml := l_connector_xml||'</connectors>'; -- Project Chart Closing Tag l_chart_data_xml := l_chart_data_xml || l_task_xml || l_connector_xml || '</project_chart>'; return l_chart_data_xml; end;
If you run the page you'll get a representation of your Team Development data in a Gantt chart. See Figure 4-16 for an example.
Bugs cover a functionality we are all familiar with. Bugs are deficiencies in the products we deliver, like software or documentation. The model for bug-tracking is built using a similar data structure as the other pieces of Team Development. Figure 4-17 shows the model. You'll see a few real tables, a few views with fixed values, and some dynamic lists of values.
All information regarding To Do's is exposed through the APEX_TEAM_BUGS
view, which is mainly based on the WWV_FLOW_BUGS
table.
A Bug has a Status, a Severity, and a Priority. The values in these select lists are defined in the views WWV_FLOW_BUG_STATUS_CODES, WWV_FLOW_BUG_SEVERITY
, and WWV_FLOW_BUG_PRIORITY
. When resolving a bug, it's assigned to a person and planned to be fixed by some release, milestone, and/or date. Furthermore you can add a lot more information on the bug itself, like the platform, browser, or operating system. Figure 4-18 shows an example of a filed bug.
Because a Bug only contains a Fix Date—and no start date or effort—you have to link a Bug to a To Do in order to use a reported Bug in your customized Gantt Chart. The Bug section is intended for capturing issues that might be customer browser- or operating system–specific.
Of all functionality in the Team Development application, Feedback is without any doubt the most valuable. Feedback offers you a simple mechanism to communicate with your end users. And Feedback can be installed in your application with just a few mouse clicks. All information regarding Feedback is exposed through the APEX_TEAM_FEEDBACK
view, which is mainly based on the WWV_FLOW_FEEDBACK
table. The data model showing all tables and views related to the Feedback functionality is shown in Figure 4-19.
The APEX_TEAM_FEEDBACK
view contains a lot of information regarding the environment of the user who enters the feedback. It not only contains the page and workspace identifiers, but also the complete session state, and even information about the browser used and the IP addresses of client and server. And if that's not enough to fit your needs, there are eight additional attributes at your disposal.
The feedback process as implemented in Team Development consists of a couple of steps that form a cycle together. The first step is creating a feedback entry by a user. Then the feedback is exported from the environment the user is working in and imported in the development environment. The developer analyzes the feedback and responds to it. He can also log the feedback entry as a Bug, a To Do, or even a Feature. The responses, which may contain questions for clarification, are exported from the development environment and imported into the user's environment. Then the user can follow up to the developer's question. That information can be exported again and that cycle can go round and round, as Figure 4-20 indicates.
Within one development environment you can manage feedback from multiple sources—for instance, from a test and production environment, or even multiple production environments running at different customer sites.
In your application, add a Page of type Feedback Page. When you keep the default settings, the Feedback page itself is created, an entry is added to the navigation bar, and feedback is enabled. When you or the users of your application click on the link in the navigation bar, a page pops up like in Figure 4-21.
Because this is just a page in your application, you can change all fields and behavior to match your requirements. When creating the page itself you can create up to eight custom attributes to the feedback page. These attributes are included in the submit process that is generated by the wizard. The default select list Feedback Type is created from select the_name, id from APEX_FEEDBACK_TYPES order by id
. If you needed more or different Feedback Types, you might think of adding records to this table but, like a lot of these kind of select lists in Team Development, it isn't a table, but a view with predefined data. So that wouldn't work. Also, replacing the select list with your own dynamic or static select list isn't a good idea, because pages in Team Development rely on values that exist in that view. So let's just keep that one as it is.
But you can add an item, as long as it fits within a varchar2(4000)
column. In the example in Figure 4-22 I added two additional items to help qualifying the feedback when it comes in by letting the end user enter a Severity and Priority.
If you've defined your own feedback items, you have to change the standard Submit Feedback Page Process a little. For example:
apex_util.submit_feedback ( p_comment => :P102_FEEDBACK, p_type => :P102_FEEDBACK_TYPE, p_application_id => :P102_APPLICATION_ID, p_page_id => :P102_PAGE_ID, p_email => :P102_EMAIL, p_attribute_01 => :P102_SEVERITY, p_label_01 => 'Severity', p_attribute_02 => :P102_PRIORITY, p_label_02 => 'Priority'),
You have to use your own items as values for the parameters p_attribute_01
, etc., and for easier interpretation of the values it is a good idea to provide the parameters p_label_01
with a value that tells what attribute_01
actually is. One of the parameters is the users' email address. This is automatically filled with the email address of the user—but only if you use the APEX authentication. If you use another type of authentication, you should place your own function here to extract the email address from the username. Or, if you use public pages with no authentication at all, you should add an email address item on your feedback page.
If you develop your applications in the same workspace as your users are using, there is no need to export and import the feedback. But that's a very unusual case. Mostly you develop on a development instance and your users are testing in a test environment—perhaps even more than one—and running production in another environment.
Exporting feedback starts from the Application Builder main page. When you press the Export button there you get a list of objects you can export. Just click the last one, called "Team Development Feedback" (see Figure 4-23), or click on the Feedback tab on the far right.
All feedback entered after the date you enter in the "Changes Since" field will be exported. Usually you'll set that to the date you last exported the feedback. Leave it empty for all feedback.
You only can export feedback for the whole workspace, which is to say, for all applications that are contained within the workspace.
One other setting is called the Deployment System. This setting is used to distinguish feedback from one workspace and another. That's especially important if you have deployed your application in more than one workspace, like test and production, or in production at multiple customer sites. This way you can see where feedback originates from and where the responses on the feedback should be sent to. In order to make this distinction, you have to be sure that this value is different for each implementation. You can set this value in the APEX Administration utility, via Edit Workspace Information, as shown in Figure 4-24. There it is called the Feedback Synchronization Source Identifier and it's defaulted to the Workspace Name.
The feedback export file is named feedback_export_from_<Deployment System>.sql
. If you entered a date/time value in the Changes Since field, the filename is appended with _since_<datetimestamp>
.
Change the Feedback Synchronization Source Identifier for every workspace you deploy to a unique and meaningful name.
From the Application Builder main page you can access the import function. You can import the exported feedback, which is just a SQL file, like any other APEX component. You can import the feedback as many times as you like and in any other workspace you want. If you try to import feedback into the same workspace you exported it from, you'll get an error. Feedback is uniquely identified by the Deployment System and a sequence number.
Once you've imported feedback you can start processing it. Figure 4-25 shows the screen from which you begin doing that.
When you press the Log as Bug button on the page in Figure 4-25, a bug is created and, apart from the information entered in this page, some context is filled in, like the application, the page, and the version. Figure 4-26 shows the resulting bug report.
Strangely, other information that is captured by using feedback isn't automatically added to the bug, like the platform, browser, and operating system. And even more interesting stuff, like the complete session state, is captured but not copied to the bug description. There is also no visible reference from the bug to the feedback to retrieve that information afterwards.
Similar to creating a bug from a feedback entry, you can also create a To Do from a feedback entry, or even transform a feedback entry into a Feature. Remarkably, only when transforming a feedback entry into a To Do, is there an option to delete the feedback entry. But deleting feedback before the issue is completely solved isn't a good idea, because of all the information that's contained within the feedback that might be relevant for sorting out the issue.
Notice that Figure 4-26 mentions "Converting feedback to a bug will set the feedback status to closed". Despite this message, that isn't really the case. In the current version of APEX (4.0.2 as I write this chapter), you must change the status of the feedback by hand.
Instead of —or in addition to—logging the feedback as a Bug or a To Do item, you can also edit the feedback. Doing so, you can change the status and add comments. See the example in Figure 4-27.
The next challenge is to get those comments back to the originating system. After all, it doesn't do much good to comment on feedback if the person originating that feedback never gets to see the comment. The next section shows how to meet this challenge.
For exporting our response back to deployment, we have to take the same steps as when exporting feedback from deployment into development. Notice the Direction in Figure 4-28 when exporting the feedback. It says Export response to deployment now.
And now you can also select the Deployment System. The select lists contain every deployment system for which there is feedback imported beforehand. This feedback export file is now named feedback_import_for_ROEL.sql
. You can see in Figure 4-28 that ROEL is the system selected in the Deployment System dropdown.
You have to take the same steps to import your response into the deployment system as you do when importing feedback into development. The difference is that you are going in the opposite direction.
If you try to import a response into an environment it wasn't exported for, you'll get an error.
After importing, you will see that the changes you made in development are reflected in the feedback of the deployment system, as shown in Figure 4-29. And although the Developer comments you entered are exported, they are not imported.
Once you've imported the response, you have reached the end of the feedback lifecycle. But sometimes you need some additional information to solve an issue, as in the example above. Of course, you can call or email the person who submitted the feedback, but there is an option within Team Development that supports this functionality as well. Unfortunately, it is not automatically implemented, but you can implement it yourself with some additional easy steps.
The first thing to do is to create a report on the feedback, so the user can not only report feedback, but also has insight on the status. To begin, create a report page, with page number 103 in this example, and make it accessible according to your standard application navigation style; it can be an entry in a list, a tab, or a link in the navigation bar. The following select
statement selects the data from the apex_team_feedback
view and should show only the feedback for the current application. You can also choose to narrow the selection down, so users can only see the feedback they entered themselves, or feedback with a certain status. That's all up to you.
SELECT feedback_number "Nr." , feedback_id "Follow up" , feedback , CASE WHEN feedback_type = 1 THEN 'General Comment' WHEN feedback_type = 2 THEN 'Enhancement Requested' WHEN feedback_type = 3 THEN 'Bug' END "Type" , CASE WHEN feedback_status = 0 THEN 'No Status' WHEN feedback_status = 1 THEN 'Acknowledged' WHEN feedback_status = 2 THEN 'Additional Info. Requested' WHEN feedback_status = 3 THEN 'Open' WHEN feedback_status = 4 THEN 'Closed'
END "Status" , page_name "Page" , public_response "Response" FROM apex_team_feedback WHERE application_id = :APP_ID ORDER BY updated_on DESC
Figure 4-30 shows what the report page you're trying to achieve will look like.
To get that result, you have to make some minor changes. First, the column Follow Up in Figure 4-30 is used as a Link Column. Set the Link Text to the image of your liking and set the URL target to javascript:FollowUp( '#Follow up#'),
. The Javascript function is defined in the Function and Global Variable Declaration section of the page as
function FollowUp( pId ){ $s('P103_FEEDBACK_ID', pId); $('#FollowUp').show(); }
Within the same page, create a new HTML Region named FollowUp with two items: P103_FEEDBACK_ID
and P103_FOLLOW_UP
. Set the Static ID of the region to FollowUp, and set the Region Attributes to style="display:none; width:540px"
. So, the region will be hidden by default and shown when a user clicks the little edit image in the report. Also create a Region Button there to submit the page.
Next, create an On Submit Page Process to save the follow up on the feedback using the apex_util.submit_feedback_followup
procedure, as shown in Figure 4-31.
You can also show the follow up on that page using the apex_util.get_feedback_follow_up
function or querying the apex_team_feedback_followup view
. Once the follow up is entered by the end user, that information can be transferred back to the development system.
You execute the same steps to get follow up back into the development system as you did to get the feedback from deployment to development. You export and import the feedback, and the follow up is exported and imported as well.
Instead of waiting for the feedback to arrive in your development environment, you can also opt for sending the entered feedback by email. This may be only for the more serious entries, but that's up to you. And of course that will only work if there is a mail server configured for sending email from APEX.
Another enhancement you might think of is sending feedback automatically by email on a regular basis. Obviously you need a mail server configured for this. You can create a procedure like the one listed below and use the apex_plsql_job.submit_process
function to schedule the procedure.
Create or replace procedure send_feedback ( p_workspace apex_workspaces.workspace%type , p_send_to varchar2 ) is l_mail_id number; l_clob clob; l_blob blob; l_mail_blob blob; l_dest_offset number := 1; l_src_offset number := 1; l_amount integer := dbms_lob.lobmaxsize; l_blob_csid number := dbms_lob.default_csid; l_lang_ctx integer := dbms_lob.default_lang_ctx; l_warning integer; -- The name of the Workspace you want to export the Feedback from l_workspace_id apex_workspaces.workspace_id%type; -- Search string for removing all "trash". Real SQL starts from there l_search varchar2(255) := 'set define off'; begin -- Get the ID of the Workspace and set the environment l_workspace_id := apex_util.find_security_group_id ( p_workspace ); wwv_flow_api.set_security_group_id( l_workspace_id ); -- Create the mail object l_mail_id := apex_mail.send ( p_to => p_send_to , p_from => '[email protected]' , p_subj => 'Feedback Export from Deployment to Development' , p_body => 'See the attachment.' ); -- Create the CLOB -- Export the Feedback to Development for the Workspace provided l_clob := wwv_flow_utilities.export_feedback_to_development ( l_workspace_id ); -- Convert to BLOB dbms_lob.createtemporary ( lob_loc => l_blob , cache => true ); dbms_lob.converttoblob ( l_blob , l_clob , l_amount , l_dest_offset , l_src_offset , l_blob_csid , l_lang_ctx , l_warning ); -- Remove all "trash", so only real SQL is left over
dbms_lob.createtemporary ( lob_loc => l_mail_blob , cache => true ); dbms_lob.copy( l_mail_blob , l_blob , dbms_lob.lobmaxsize , 1 , dbms_lob.instr( lob_loc => l_blob , pattern =>utl_raw.cast_to_raw(l_search) ) ); -- Add the file as a BLOB attachment to the mail apex_mail.add_attachment ( p_mail_id => l_mail_id , p_attachment => l_mail_blob , p_filename => 'feedback_export_from_'||lower(p_workspace)||'.sql' , p_mime_type => 'application/text' ); commit; end;
Now that you know about the functionality of Team Development, it may become clear that the planning capacity of Team Development doesn't beat a "real" project management tool, like Microsoft Project. Even if you add some nice Gantt charts, which are an absolute necessity for any planning tool, Team Development still lacks too much functionality. Here are a fewof the things you can't do with Team Development:
Add a capacity to a resource (like 40 hours per week).
Plan using the given capacity.
Add a cost to a resource, so you can plan how much money you have to spend.
Monitor how many hours a resource spends, using an interface with a time reporting application.
Add multiple predecessor to To Do's, so you can plan and execute the actions in the right order and determine the critical path.
Of course, you can build all this in your custom Team Development Enhancements application, but capacity planning and critical path determination are complex mathematical issues and not easy to solve. Still, for small projects (up to five people or so), Team Development might be a very convenient—and inexpensive—tool to use. But when a project starts getting more complex, you have to spend some money and buy a specialized tool to support your business.
That said, the Feedback feature of Team Development is in itself so powerful—especially when you add functionality like that shown in the examples—that for Feedback alone you should consider usingTeam Development. When you're in the test phase of your project in particular, Feedback will facilitate communication between users and developers. Your application can only benefit from that.