Revision c1569bc1
Von Moritz Bunkus vor fast 11 Jahren hinzugefügt
SL/Controller/RequirementSpec.pm | ||
---|---|---|
|
||
use Rose::Object::MakeMethods::Generic
|
||
(
|
||
scalar => [ qw(requirement_spec customers projects types statuses db_args flat_filter is_template) ],
|
||
scalar => [ qw(requirement_spec requirement_spec_item customers projects types statuses db_args flat_filter is_template) ],
|
||
);
|
||
|
||
__PACKAGE__->run_before('setup');
|
||
__PACKAGE__->run_before('load_requirement_spec', only => [ qw( edit update destroy tree) ]);
|
||
__PACKAGE__->run_before('load_requirement_spec', only => [ qw( edit update show destroy tree) ]);
|
||
__PACKAGE__->run_before('load_select_options', only => [ qw(new edit create update list) ]);
|
||
__PACKAGE__->run_before('load_search_select_options', only => [ qw( list) ]);
|
||
|
||
... | ... | |
$self->render('requirement_spec/form', title => t8('Edit requirement spec'));
|
||
}
|
||
|
||
sub action_show {
|
||
my ($self) = @_;
|
||
|
||
my $item = $::form->{requirement_spec_item_id} ? SL::DB::RequirementSpecItem->new(id => $::form->{requirement_spec_item_id})->load : @{ $self->requirement_spec->sections }[0];
|
||
$self->requirement_spec_item($item);
|
||
|
||
$self->render('requirement_spec/show', title => t8('Show requirement spec'));
|
||
}
|
||
|
||
sub action_create {
|
||
my ($self) = @_;
|
||
|
||
... | ... | |
my ($self) = @_;
|
||
|
||
$::auth->assert('config');
|
||
$::request->{layout}->use_stylesheet("${_}.css") for qw(requirement_spec yaml/core/base.min);
|
||
$::request->{layout}->use_javascript("${_}.js") for qw(jquery.jstree requirement_spec);
|
||
$::request->{layout}->use_stylesheet("${_}.css") for qw(jquery.contextMenu requirement_spec);
|
||
$::request->{layout}->use_javascript("${_}.js") for qw(jquery.jstree jquery/jquery.contextMenu requirement_spec);
|
||
$self->is_template($::form->{is_template} ? 1 : 0);
|
||
|
||
return 1;
|
SL/Controller/RequirementSpecItem.pm | ||
---|---|---|
);
|
||
|
||
# __PACKAGE__->run_before('load_requirement_spec');
|
||
__PACKAGE__->run_before('load_requirement_spec_item', only => [qw(dragged_and_dropped)]);
|
||
__PACKAGE__->run_before('load_requirement_spec_item', only => [qw(dragged_and_dropped edit_section update_section)]);
|
||
|
||
#
|
||
# actions
|
||
... | ... | |
$self->render(\'', { type => 'json' });
|
||
}
|
||
|
||
sub action_edit_section {
|
||
my ($self, %params) = @_;
|
||
$self->render('requirement_spec_item/_section_form', { layout => 0 });
|
||
}
|
||
|
||
sub action_update_section {
|
||
my ($self, %params) = @_;
|
||
|
||
$self->item->update_attributes(title => $::form->{title}, description => $::form->{description});
|
||
|
||
my $result = {
|
||
id => $self->item->id,
|
||
header_html => $self->render('requirement_spec_item/_section_header', { layout => 0, output => 0 }, requirement_spec_item => $self->item),
|
||
node_name => join(' ', map { $_ || '' } ($self->item->fb_number, $self->item->title)),
|
||
};
|
||
$self->render(\to_json($result), { type => 'json' });
|
||
}
|
||
|
||
#
|
||
# filters
|
||
#
|
SL/DB/RequirementSpec.pm | ||
---|---|---|
return [ sort { $a->position <=> $b->position } grep { !$_->parent_id } @{ $self->items } ];
|
||
}
|
||
|
||
sub displayable_name {
|
||
my ($self) = @_;
|
||
|
||
return sprintf('%s: "%s"', $self->type->description, $self->title);
|
||
}
|
||
|
||
1;
|
SL/Presenter.pm | ||
---|---|---|
use SL::Presenter::Project;
|
||
use SL::Presenter::Record;
|
||
use SL::Presenter::RequirementSpec;
|
||
use SL::Presenter::RequirementSpecItem;
|
||
use SL::Presenter::SepaExport;
|
||
use SL::Presenter::Text;
|
||
use SL::Presenter::Tag;
|
SL/Presenter/RequirementSpec.pm | ||
---|---|---|
use parent qw(Exporter);
|
||
|
||
use Exporter qw(import);
|
||
our @EXPORT = qw(requirement_spec_text_block_jstree_data
|
||
requirement_spec_item_jstree_data);
|
||
our @EXPORT = qw(requirement_spec_text_block_jstree_data);
|
||
|
||
use Carp;
|
||
|
||
... | ... | |
};
|
||
}
|
||
|
||
sub requirement_spec_item_jstree_data {
|
||
my ($self, $item, %params) = @_;
|
||
|
||
my @children = map { $self->requirement_spec_item_jstree_data($_, %params) } @{ $item->sorted_children };
|
||
my $type = !$item->parent_id ? 'section' : 'functionblock';
|
||
|
||
return {
|
||
data => join(' ', map { $_ || '' } ($item->fb_number, $item->title)),
|
||
metadata => { id => $item->id, type => $type },
|
||
attr => { id => "fb-" . $item->id, href => $params{href} || '#' },
|
||
children => \@children,
|
||
};
|
||
}
|
||
|
||
1;
|
SL/Presenter/RequirementSpecItem.pm | ||
---|---|---|
package SL::Presenter::RequirementSpecItem;
|
||
|
||
use strict;
|
||
|
||
use parent qw(Exporter);
|
||
|
||
use Exporter qw(import);
|
||
our @EXPORT = qw(requirement_spec_item_jstree_data requirement_spec_item_dependency_list);
|
||
|
||
use Carp;
|
||
|
||
sub requirement_spec_item_jstree_data {
|
||
my ($self, $item, %params) = @_;
|
||
|
||
my @children = map { $self->requirement_spec_item_jstree_data($_, %params) } @{ $item->sorted_children };
|
||
my $type = !$item->parent_id ? 'section' : 'functionblock';
|
||
|
||
return {
|
||
data => join(' ', map { $_ || '' } ($item->fb_number, $item->title)),
|
||
metadata => { id => $item->id, type => $type },
|
||
attr => { id => "fb-" . $item->id, href => $params{href} || '#' },
|
||
children => \@children,
|
||
};
|
||
}
|
||
|
||
sub requirement_spec_item_dependency_list {
|
||
my ($self, $item) = @_;
|
||
|
||
$::locale->language_join([ map { $_->fb_number } @{ $item->dependencies } ]);
|
||
}
|
||
|
||
1;
|
css/requirement_spec.css | ||
---|---|---|
width: 300px;
|
||
}
|
||
|
||
#column-container {
|
||
width: 100%;
|
||
padding-left: 0;
|
||
padding-right: 0;
|
||
margin-left: 0;
|
||
margin-right: 0;
|
||
}
|
||
|
||
#tree-column {
|
||
float: left;
|
||
width: 25%;
|
||
border-right: 1px solid black;
|
||
}
|
||
|
||
#content-column {
|
||
margin-left: 10px;
|
||
float: left;
|
||
padding-left: 10px;
|
||
}
|
||
|
||
.section-empty-description {
|
||
color: #bbb;
|
||
}
|
templates/webpages/requirement_spec/_version.html | ||
---|---|---|
[%- USE L -%][%- USE LxERP -%][%- USE HTML -%]
|
||
[% L.stuff %]
|
||
[% LxERP.t8("Current version") %]:
|
||
[% IF !requirement_spec.version_id %]
|
||
[% LxERP.t8("Working copy without version") %]
|
||
[% ELSE %]
|
||
[% LxERP.t8("Version") %] [% HTML.escape(requirement_spec.version.version_number) %]
|
||
[% LxERP.t8("dated") %] [% HTML.escape(requirement_spec.version.itime.displayable_date) %]
|
||
[%- END -%]
|
templates/webpages/requirement_spec/show.html | ||
---|---|---|
[%- USE JSON -%][%- USE HTML %][%- USE L %][%- USE LxERP %][%- USE P -%]
|
||
|
||
<h1>[%- HTML.escape(SELF.requirement_spec.displayable_name('format', 'with_customer')) %]
|
||
[% LxERP.t8("for") %]
|
||
[% HTML.escape(SELF.requirement_spec.customer.displayable_name) -%]
|
||
</h1>
|
||
|
||
[%- L.hidden_tag('requirement_spec_id', SELF.requirement_spec.id) -%]
|
||
|
||
<div id="requirement_spec_version">
|
||
[%- INCLUDE 'requirement_spec/_version.html' requirement_spec=SELF.requirement_spec -%]
|
||
</div>
|
||
|
||
<div id="column-container">
|
||
<div id="tree-column" style="border-right: 1px solid black">
|
||
<div style="min-height: 32px; height: 32px;">
|
||
<div style="float: left">
|
||
[% L.button_tag("new_section_form()", LxERP.t8("New section"), id="new-section-button") %]
|
||
</div>
|
||
<div id="spinner" class="clearfix" style="float: right; display: none; background:url('js/themes/requirement-spec/throbber.gif') center center no-repeat !important; min-height: 32px; height: 32px; min-width: 32px; width: 32px;"></div>
|
||
</div>
|
||
|
||
<div id="tree"></div>
|
||
</div>
|
||
|
||
<div id="content-column" class="clearfix">
|
||
<div id="section-container" class="section-container">
|
||
|
||
<div id="section_content" class="section-content">
|
||
[%- IF SELF.requirement_spec_item && SELF.requirement_spec_item.id -%]
|
||
[%- INCLUDE 'requirement_spec_item/_single_section.html' requirement_spec_item=SELF.requirement_spec_item -%]
|
||
[%- ELSE -%]
|
||
no section
|
||
[%#- render :partial => 'requirement_spec_items/no_section' -%]
|
||
[%- END -%]
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script type="text/javascript">
|
||
<!--
|
||
var tree_data = [
|
||
{ "data": [% JSON.json(LxERP.t8("Text blocks front")) %],
|
||
"metadata": { "type": "textblocks-front" },
|
||
"attr": { "id": "tb-front" },
|
||
"children": [
|
||
[% FOREACH tb = SELF.requirement_spec.text_blocks_for_position(0) %]
|
||
[% P.requirement_spec_text_block_jstree_data(tb).json %][% IF !loop.last %],[% END %]
|
||
[% END %]
|
||
]
|
||
},
|
||
|
||
{ "data": [% JSON.json(LxERP.t8("Sections")) %],
|
||
"metadata": { "type": "sections" },
|
||
"attr": { "id": "sections" },
|
||
"children": [
|
||
|
||
[% FOREACH section = SELF.requirement_spec.sections %]
|
||
[% P.requirement_spec_item_jstree_data(section).json %][% IF !loop.last %],[% END %]
|
||
[% END %]
|
||
]
|
||
},
|
||
|
||
{ "data": [% JSON.json(LxERP.t8("Text blocks back")) %],
|
||
"metadata": { "type": "textblocks-back" },
|
||
"attr": { "id": "tb-back" },
|
||
"children": [
|
||
[% FOREACH tb = SELF.requirement_spec.text_blocks_for_position(1) %]
|
||
[% P.requirement_spec_text_block_jstree_data(tb).json %][% IF !loop.last %],[% END %]
|
||
[% END %]
|
||
]
|
||
}
|
||
];
|
||
|
||
$(function() {
|
||
$('#tree').jstree({
|
||
"core": {
|
||
"animation": 0,
|
||
"initially_open": [ "tb-front", "tb-back", "sections"
|
||
[%- FOREACH section = SELF.requirement_spec.sections -%]
|
||
, "fb-[% section.id %]"
|
||
[%- FOREACH function_block = section.children -%]
|
||
, "fb-[% function_block.id -%]"
|
||
[%- END -%]
|
||
[%- END -%]
|
||
]
|
||
},
|
||
"json_data": {
|
||
"data": tree_data
|
||
},
|
||
"crrm": {
|
||
"move": {
|
||
"check_move": check_move,
|
||
"open_move": true
|
||
}
|
||
},
|
||
"themes": {
|
||
"theme": "requirement-spec"
|
||
},
|
||
"plugins": [ "themes", "json_data", "ui", "crrm", "dnd" ]
|
||
})
|
||
.bind("move_node.jstree", node_moved);
|
||
|
||
$(document).ajaxSend(function() {
|
||
$('#spinner').show();
|
||
}).ajaxStop(function() {
|
||
$('#spinner').hide();
|
||
});
|
||
});
|
||
-->
|
||
</script>
|
templates/webpages/requirement_spec/tree.html | ||
---|---|---|
|
||
[%- L.hidden_tag('requirement_spec_id', SELF.requirement_spec.id) -%]
|
||
|
||
<div id="page" class="ym-grid ym-equalize">
|
||
<div class="ym-g25 ym-gl" style="border-right: 1px solid black">
|
||
<div id="column-container">
|
||
<div id="tree-column">
|
||
<div style="min-height: 32px; height: 32px;">
|
||
<div style="float: left">
|
||
[% L.button_tag("new_section_form()", LxERP.t8("New section"), id="new-section-button") %]
|
||
</div>
|
||
<div id="spinner" style="float: right; display: none; background:url('js/themes/requirement-spec/throbber.gif') center center no-repeat !important; min-height: 32px; height: 32px; min-width: 32px; width: 32px;"></div>
|
||
<div style="clear: both"></div>
|
||
</div>
|
||
|
||
<div id="tree"></div>
|
||
</div>
|
||
|
||
<div class="ym-gl">
|
||
<div id="content-column">
|
||
<p>There's beauty in the breakdown. 0</p>
|
||
<p>There's beauty in the breakdown. 1</p>
|
||
<p>There's beauty in the breakdown. 2</p>
|
||
<p>There's beauty in the breakdown. 3</p>
|
||
<p>There's beauty in the breakdown. 4</p>
|
||
<p>There's beauty in the breakdown. 5</p>
|
||
<p>There's beauty in the breakdown. 6</p>
|
||
<p>There's beauty in the breakdown. 7</p>
|
||
<p>There's beauty in the breakdown. 8</p>
|
||
<p>There's beauty in the breakdown. 9</p>
|
||
<p>There's beauty in the breakdown. 10</p>
|
||
<p>There's beauty in the breakdown. 11</p>
|
||
<p>There's beauty in the breakdown. 12</p>
|
||
<p>There's beauty in the breakdown. 13</p>
|
||
<p>There's beauty in the breakdown. 14</p>
|
||
<p>There's beauty in the breakdown. 15</p>
|
||
<p>There's beauty in the breakdown. 16</p>
|
||
<p>There's beauty in the breakdown. 17</p>
|
||
<p>There's beauty in the breakdown. 18</p>
|
||
<p>There's beauty in the breakdown. 19</p>
|
||
<p>There's beauty in the breakdown. 20</p>
|
||
<p>There's beauty in the breakdown. 21</p>
|
||
<p>There's beauty in the breakdown. 22</p>
|
||
<!-- <p>There's beauty in the breakdown. 23</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 24</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 25</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 26</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 27</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 28</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 29</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 30</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 31</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 32</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 33</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 34</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 35</p> -->
|
||
</div>
|
||
<div id="content-column" class="clearfix">
|
||
<p>There's beauty in the breakdown. 0</p>
|
||
<p>There's beauty in the breakdown. 1</p>
|
||
<p>There's beauty in the breakdown. 2</p>
|
||
<p>There's beauty in the breakdown. 3</p>
|
||
<p>There's beauty in the breakdown. 4</p>
|
||
<p>There's beauty in the breakdown. 5</p>
|
||
<p>There's beauty in the breakdown. 6</p>
|
||
<p>There's beauty in the breakdown. 7</p>
|
||
<p>There's beauty in the breakdown. 8</p>
|
||
<p>There's beauty in the breakdown. 9</p>
|
||
<p>There's beauty in the breakdown. 10</p>
|
||
<p>There's beauty in the breakdown. 11</p>
|
||
<p>There's beauty in the breakdown. 12</p>
|
||
<p>There's beauty in the breakdown. 13</p>
|
||
<p>There's beauty in the breakdown. 14</p>
|
||
<p>There's beauty in the breakdown. 15</p>
|
||
<p>There's beauty in the breakdown. 16</p>
|
||
<p>There's beauty in the breakdown. 17</p>
|
||
<p>There's beauty in the breakdown. 18</p>
|
||
<p>There's beauty in the breakdown. 19</p>
|
||
<p>There's beauty in the breakdown. 20</p>
|
||
<p>There's beauty in the breakdown. 21</p>
|
||
<p>There's beauty in the breakdown. 22</p>
|
||
<!-- <p>There's beauty in the breakdown. 23</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 24</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 25</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 26</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 27</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 28</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 29</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 30</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 31</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 32</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 33</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 34</p> -->
|
||
<!-- <p>There's beauty in the breakdown. 35</p> -->
|
||
</div>
|
||
</div>
|
||
|
||
... | ... | |
})
|
||
.bind("move_node.jstree", node_moved);
|
||
});
|
||
|
||
$(document).ajaxSend(function() {
|
||
$('#spinner').show();
|
||
}).ajaxStop(function() {
|
||
$('#spinner').hide();
|
||
});
|
||
-->
|
||
</script>
|
templates/webpages/requirement_spec_item/_section_form.html | ||
---|---|---|
[%- USE HTML %][%- USE L %][%- USE LxERP %]
|
||
[%- SET id_base="section-form-" _ HTML.escape(id) %]
|
||
[%- IF title %]
|
||
<div class="listtop">[%- HTML.escape(title) %]</div>
|
||
[%- END -%]
|
||
[%- SET id_base="section-form" %]
|
||
<div id="[% id_base %]">
|
||
<h1>[%- LxERP.t8("Edit section #1", SELF.item.fb_number) %]</h1>
|
||
|
||
<form id="[% id_base %]">
|
||
[% L.hidden_tag("requirment_spec_id", SELF.item.requirement_spec_id, id=(id_base _ "-requirement-spec-id")) %]
|
||
<form>
|
||
[% L.hidden_tag("requirement_spec_id", SELF.item.requirement_spec_id, id=(id_base _ "-requirement-spec-id")) %]
|
||
[% L.hidden_tag("id", SELF.item.id, id=(id_base _ "-requirement-spec-item-id")) %]
|
||
|
||
<p>
|
||
[%- LxERP.t8("Title") %]:<br>
|
||
[% L.input_tag("title", SELF.item.title, id=(id_base _ "-title")) %]
|
||
</p>
|
||
<p>
|
||
[%- LxERP.t8("Title") %]:<br>
|
||
[% L.input_tag("title", SELF.item.title, id=(id_base _ "-title")) %]
|
||
</p>
|
||
|
||
<p>
|
||
[%- LxERP.t8("Description") %]:<br>
|
||
[% L.textarea_tag("description", SELF.item.description, id=(id_base _ "-title"), rows=8, cols=80) %]
|
||
</p>
|
||
<p>
|
||
[%- LxERP.t8("Description") %]:<br>
|
||
[% L.textarea_tag("description", SELF.item.description, id=(id_base _ "-description"), rows=8, cols=80) %]
|
||
</p>
|
||
|
||
<p>
|
||
[% L.button_tag("submit_section_form('" _ HTML.escape(id) _ "')", LxERP.t8("Save")) %]
|
||
[% L.button_tag("cancel_section_form('" _ HTML.escape(id) _ "')", LxERP.t8("Cancel")) %]
|
||
</p>
|
||
</form>
|
||
<p>
|
||
[% L.button_tag("submit_section_form()", LxERP.t8("Save")) %]
|
||
<a href="#" onclick="cancel_section_form()">[% LxERP.t8("Cancel") %]</a>
|
||
</p>
|
||
</form>
|
||
</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) -%]
|
||
</h1>
|
||
|
||
[% IF requirement_spec_item.description %]
|
||
<div class="section-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 %]
|
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 -%]">
|
||
[%#- link_to_remote LxERP.t8("FIXME no_function_blocks_have_been_created_for_this_section_yet) + " " + t(:create_a_function_block_now"),
|
||
:url => new_requirement_spec_requirement_spec_item_url(requirement_spec_item.requirement_spec,
|
||
:requirement_spec_item_id => requirement_spec_item.id),
|
||
:method => :get,
|
||
:update => "new_subitem_form",
|
||
:loading => "$('new_subitem_link').hide();" -%]
|
||
</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 -%]
|
||
|
|
||
[%- LxERP.t8("Risk") -%]: [%- requirement_spec_item.requirement_spec_risk.description IF requirement_spec_item.requirement_spec_risk -%]
|
||
|
|
||
[%- LxERP.t8("Effort") -%]: [%#- render :partial => 'requirement_spec_items/time_estimation_item', :locals => { :item => requirement_spec_item } -%]
|
||
</span>
|
||
|
||
</div>
|
||
</div>
|
||
</li>
|
Auch abrufbar als: Unified diff
Pflichtenhefte bearbeiten