Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 1f592a0f

Von Moritz Bunkus vor fast 11 Jahren hinzugefügt

  • ID 1f592a0f4f88893b5c2cb29b2d10e2d07b444ac0
  • Vorgänger e2cad7d4
  • Nachfolger 3250f2ee

Pflichtenhefte: Auflisten von Abschnitten

Unterschiede anzeigen:

SL/Controller/RequirementSpecItem.pm
use Rose::Object::MakeMethods::Generic
(
scalar => [ qw(requirement_spec item) ],
scalar => [ qw(requirement_spec item visible_item visible_section) ],
);
# __PACKAGE__->run_before('load_requirement_spec');
......
# actions
#
sub action_ajax_list {
my ($self) = @_;
my $js = SL::ClientJS->new;
if (!$::form->{clicked_id}) {
# Clicked on "sections" in the tree. Do nothing.
return $self->render($js);
}
$self->init_visible_section($::form->{current_content_id}, $::form->{current_content_type});
$self->item(SL::DB::RequirementSpecItem->new(id => $::form->{clicked_id})->load->get_section);
if (!$self->visible_section || ($self->visible_section->id != $self->item->id)) {
my $html = $self->render('requirement_spec_item/_section', { output => 0 }, requirement_spec_item => $self->item);
$js->html('#column-content', $html)
->val('#current_content_type', $self->item->get_type)
->val('#current_content_id', $self->item->id);
}
$self->render($js);
}
sub action_new {
my ($self) = @_;
......
return join "\n", (split m/\n/, $@)[0..4];
}
sub init_visible_section {
my ($self, $content_id, $content_type) = @_;
return undef unless $content_id;
return undef unless $content_type =~ m/section|function-block/;
$self->visible_item(SL::DB::RequirementSpecItem->new(id => $content_id)->load);
return $self->visible_section($self->visible_item->get_section);
}
1;
SL/Controller/RequirementSpecTextBlock.pm
my $html = $self->render('requirement_spec_text_block/ajax_list', { output => 0 }, TEXT_BLOCKS => $text_blocks, output_position => $new_where);
$js->html('#column-content', $html)
->val('#current_content_type', 'text-blocks-' . (0 == $new_where ? 'front' : 'back'))
->val('#current_content_id', $::form->{clicked_id});
}
$self->render($js);
SL/DB/RequirementSpecItem.pm
return [ sort { $a->position <=> $b->position } @{ $self->children } ];
}
sub get_section {
my ($self) = @_;
$self = $self->parent while $self->parent_id;
return $self;
}
sub get_type {
my ($self) = @_;
return 'section' if !$self->parent_id;
return $self->parent->parent_id ? 'sub-function-block' : 'function-block';
}
1;
SL/Presenter/RequirementSpecItem.pm
my ($self, $item, %params) = @_;
my @children = map { $self->requirement_spec_item_jstree_data($_, %params) } @{ $item->sorted_children };
my $type = !$item->parent_id ? 'section' : 'functionblock';
my $type = !$item->parent_id ? 'section' : 'function-block';
return {
data => join(' ', map { $_ || '' } ($item->fb_number, $item->title)),
data => join(' ', map { $_ || '' } ($item->fb_number, $item->title, '<' . $item->id . '>')),
metadata => { id => $item->id, type => $type },
attr => { id => "fb-" . $item->id, href => $params{href} || '#' },
attr => { id => "fb-" . $item->id, href => $params{href} || '#', class => $type . '-context-menu' },
children => \@children,
};
}
css/requirement_spec.css
.section-empty-description {
color: #bbb;
}
.function-block {
border-bottom: 1px solid #bbb;
}
.section-description-heading {
font-weight: bold;
}
.section-description {
color: #000;
background: rgb(235, 235, 235);
border: 1px solid #ccc;
margin-bottom: 15px;
}
.sub-function-block {
border-bottom: 1px solid #ccc;
}
.sub-function-block-container {
margin: 10px 0px 10px 20px;
border: 1px solid #ccc;
}
.sub-function-block-header {
padding: 5px;
font-weight: bold;
color: #fff;
background: #ccc;
}
js/requirement_spec.js
/* Functions used for the requirement specs tree view */
// -----------------------------------------------------------------------------
// ------------------------------ the tree itself ------------------------------
// -----------------------------------------------------------------------------
function requirement_spec_tree_check_move(data) {
var dragged_type = data.o.data('type');
var dropped_type = data.r.data('type');
......
if ((dropped_type == "text-block") || (dropped_type == "text-blocks-front") || (dropped_type == "text-blocks-back"))
return false;
var dropped_depth = dropped_type == "sections" ? 0 : dropped_type == "section" ? 1 : data.r.parent().parent().data('type') != "functionblock" ? 2 : 3;
var dropped_depth = dropped_type == "sections" ? 0 : dropped_type == "section" ? 1 : data.r.parent().parent().data('type') != "function-block" ? 2 : 3;
if ((data.p == "inside") || (data.p == "last"))
dropped_depth++;
......
if (!type)
return;
if ('sections' == type) {
$('#current_content_type').val('sections');
$('#current_content_id').val('');
return;
}
var url = 'controller.pl?action='
$.get('controller.pl', {
action: (/^text-block/ ? 'RequirementSpecTextBlock' : 'RequirementSpecItem') + '/ajax_list.js',
action: (/^text-block/.test(type) ? 'RequirementSpecTextBlock' : 'RequirementSpecItem') + '/ajax_list.js',
requirement_spec_id: $('#requirement_spec_id').val(),
current_content_type: $('#current_content_type').val(),
current_content_id: $('#current_content_id').val(),
clicked_type: type,
clicked_id: node.data('id')
}, function(new_data) {
$('#current_content_type').val(type);
$('#current_content_id').val(node.data('id'));
eval_json_result(new_data);
});
}
function section_form_requested(data) {
$('#new-section-button').removeAttr('disabled');
if (data.status == "ok")
$('#content-column').html(data.html);
else
alert('oh yeah response: ' + data.status + "\n" + data.error);
}
function section_form_submitted(data) {
alert('oh yeah response: ' + data.status);
}
function server_side_error(things_to_enable) {
alert('Server-side error.');
if (things_to_enable)
$(things_to_enable).removeAttr('disabled');
}, eval_json_result);
}
function new_section_form() {
$('#new-section-button').attr('disabled', 'disabled');
$.ajax({
type: 'POST',
url: 'controller.pl',
data: 'action=RequirementSpecItem/new.json&requirement_spec_id=' + $('#requirement_spec_id').val() + '&item_type=section',
success: section_form_requested,
error: function() { server_side_error('#new-section-button'); }
});
}
function submit_section_form(id) {
$.ajax({
type: 'POST',
url: 'controller.pl',
data: 'action=RequirementSpecItem/create.json&' + $('section-form-' + id).serialize(),
success: section_form_submitted
});
}
function cancel_section_form(id) {
$('#content-column').html('intentionally empty');
}
// -------------------------------------------------------------------------
// ------------------------------ text blocks ------------------------------
// -------------------------------------------------------------------------
function find_text_block_id(clicked_elt) {
// console.log("id: " + $(clicked_elt).attr('id'));
......
if (id)
$('#text-block-' + id).show();
}
// --------------------------------------------------------------------------------
// ------------------------------ sections and items ------------------------------
// --------------------------------------------------------------------------------
function find_item_id(clicked_elt) {
console.log("clicked id: " + $(clicked_elt).attr('id'));
var id = $(clicked_elt).attr('id');
var result = /^(function-block|function-block-content|sub-function-block|sub-function-block-content|section|section-header)-(\d+)$/.exec(id);
if (result) {
console.log("find_item_id: case 1: " + result[2]);
return result[2];
}
id = $(clicked_elt).closest("[id*=fb-]").attr('id')
if (/^fb-\d+$/.test(id)) {
console.log("find_item_id: case 2: " + id.substr(3));
return id.substr(3) * 1;
}
console.log("find_item_id: case undef");
return undefined;
}
function standard_item_ajax_call(key, opt, other_data) {
var data = {
action: "RequirementSpecTextBlock/ajax_" + key,
requirement_spec_id: $('#requirement_spec_id').val(),
id: find_item_id(opt.$trigger),
current_content_type: $('#current_content_type').val(),
current_content_id: $('#current_content_id').val()
};
console.log("I would normally POST the following now:");
console.log(data);
// $.post("controller.pl", $.extend(data, other_data || {}), eval_json_result);
return true;
}
function disable_edit_item_commands(key, opt) {
return false; // find_item_id(opt.$trigger) == undefined;
}
locale/de/all
'Add and edit units' => 'Einheiten erfassen und bearbeiten',
'Add bank account' => 'Bankkonto erfassen',
'Add custom variable' => 'Benutzerdefinierte Variable erfassen',
'Add function block' => 'Funktionsblock hinzufügen',
'Add link: select records to link with' => 'Verknüpfungen hinzufügen: zu verknüpfende Belege auswählen',
'Add linked record' => 'Verknüpften Beleg hinzufügen',
'Add links' => 'Verknüpfungen hinzufügen',
......
'Add new custom variable' => 'Neue benutzerdefinierte Variable erfassen',
'Add note' => 'Notiz erfassen',
'Add printer' => 'Drucker hinzufügen',
'Add section' => 'Abschnitt hinzufügen',
'Add sub function block' => 'Unterfunktionsblock hinzufügen',
'Add text block' => 'Textblock erfassen',
'Add unit' => 'Einheit hinzuf&uuml;gen',
'Address' => 'Adresse',
......
'Delete drafts' => 'Entwürfe löschen',
'Delete links' => 'Verknüpfungen löschen',
'Delete profile' => 'Profil löschen',
'Delete section' => 'Abschnitt löschen',
'Delete text block' => 'Textblock löschen',
'Delete transaction' => 'Buchung löschen',
'Deleted' => 'Gelöscht',
......
'Edit requirement spec status' => 'Pflichtenheftstatus bearbeiten',
'Edit requirement spec type' => 'Pflichtenhefttypen bearbeiten',
'Edit risk level' => 'Risikograd bearbeiten',
'Edit section' => 'Abschnitt bearbeiten',
'Edit section #1' => 'Abschnitt #1 bearbeiten',
'Edit templates' => 'Vorlagen bearbeiten',
'Edit text block' => 'Textblock bearbeiten',
......
'No default currency' => 'Keine Standardwährung',
'No delivery term has been created yet.' => 'Es wurden noch keine Lieferbedingungen angelegt',
'No department has been created yet.' => 'Es wurde noch keine Abteilung erfasst.',
'No description has been entered yet.' => 'Es wurde noch keine Beschreibung eingegeben.',
'No dunnings have been selected for printing.' => 'Es wurden keine Mahnungen zum Drucken ausgew&auml;hlt.',
'No file has been uploaded yet.' => 'Es wurde noch keine Datei hochgeladen.',
'No function blocks have been created yet.' => 'Es wurden noch keine Funktionsblöcke angelegt.',
......
'No requirement spec statuses has been created yet.' => 'Es wurden noch keine Pflichtenheftstatus angelegt.',
'No requirement spec type has been created yet.' => 'Es wurden noch keine Pflichtenhefttypen angelegt.',
'No risks level has been created yet.' => 'Es wurden noch keine Risikograde angelegt.',
'No sections have been created so far.' => '',
'No shipto selected to delete' => 'Keine Lieferadresse zum Löschen ausgewählt',
'No summary account' => 'Kein Sammelkonto',
'No text blocks have been created for this position.' => 'Für diese Position wurden noch keine Textblöcke angelegt.',
......
'Postscript' => 'Postscript',
'Posustva_coa' => 'USTVA Kennz.',
'Pre-defined Texts' => 'Vordefinierte Textblöcke',
'Preamble' => 'Einleitung',
'Preferences' => 'Einstellungen',
'Preferences saved!' => 'Einstellungen gespeichert!',
'Prefix for the new bins\' names' => 'Namenspr&auml;fix f&uuml;r die neuen Lagerpl&auml;tze',
templates/webpages/requirement_spec/show.html
<div id="column-content">
[%- IF SELF.requirement_spec_item -%]
[%- INCLUDE 'requirement_spec_item/_single_section.html' requirement_spec_item=SELF.requirement_spec_item -%]
[%- INCLUDE 'requirement_spec_item/_section.html' requirement_spec_item=SELF.requirement_spec_item -%]
[%- ELSE -%]
no section
[%#- render :partial => 'requirement_spec_items/no_section' -%]
[%- INCLUDE 'requirement_spec_item/_no_section.html' -%]
[%- END -%]
</div>
</div>
......
{ data: [% JSON.json(LxERP.t8("Sections")) %],
metadata: { type: "sections" },
attr: { id: "sections" },
attr: { id: "sections", class: "section-context-menu" },
children: [
[% FOREACH section = SELF.requirement_spec.sections %]
......
return true;
}
function ask_delete_item(key, opt) {
if (confirm("[% LxERP.t8("Are you sure?") %]"))
standard_item_ajax_call(key, opt);
return true;
}
$(function(){
$.contextMenu({
selector: '.text-block-context-menu',
items: {
add: { name: "[% LxERP.t8('Add text block') %]", icon: "add", callback: standard_text_block_ajax_call },
edit: { name: "[% LxERP.t8('Edit text block') %]", icon: "edit", callback: standard_text_block_ajax_call, disabled: disable_edit_text_block_commands },
delete: { name: "[% LxERP.t8('Delete text block') %]", icon: "delete", callback: ask_delete_text_block, disabled: disable_edit_text_block_commands },
sep1: "---------",
copy: { name: "[% LxERP.t8('Copy') %]", icon: "copy", disabled: disable_edit_text_block_commands },
paste: { name: "[% LxERP.t8('Paste') %]", icon: "paste", disabled: disable_edit_text_block_commands }
}
});
$.contextMenu({
selector: '.text-block-context-menu',
items: {
add: { name: "[% LxERP.t8('Add text block') %]", icon: "add", callback: standard_text_block_ajax_call },
edit: { name: "[% LxERP.t8('Edit text block') %]", icon: "edit", callback: standard_text_block_ajax_call, disabled: disable_edit_text_block_commands },
delete: { name: "[% LxERP.t8('Delete text block') %]", icon: "delete", callback: ask_delete_text_block, disabled: disable_edit_text_block_commands },
sep1: "---------",
copy: { name: "[% LxERP.t8('Copy') %]", icon: "copy", disabled: disable_edit_text_block_commands },
paste: { name: "[% LxERP.t8('Paste') %]", icon: "paste", disabled: disable_edit_text_block_commands }
}
});
$.contextMenu({
selector: '.section-context-menu',
items: {
add_section: { name: "[% LxERP.t8('Add section') %]", icon: "add", callback: standard_item_ajax_call },
add_function_block: { name: "[% LxERP.t8('Add function block') %]", icon: "add", callback: standard_text_block_ajax_call },
sep1: "---------",
edit: { name: "[% LxERP.t8('Edit') %]", icon: "edit", callback: standard_item_ajax_call, disabled: disable_edit_item_commands },
delete: { name: "[% LxERP.t8('Delete') %]", icon: "delete", callback: ask_delete_item, disabled: disable_edit_item_commands },
sep2: "---------",
copy: { name: "[% LxERP.t8('Copy') %]", icon: "copy", disabled: disable_edit_item_commands },
paste: { name: "[% LxERP.t8('Paste') %]", icon: "paste", disabled: disable_edit_item_commands }
}
});
$.contextMenu({
selector: '.function-block-context-menu,.sub-function-block-context-menu',
items: {
new_item: { name: "[% LxERP.t8('Add function block') %]", icon: "add", callback: standard_item_ajax_call },
new_sub_item: { name: "[% LxERP.t8('Add sub function block') %]", icon: "add", callback: standard_item_ajax_call },
sep1: "---------",
edit: { name: "[% LxERP.t8('Edit') %]", icon: "edit", callback: standard_item_ajax_call, disabled: disable_edit_item_commands },
delete: { name: "[% LxERP.t8('Delete') %]", icon: "delete", callback: standard_item_ajax_call, disabled: disable_edit_item_commands },
sep2: "---------",
copy: { name: "[% LxERP.t8('Copy') %]", icon: "copy", disabled: disable_edit_item_commands },
paste: { name: "[% LxERP.t8('Paste') %]", icon: "paste", disabled: disable_edit_item_commands }
}
});
});
function edit_section_header() {
$.post("controller.pl?action=RequirementSpecItem/edit_section&id=" + encodeURIComponent($('#active_section_id').val()), function(data) {
var header = $('#section-header');
header.data('old-elements', header.children().detach());
header.html(data);
});
}
function submit_section_form() {
$.post("controller.pl?action=RequirementSpecItem/update_section&id=" + $('#section-form form').serialize(), function(data) {
var header = $('#section-header');
header.removeData('old-elements');
header.html(data['header_html']);
$('#tree').jstree('rename_node', '#fb-' + data['id'], data['node_name']);
});
}
function cancel_section_form() {
var header = $('#section-header');
header.empty();
header.append(header.data('old-elements'));
header.removeData('old-elements');
}
-->
</script>
templates/webpages/requirement_spec_item/_function_block.html
[%- USE HTML -%][%- USE LxERP -%][%- USE P -%][%- USE L -%]
<div id="function-block-[% requirement_spec_item.id %]" class="function-block">
<div id="function-block-content-[%- requirement_spec_item.id -%]" class="function-block-content[%- IF requirement_spec_item.flagged -%] flagged[%- END -%] function-block-context-menu">
[% INCLUDE 'requirement_spec_item/_function_block_content_top.html' id_prefix='' %]
<div class="sub-function-block-container" id="sub-function-block_container-[%- requirement_spec_item.id -%]"[%- IF !requirement_spec_item.children.size -%] style="display: none"[%- END -%]>
<div class="sub-function-block-header" id="sub-function-block_header_[%- requirement_spec_item.id -%]">
[%- LxERP.t8("Sub function blocks") -%]
</div>
[%- FOREACH sub_function_block = requirement_spec_item.children -%]
[%- INCLUDE 'requirement_spec_item/_sub_function_block.html' requirement_spec_item=sub_function_block -%]
[%- END -%]
</div>
[% INCLUDE 'requirement_spec_item/_function_block_content_bottom.html' id_prefix='' %]
</div>
</div>
templates/webpages/requirement_spec_item/_function_block_content_bottom.html
[%- USE LxERP -%][%- USE P -%]<div id="[% id_prefix %]function-block-content-bottom-[% requirement_spec_item.id %]" class="smaller" style="text-align:right">
[%- IF requirement_spec_item.dependencies.size -%]
<span class="gray">
[%- LxERP.t8("Dependencies") -%]: [%- P.requirement_spec_item_dependency_list(requirement_spec_item.dependencies) -%]
</span><br>
[%- END -%]
<span class="gray">
[%- LxERP.t8("Complexity") -%]: [%- requirement_spec_item.requirement_spec_complexity.description IF requirement_spec_item.requirement_spec_complexity -%]
&nbsp; | &nbsp;
[%- LxERP.t8("Risk") -%]: [%- requirement_spec_item.requirement_spec_risk.description IF requirement_spec_item.requirement_spec_risk -%]
&nbsp; | &nbsp;
[%- LxERP.t8("Effort") -%]: [%#- render :partial => 'requirement_spec_items/time_estimation_item', :locals => { :item => requirement_spec_item } -%]
</span>
</div>
templates/webpages/requirement_spec_item/_function_block_content_top.html
[%- USE HTML -%][%- USE L -%]<div id="[% id_prefix %]function-block-content-top-[% requirement_spec_item.id %]">
<b>[%- HTML.escape(requirement_spec_item.fb_number) -%]</b> &lt;[% requirement_spec_item.id %]&gt;
[%- L.simple_format(requirement_spec_item.description) -%]
</div>
templates/webpages/requirement_spec_item/_no_section.html
[%- USE LxERP -%]
<span class="section-context-menu">
[%- LxERP.t8("No sections have been created so far.") %]
[% LxERP.t8("Create one from the context menu by right-clicking on this text.") %]
</span>
templates/webpages/requirement_spec_item/_section.html
[%- USE HTML -%][%- USE LxERP -%][%- USE L -%]
<div id="full-section-content">
<div class="section-context-menu" id="section-header-[% requirement_spec_item.id %]">
[%- INCLUDE 'requirement_spec_item/_section_header.html' %]
</div>
<div id="section-list-empty" class="section-context-menu"[% IF requirement_spec_item.children.size %] style="display: none"[% END %]>
[%- LxERP.t8("No function blocks have been created yet.") %]
[% LxERP.t8("Create one from the context menu by right-clicking on this text.") %]
</div>
<div id="section-list" class="section">
[%- FOREACH function_block = requirement_spec_item.children -%]
[%- INCLUDE 'requirement_spec_item/_function_block.html' requirement_spec_item=function_block -%]
[%- END -%]
</div>
</div>
templates/webpages/requirement_spec_item/_section_header.html
[%- USE HTML -%][%- USE L -%][%- USE LxERP -%]
<h1>
[%- HTML.escape(requirement_spec_item.fb_number) %]: [% HTML.escape(requirement_spec_item.title) -%]
[%- HTML.escape(requirement_spec_item.fb_number) %]: &lt;[% requirement_spec_item.id %]&gt;
[% IF requirement_spec_item.title %]
[% HTML.escape(requirement_spec_item.title) %]
[% ELSE %]
<div class="dimmed-text">
[%- LxERP.t8("No text has been entered yet.") %]
</div>
[% END %]
</h1>
[% IF requirement_spec_item.description %]
<div class="section-description">
<div class="section-description">
<div class="section-description-heading">[%- LxERP.t8("Preamble") %]</div>
[% IF requirement_spec_item.description %]
[%- L.simple_format(requirement_spec_item.description) -%]
</div>
[%- ELSE %]
<div class="section-empty-description">[%- LxERP.t8("No description has been entered yet.") %]</div>
[%- END %]
[%- ELSE %]
<span class="dimmed-text">[%- LxERP.t8("No text has been entered yet.") %]</span>
[%- END %]
</div>
templates/webpages/requirement_spec_item/_single_section.html
[%- USE HTML -%][%- USE LxERP -%][%- USE L -%]
<div class="section-context-menu" id="section-header">
[%- INCLUDE 'requirement_spec_item/_section_header.html' %]
</div>
[%- L.hidden_tag('active_section_id', requirement_spec_item.id) -%]
<ul id="section" class="section function-block-context-menu">
[%- FOREACH subitem = requirement_spec_item.children -%]
[%- INCLUDE 'requirement_spec_item/_single_subitem.html' requirement_spec_item=subitem -%]
[%- END -%]
</ul>
<div id="new_subitem_form" class="subitem-form clearfix">
</div>
<div id="new_subitem_link" class="highlight-box" style="[%- 'display:none' IF requirement_spec_item.children.size -%]">
[%- LxERP.t8("No function blocks have been created yet.") %]
</div>
<script type="text/javascript">
<!--
$(function(){
$.contextMenu({
selector: '.section-context-menu',
callback: function(key, options) {
var m = "clicked: " + key;
window.console && console.log(m) || alert(m);
},
items: {
edit: { name: "[% LxERP.t8('Edit section') %]", icon: "edit", callback: edit_section_header },
delete: { name: "[% LxERP.t8('Delete section') %]", icon: "delete" },
sep1: "---------",
copy: { name: "[% LxERP.t8('Copy') %]", icon: "copy" },
paste: { name: "[% LxERP.t8('Paste') %]", icon: "paste" }
}
});
$.contextMenu({
selector: '.function-block-context-menu',
callback: function(key, options) {
var m = "clicked: " + key;
window.console && console.log(m) || alert(m);
},
items: {
new_item: { name: "[% LxERP.t8('New function block') %]", icon: "add"},
new_sub_item: { name: "[% LxERP.t8('New sub function block') %]", icon: "add"},
sep1: "---------",
edit: { name: "[% LxERP.t8('Edit') %]", icon: "edit"},
delete: { name: "[% LxERP.t8('Delete') %]", icon: "delete"},
sep2: "---------",
copy: { name: "[% LxERP.t8('Copy') %]", icon: "copy" },
paste: { name: "[% LxERP.t8('Paste') %]", icon: "paste" }
}
});
$('.section-context-menu').on('click', function(e){
console.log('clicked', this);
});
});
function edit_section_header() {
$.post("controller.pl?action=RequirementSpecItem/edit_section&id=" + encodeURIComponent($('#active_section_id').val()), function(data) {
var header = $('#section-header');
header.data('old-elements', header.children().detach());
header.html(data);
});
}
function submit_section_form() {
$.post("controller.pl?action=RequirementSpecItem/update_section&id=" + $('#section-form form').serialize(), function(data) {
var header = $('#section-header');
header.removeData('old-elements');
header.html(data['header_html']);
$('#tree').jstree('rename_node', '#fb-' + data['id'], data['node_name']);
});
}
function cancel_section_form() {
var header = $('#section-header');
header.empty();
header.append(header.data('old-elements'));
header.removeData('old-elements');
}
-->
</script>
templates/webpages/requirement_spec_item/_single_subitem.html
[%- USE HTML -%][%- USE LxERP -%][%- USE P -%]
<li id="subitem_[%- requirement_spec_item.id -%]" class="subitem">
<div id="subitem_content_[%- requirement_spec_item.id -%]" class="subitem-content[%- IF requirement_spec_item.flagged -%] flagged[%- END -%]">
[%#- IF !@requirement_spec.project.nil? -%]
[%#- link_to image_tag("chronometer.png"), account_time_requirement_spec_requirement_spec_item_path(requirement_spec_item.requirement_spec, requirement_spec_item) -%]
[%#- END -%]
[%#- link_to_new_sub(requirement_spec_item.parent) -%]
[%#- link_to_remote image_tag("new_subsub.png"),
:url => new_requirement_spec_requirement_spec_item_url(requirement_spec_item.requirement_spec, :requirement_spec_item_id => requirement_spec_item.id),
:method => :get,
:condition => "check_for_editbox()",
:update => "new_subsubitem_form_#{requirement_spec_item.id}" -%]
<b>[%- HTML.escape(requirement_spec_item.fb_number) -%]</b>
[%- HTML.escape(requirement_spec_item.description) -%]
<div class="subsubitem-container" id="subsubitem_container_[%- requirement_spec_item.id -%]">
<div class="subsubitem-header" id="subsubitem_header_[%- requirement_spec_item.id -%]"[%- IF !requirement_spec_item.children.size -%] style="display: none"[%- END -%]>
[%- LxERP.t8("Sub function blocks") -%]
</div>
[%- IF requirement_spec_item.children.size -%]
[%- FOREACH subsubitem = requirement_spec_item.children -%]
[%#- render :partial => "requirement_spec_items/single_subsubitem", :locals => {:requirement_spec_item => subsubitem} -%]
[%- END -%]
[%- END -%]
</div>
<div id="new_subsubitem_form_[%- requirement_spec_item.id -%]" class="subsubitem_form"></div>
<div class="smaller" style="text-align:right">
[%- IF requirement_spec_item.dependencies.size -%]
<span class="gray">
[%- LxERP.t8("Dependencies") -%]: [%- P.requirement_spec_item_dependency_list(requirement_spec_item.dependencies) -%]
</span><br>
[%- END -%]
<span class="gray">
[%- LxERP.t8("Complexity") -%]: [%- requirement_spec_item.requirement_spec_complexity.description IF requirement_spec_item.requirement_spec_complexity -%]
&nbsp; | &nbsp;
[%- LxERP.t8("Risk") -%]: [%- requirement_spec_item.requirement_spec_risk.description IF requirement_spec_item.requirement_spec_risk -%]
&nbsp; | &nbsp;
[%- LxERP.t8("Effort") -%]: [%#- render :partial => 'requirement_spec_items/time_estimation_item', :locals => { :item => requirement_spec_item } -%]
</span>
</div>
</div>
</li>
templates/webpages/requirement_spec_item/_sub_function_block.html
[%- USE HTML -%][%- USE LxERP -%][%- USE P -%]
<div id="sub-function-block-[% requirement_spec_item.id %]" class="sub-function-block">
<div id="sub-function-block-content-[%- requirement_spec_item.id -%]" class="sub-function-block-content[%- IF requirement_spec_item.flagged -%] flagged[%- END -%] sub-function-block-context-menu">
[% INCLUDE 'requirement_spec_item/_function_block_content_top.html' id_prefix='sub-' %]
[% INCLUDE 'requirement_spec_item/_function_block_content_bottom.html' id_prefix='sub-' %]
</div>
</div>

Auch abrufbar als: Unified diff