Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 1f592a0f

Von Moritz Bunkus vor mehr als 10 Jahren hinzugefügt

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

Pflichtenhefte: Auflisten von Abschnitten

Unterschiede anzeigen:

SL/Controller/RequirementSpecItem.pm
14 14

  
15 15
use Rose::Object::MakeMethods::Generic
16 16
(
17
 scalar => [ qw(requirement_spec item) ],
17
  scalar => [ qw(requirement_spec item visible_item visible_section) ],
18 18
);
19 19

  
20 20
# __PACKAGE__->run_before('load_requirement_spec');
......
24 24
# actions
25 25
#
26 26

  
27
sub action_ajax_list {
28
  my ($self) = @_;
29

  
30
  my $js = SL::ClientJS->new;
31

  
32
  if (!$::form->{clicked_id}) {
33
    # Clicked on "sections" in the tree. Do nothing.
34
    return $self->render($js);
35
  }
36

  
37
  $self->init_visible_section($::form->{current_content_id}, $::form->{current_content_type});
38
  $self->item(SL::DB::RequirementSpecItem->new(id => $::form->{clicked_id})->load->get_section);
39

  
40
  if (!$self->visible_section || ($self->visible_section->id != $self->item->id)) {
41
    my $html = $self->render('requirement_spec_item/_section', { output => 0 }, requirement_spec_item => $self->item);
42
    $js->html('#column-content', $html)
43
       ->val('#current_content_type', $self->item->get_type)
44
       ->val('#current_content_id', $self->item->id);
45
  }
46

  
47
  $self->render($js);
48
}
49

  
27 50
sub action_new {
28 51
  my ($self) = @_;
29 52

  
......
108 131
  return join "\n", (split m/\n/, $@)[0..4];
109 132
}
110 133

  
134
sub init_visible_section {
135
  my ($self, $content_id, $content_type) = @_;
136

  
137
  return undef unless $content_id;
138
  return undef unless $content_type =~ m/section|function-block/;
139

  
140
  $self->visible_item(SL::DB::RequirementSpecItem->new(id => $content_id)->load);
141
  return $self->visible_section($self->visible_item->get_section);
142
}
143

  
111 144
1;
SL/Controller/RequirementSpecTextBlock.pm
48 48
    my $html        = $self->render('requirement_spec_text_block/ajax_list', { output => 0 }, TEXT_BLOCKS => $text_blocks, output_position => $new_where);
49 49

  
50 50
    $js->html('#column-content', $html)
51
       ->val('#current_content_type', 'text-blocks-' . (0 == $new_where ? 'front' : 'back'))
52
       ->val('#current_content_id',   $::form->{clicked_id});
51 53
  }
52 54

  
53 55
  $self->render($js);
SL/DB/RequirementSpecItem.pm
37 37
  return [ sort { $a->position <=> $b->position } @{ $self->children } ];
38 38
}
39 39

  
40
sub get_section {
41
  my ($self) = @_;
42

  
43
  $self = $self->parent while $self->parent_id;
44

  
45
  return $self;
46
}
47

  
48
sub get_type {
49
  my ($self) = @_;
50

  
51
  return 'section' if !$self->parent_id;
52
  return $self->parent->parent_id ? 'sub-function-block' : 'function-block';
53
}
54

  
40 55
1;
SL/Presenter/RequirementSpecItem.pm
13 13
  my ($self, $item, %params) = @_;
14 14

  
15 15
  my @children = map { $self->requirement_spec_item_jstree_data($_, %params) } @{ $item->sorted_children };
16
  my $type     = !$item->parent_id ? 'section' : 'functionblock';
16
  my $type     = !$item->parent_id ? 'section' : 'function-block';
17 17

  
18 18
  return {
19
    data     => join(' ', map { $_ || '' } ($item->fb_number, $item->title)),
19
    data     => join(' ', map { $_ || '' } ($item->fb_number, $item->title, '<' . $item->id . '>')),
20 20
    metadata => { id =>         $item->id, type => $type },
21
    attr     => { id => "fb-" . $item->id, href => $params{href} || '#' },
21
    attr     => { id => "fb-" . $item->id, href => $params{href} || '#', class => $type . '-context-menu' },
22 22
    children => \@children,
23 23
  };
24 24
}
css/requirement_spec.css
25 25
.section-empty-description {
26 26
  color: #bbb;
27 27
}
28

  
29
.function-block {
30
  border-bottom: 1px solid #bbb;
31
}
32

  
33
.section-description-heading {
34
  font-weight: bold;
35
}
36

  
37
.section-description {
38
  color: #000;
39
  background: rgb(235, 235, 235);
40
  border: 1px solid #ccc;
41
  margin-bottom: 15px;
42
}
43

  
44
.sub-function-block {
45
  border-bottom: 1px solid #ccc;
46
}
47

  
48
.sub-function-block-container {
49
  margin: 10px 0px 10px 20px;
50
  border: 1px solid #ccc;
51
}
52

  
53
.sub-function-block-header {
54
  padding: 5px;
55
  font-weight: bold;
56
  color: #fff;
57
  background: #ccc;
58
}
js/requirement_spec.js
1 1
/* Functions used for the requirement specs tree view */
2 2

  
3
// -----------------------------------------------------------------------------
4
// ------------------------------ the tree itself ------------------------------
5
// -----------------------------------------------------------------------------
6

  
3 7
function requirement_spec_tree_check_move(data) {
4 8
  var dragged_type = data.o.data('type');
5 9
  var dropped_type = data.r.data('type');
......
31 35
  if ((dropped_type == "text-block") || (dropped_type == "text-blocks-front") || (dropped_type == "text-blocks-back"))
32 36
    return false;
33 37

  
34
  var dropped_depth = dropped_type == "sections" ? 0 : dropped_type == "section" ? 1 : data.r.parent().parent().data('type') != "functionblock" ? 2 : 3;
38
  var dropped_depth = dropped_type == "sections" ? 0 : dropped_type == "section" ? 1 : data.r.parent().parent().data('type') != "function-block" ? 2 : 3;
35 39
  if ((data.p == "inside") || (data.p == "last"))
36 40
    dropped_depth++;
37 41

  
......
73 77
  if (!type)
74 78
    return;
75 79

  
76
  if ('sections' ==  type) {
77
    $('#current_content_type').val('sections');
78
    $('#current_content_id').val('');
79
    return;
80
  }
81

  
82 80
  var url = 'controller.pl?action='
83 81
  $.get('controller.pl', {
84
    action:               (/^text-block/ ? 'RequirementSpecTextBlock' : 'RequirementSpecItem') + '/ajax_list.js',
82
    action:               (/^text-block/.test(type) ? 'RequirementSpecTextBlock' : 'RequirementSpecItem') + '/ajax_list.js',
85 83
    requirement_spec_id:  $('#requirement_spec_id').val(),
86 84
    current_content_type: $('#current_content_type').val(),
87 85
    current_content_id:   $('#current_content_id').val(),
88 86
    clicked_type:         type,
89 87
    clicked_id:           node.data('id')
90
  }, function(new_data) {
91
    $('#current_content_type').val(type);
92
    $('#current_content_id').val(node.data('id'));
93
    eval_json_result(new_data);
94
  });
95
}
96

  
97
function section_form_requested(data) {
98
  $('#new-section-button').removeAttr('disabled');
99
  if (data.status == "ok")
100
    $('#content-column').html(data.html);
101
  else
102
    alert('oh yeah response: ' + data.status + "\n" + data.error);
103
}
104

  
105
function section_form_submitted(data) {
106
  alert('oh yeah response: ' + data.status);
107
}
108

  
109
function server_side_error(things_to_enable) {
110
  alert('Server-side error.');
111
  if (things_to_enable)
112
    $(things_to_enable).removeAttr('disabled');
88
  }, eval_json_result);
113 89
}
114 90

  
115
function new_section_form() {
116
  $('#new-section-button').attr('disabled', 'disabled');
117
  $.ajax({
118
    type: 'POST',
119
    url: 'controller.pl',
120
    data: 'action=RequirementSpecItem/new.json&requirement_spec_id=' + $('#requirement_spec_id').val() + '&item_type=section',
121
    success: section_form_requested,
122
    error: function() { server_side_error('#new-section-button'); }
123
  });
124
}
125

  
126
function submit_section_form(id) {
127
  $.ajax({
128
    type: 'POST',
129
    url: 'controller.pl',
130
    data: 'action=RequirementSpecItem/create.json&' + $('section-form-' + id).serialize(),
131
    success: section_form_submitted
132
  });
133
}
134

  
135
function cancel_section_form(id) {
136
  $('#content-column').html('intentionally empty');
137
}
91
// -------------------------------------------------------------------------
92
// ------------------------------ text blocks ------------------------------
93
// -------------------------------------------------------------------------
138 94

  
139 95
function find_text_block_id(clicked_elt) {
140 96
  // console.log("id: " + $(clicked_elt).attr('id'));
......
209 165
  if (id)
210 166
    $('#text-block-' + id).show();
211 167
}
168

  
169
// --------------------------------------------------------------------------------
170
// ------------------------------ sections and items ------------------------------
171
// --------------------------------------------------------------------------------
172

  
173
function find_item_id(clicked_elt) {
174
  console.log("clicked id: " + $(clicked_elt).attr('id'));
175
  var id     = $(clicked_elt).attr('id');
176
  var result = /^(function-block|function-block-content|sub-function-block|sub-function-block-content|section|section-header)-(\d+)$/.exec(id);
177
  if (result) {
178
    console.log("find_item_id: case 1: " + result[2]);
179
    return result[2];
180
  }
181

  
182
  id = $(clicked_elt).closest("[id*=fb-]").attr('id')
183
  if (/^fb-\d+$/.test(id)) {
184
    console.log("find_item_id: case 2: " + id.substr(3));
185
    return id.substr(3) * 1;
186
  }
187

  
188
  console.log("find_item_id: case undef");
189
  return undefined;
190
}
191

  
192
function standard_item_ajax_call(key, opt, other_data) {
193
  var data = {
194
    action:               "RequirementSpecTextBlock/ajax_" + key,
195
    requirement_spec_id:  $('#requirement_spec_id').val(),
196
    id:                   find_item_id(opt.$trigger),
197
    current_content_type: $('#current_content_type').val(),
198
    current_content_id:   $('#current_content_id').val()
199
  };
200

  
201
  console.log("I would normally POST the following now:");
202
  console.log(data);
203
  // $.post("controller.pl", $.extend(data, other_data || {}), eval_json_result);
204

  
205
  return true;
206
}
207

  
208
function disable_edit_item_commands(key, opt) {
209
  return false; // find_item_id(opt.$trigger) == undefined;
210
}
locale/de/all
167 167
  'Add and edit units'          => 'Einheiten erfassen und bearbeiten',
168 168
  'Add bank account'            => 'Bankkonto erfassen',
169 169
  'Add custom variable'         => 'Benutzerdefinierte Variable erfassen',
170
  'Add function block'          => 'Funktionsblock hinzufügen',
170 171
  'Add link: select records to link with' => 'Verknüpfungen hinzufügen: zu verknüpfende Belege auswählen',
171 172
  'Add linked record'           => 'Verknüpften Beleg hinzufügen',
172 173
  'Add links'                   => 'Verknüpfungen hinzufügen',
......
174 175
  'Add new custom variable'     => 'Neue benutzerdefinierte Variable erfassen',
175 176
  'Add note'                    => 'Notiz erfassen',
176 177
  'Add printer'                 => 'Drucker hinzufügen',
178
  'Add section'                 => 'Abschnitt hinzufügen',
179
  'Add sub function block'      => 'Unterfunktionsblock hinzufügen',
177 180
  'Add text block'              => 'Textblock erfassen',
178 181
  'Add unit'                    => 'Einheit hinzuf&uuml;gen',
179 182
  'Address'                     => 'Adresse',
......
709 712
  'Delete drafts'               => 'Entwürfe löschen',
710 713
  'Delete links'                => 'Verknüpfungen löschen',
711 714
  'Delete profile'              => 'Profil löschen',
712
  'Delete section'              => 'Abschnitt löschen',
713 715
  'Delete text block'           => 'Textblock löschen',
714 716
  'Delete transaction'          => 'Buchung löschen',
715 717
  'Deleted'                     => 'Gelöscht',
......
889 891
  'Edit requirement spec status' => 'Pflichtenheftstatus bearbeiten',
890 892
  'Edit requirement spec type'  => 'Pflichtenhefttypen bearbeiten',
891 893
  'Edit risk level'             => 'Risikograd bearbeiten',
892
  'Edit section'                => 'Abschnitt bearbeiten',
893 894
  'Edit section #1'             => 'Abschnitt #1 bearbeiten',
894 895
  'Edit templates'              => 'Vorlagen bearbeiten',
895 896
  'Edit text block'             => 'Textblock bearbeiten',
......
1438 1439
  'No default currency'         => 'Keine Standardwährung',
1439 1440
  'No delivery term has been created yet.' => 'Es wurden noch keine Lieferbedingungen angelegt',
1440 1441
  'No department has been created yet.' => 'Es wurde noch keine Abteilung erfasst.',
1441
  'No description has been entered yet.' => 'Es wurde noch keine Beschreibung eingegeben.',
1442 1442
  'No dunnings have been selected for printing.' => 'Es wurden keine Mahnungen zum Drucken ausgew&auml;hlt.',
1443 1443
  'No file has been uploaded yet.' => 'Es wurde noch keine Datei hochgeladen.',
1444 1444
  'No function blocks have been created yet.' => 'Es wurden noch keine Funktionsblöcke angelegt.',
......
1457 1457
  'No requirement spec statuses has been created yet.' => 'Es wurden noch keine Pflichtenheftstatus angelegt.',
1458 1458
  'No requirement spec type has been created yet.' => 'Es wurden noch keine Pflichtenhefttypen angelegt.',
1459 1459
  'No risks level has been created yet.' => 'Es wurden noch keine Risikograde angelegt.',
1460
  'No sections have been created so far.' => '',
1460 1461
  'No shipto selected to delete' => 'Keine Lieferadresse zum Löschen ausgewählt',
1461 1462
  'No summary account'          => 'Kein Sammelkonto',
1462 1463
  'No text blocks have been created for this position.' => 'Für diese Position wurden noch keine Textblöcke angelegt.',
......
1676 1677
  'Postscript'                  => 'Postscript',
1677 1678
  'Posustva_coa'                => 'USTVA Kennz.',
1678 1679
  'Pre-defined Texts'           => 'Vordefinierte Textblöcke',
1680
  'Preamble'                    => 'Einleitung',
1679 1681
  'Preferences'                 => 'Einstellungen',
1680 1682
  'Preferences saved!'          => 'Einstellungen gespeichert!',
1681 1683
  'Prefix for the new bins\' names' => 'Namenspr&auml;fix f&uuml;r die neuen Lagerpl&auml;tze',
templates/webpages/requirement_spec/show.html
24 24

  
25 25
  <div id="column-content">
26 26
   [%- IF SELF.requirement_spec_item -%]
27
    [%- INCLUDE 'requirement_spec_item/_single_section.html' requirement_spec_item=SELF.requirement_spec_item -%]
27
    [%- INCLUDE 'requirement_spec_item/_section.html' requirement_spec_item=SELF.requirement_spec_item -%]
28 28
   [%- ELSE -%]
29
    no section
30
    [%#- render :partial => 'requirement_spec_items/no_section' -%]
29
    [%- INCLUDE 'requirement_spec_item/_no_section.html' -%]
31 30
   [%- END -%]
32 31
  </div>
33 32
 </div>
......
48 47

  
49 48
       { data:     [% JSON.json(LxERP.t8("Sections")) %],
50 49
         metadata: { type: "sections" },
51
         attr:     { id: "sections" },
50
         attr:     { id: "sections", class: "section-context-menu" },
52 51
         children: [
53 52

  
54 53
[% FOREACH section = SELF.requirement_spec.sections %]
......
108 107
  return true;
109 108
}
110 109

  
110
function ask_delete_item(key, opt) {
111
  if (confirm("[% LxERP.t8("Are you sure?") %]"))
112
    standard_item_ajax_call(key, opt);
113
  return true;
114
}
115

  
111 116
$(function(){
112
    $.contextMenu({
113
        selector: '.text-block-context-menu',
114
        items: {
115
          add:    { name: "[% LxERP.t8('Add text block') %]", icon: "add", callback: standard_text_block_ajax_call },
116
          edit:   { name: "[% LxERP.t8('Edit text block') %]", icon: "edit", callback: standard_text_block_ajax_call, disabled: disable_edit_text_block_commands },
117
          delete: { name: "[% LxERP.t8('Delete text block') %]", icon: "delete", callback: ask_delete_text_block, disabled: disable_edit_text_block_commands },
118
          sep1:   "---------",
119
          copy:   { name: "[% LxERP.t8('Copy') %]", icon: "copy", disabled: disable_edit_text_block_commands },
120
          paste:  { name: "[% LxERP.t8('Paste') %]", icon: "paste", disabled: disable_edit_text_block_commands }
121
        }
122
      });
117
  $.contextMenu({
118
    selector: '.text-block-context-menu',
119
    items: {
120
      add:    { name: "[% LxERP.t8('Add text block') %]",    icon: "add",    callback: standard_text_block_ajax_call },
121
      edit:   { name: "[% LxERP.t8('Edit text block') %]",   icon: "edit",   callback: standard_text_block_ajax_call, disabled: disable_edit_text_block_commands },
122
      delete: { name: "[% LxERP.t8('Delete text block') %]", icon: "delete", callback: ask_delete_text_block,         disabled: disable_edit_text_block_commands },
123
      sep1:   "---------",
124
      copy:   { name: "[% LxERP.t8('Copy') %]",              icon: "copy",  disabled: disable_edit_text_block_commands },
125
      paste:  { name: "[% LxERP.t8('Paste') %]",             icon: "paste", disabled: disable_edit_text_block_commands }
126
    }
127
  });
128

  
129

  
130
  $.contextMenu({
131
    selector: '.section-context-menu',
132
    items: {
133
      add_section:        { name: "[% LxERP.t8('Add section') %]",        icon: "add",    callback: standard_item_ajax_call },
134
      add_function_block: { name: "[% LxERP.t8('Add function block') %]", icon: "add",    callback: standard_text_block_ajax_call },
135
      sep1:               "---------",
136
      edit:               { name: "[% LxERP.t8('Edit') %]",               icon: "edit",   callback: standard_item_ajax_call, disabled: disable_edit_item_commands },
137
      delete:             { name: "[% LxERP.t8('Delete') %]",             icon: "delete", callback: ask_delete_item,         disabled: disable_edit_item_commands },
138
      sep2:               "---------",
139
      copy:               { name: "[% LxERP.t8('Copy') %]",               icon: "copy",  disabled: disable_edit_item_commands },
140
      paste:              { name: "[% LxERP.t8('Paste') %]",              icon: "paste", disabled: disable_edit_item_commands }
141
    }
142
  });
143

  
144
  $.contextMenu({
145
    selector: '.function-block-context-menu,.sub-function-block-context-menu',
146
    items: {
147
      new_item:     { name: "[% LxERP.t8('Add function block') %]",     icon: "add", callback: standard_item_ajax_call },
148
      new_sub_item: { name: "[% LxERP.t8('Add sub function block') %]", icon: "add", callback: standard_item_ajax_call },
149
      sep1:         "---------",
150
      edit:         { name: "[% LxERP.t8('Edit') %]",   icon: "edit",   callback: standard_item_ajax_call, disabled: disable_edit_item_commands },
151
      delete:       { name: "[% LxERP.t8('Delete') %]", icon: "delete", callback: standard_item_ajax_call, disabled: disable_edit_item_commands },
152
      sep2:         "---------",
153
      copy:         { name: "[% LxERP.t8('Copy') %]",  icon: "copy",  disabled: disable_edit_item_commands },
154
      paste:        { name: "[% LxERP.t8('Paste') %]", icon: "paste", disabled: disable_edit_item_commands }
155
    }
156
  });
123 157
});
124 158

  
159
function edit_section_header() {
160
  $.post("controller.pl?action=RequirementSpecItem/edit_section&id=" + encodeURIComponent($('#active_section_id').val()), function(data) {
161
    var header = $('#section-header');
162
    header.data('old-elements', header.children().detach());
163
    header.html(data);
164
  });
165
}
166

  
167
function submit_section_form() {
168
  $.post("controller.pl?action=RequirementSpecItem/update_section&id=" + $('#section-form form').serialize(), function(data) {
169
    var header = $('#section-header');
170
    header.removeData('old-elements');
171
    header.html(data['header_html']);
172
    $('#tree').jstree('rename_node', '#fb-' + data['id'], data['node_name']);
173
  });
174
}
175

  
176
function cancel_section_form() {
177
  var header = $('#section-header');
178
  header.empty();
179
  header.append(header.data('old-elements'));
180
  header.removeData('old-elements');
181
}
182

  
183

  
184

  
185

  
186

  
187

  
125 188
  -->
126 189
</script>
templates/webpages/requirement_spec_item/_function_block.html
1
[%- USE HTML -%][%- USE LxERP -%][%- USE P -%][%- USE L -%]
2
<div id="function-block-[% requirement_spec_item.id %]" class="function-block">
3

  
4
 <div id="function-block-content-[%- requirement_spec_item.id -%]" class="function-block-content[%- IF requirement_spec_item.flagged -%] flagged[%- END -%] function-block-context-menu">
5

  
6
  [% INCLUDE 'requirement_spec_item/_function_block_content_top.html' id_prefix='' %]
7

  
8
  <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 -%]>
9
   <div class="sub-function-block-header" id="sub-function-block_header_[%- requirement_spec_item.id -%]">
10
    [%- LxERP.t8("Sub function blocks") -%]
11
   </div>
12
   [%- FOREACH sub_function_block = requirement_spec_item.children -%]
13
    [%- INCLUDE 'requirement_spec_item/_sub_function_block.html' requirement_spec_item=sub_function_block -%]
14
   [%- END -%]
15
  </div>
16

  
17
  [% INCLUDE 'requirement_spec_item/_function_block_content_bottom.html' id_prefix='' %]
18
 </div>
19
</div>
templates/webpages/requirement_spec_item/_function_block_content_bottom.html
1
[%- USE LxERP -%][%- USE P -%]<div id="[% id_prefix %]function-block-content-bottom-[% requirement_spec_item.id %]" class="smaller" style="text-align:right">
2
 [%- IF requirement_spec_item.dependencies.size -%]
3
 <span class="gray">
4
  [%- LxERP.t8("Dependencies") -%]: [%- P.requirement_spec_item_dependency_list(requirement_spec_item.dependencies) -%]
5
 </span><br>
6
 [%- END -%]
7
 <span class="gray">
8
  [%- LxERP.t8("Complexity") -%]: [%- requirement_spec_item.requirement_spec_complexity.description IF requirement_spec_item.requirement_spec_complexity -%]
9
  &nbsp; | &nbsp;
10
  [%- LxERP.t8("Risk") -%]: [%- requirement_spec_item.requirement_spec_risk.description IF requirement_spec_item.requirement_spec_risk -%]
11
  &nbsp; | &nbsp;
12
  [%- LxERP.t8("Effort") -%]: [%#- render :partial => 'requirement_spec_items/time_estimation_item', :locals => { :item => requirement_spec_item } -%]
13
 </span>
14

  
15
</div>
templates/webpages/requirement_spec_item/_function_block_content_top.html
1
[%- USE HTML -%][%- USE L -%]<div id="[% id_prefix %]function-block-content-top-[% requirement_spec_item.id %]">
2
 <b>[%- HTML.escape(requirement_spec_item.fb_number) -%]</b> &lt;[% requirement_spec_item.id %]&gt;
3
 [%- L.simple_format(requirement_spec_item.description) -%]
4
</div>
templates/webpages/requirement_spec_item/_no_section.html
1
[%- USE LxERP -%]
2
<span class="section-context-menu">
3
 [%- LxERP.t8("No sections have been created so far.") %]
4
 [% LxERP.t8("Create one from the context menu by right-clicking on this text.") %]
5
</span>
templates/webpages/requirement_spec_item/_section.html
1
[%- USE HTML -%][%- USE LxERP -%][%- USE L -%]
2
<div id="full-section-content">
3
 <div class="section-context-menu" id="section-header-[% requirement_spec_item.id %]">
4
  [%- INCLUDE 'requirement_spec_item/_section_header.html' %]
5
 </div>
6

  
7
 <div id="section-list-empty" class="section-context-menu"[% IF requirement_spec_item.children.size %] style="display: none"[% END %]>
8
  [%- LxERP.t8("No function blocks have been created yet.") %]
9
  [% LxERP.t8("Create one from the context menu by right-clicking on this text.") %]
10
 </div>
11

  
12
 <div id="section-list" class="section">
13
  [%- FOREACH function_block = requirement_spec_item.children -%]
14
   [%- INCLUDE 'requirement_spec_item/_function_block.html' requirement_spec_item=function_block -%]
15
  [%- END -%]
16
 </div>
17
</div>
templates/webpages/requirement_spec_item/_section_header.html
1 1
[%- USE HTML -%][%- USE L -%][%- USE LxERP -%]
2 2
<h1>
3
 [%- HTML.escape(requirement_spec_item.fb_number) %]: [% HTML.escape(requirement_spec_item.title) -%]
3
 [%- HTML.escape(requirement_spec_item.fb_number) %]: &lt;[% requirement_spec_item.id %]&gt;
4
 [% IF requirement_spec_item.title %]
5
  [% HTML.escape(requirement_spec_item.title) %]
6
 [% ELSE %]
7
  <div class="dimmed-text">
8
   [%- LxERP.t8("No text has been entered yet.") %]
9
  </div>
10
 [% END %]
4 11
</h1>
5 12

  
6
[% IF requirement_spec_item.description %]
7
 <div class="section-description">
13
<div class="section-description">
14
 <div class="section-description-heading">[%- LxERP.t8("Preamble") %]</div>
15
 [% IF requirement_spec_item.description %]
8 16
  [%- L.simple_format(requirement_spec_item.description) -%]
9
 </div>
10
[%- ELSE %]
11
 <div class="section-empty-description">[%- LxERP.t8("No description has been entered yet.") %]</div>
12
[%- END %]
17
 [%- ELSE %]
18
  <span class="dimmed-text">[%- LxERP.t8("No text has been entered yet.") %]</span>
19
 [%- END %]
20
</div>
templates/webpages/requirement_spec_item/_single_section.html
1
[%- USE HTML -%][%- USE LxERP -%][%- USE L -%]
2
<div class="section-context-menu" id="section-header">
3
 [%- INCLUDE 'requirement_spec_item/_section_header.html' %]
4
</div>
5

  
6
[%- L.hidden_tag('active_section_id', requirement_spec_item.id) -%]
7

  
8
<ul id="section" class="section function-block-context-menu">
9
  [%- FOREACH subitem = requirement_spec_item.children -%]
10
    [%- INCLUDE 'requirement_spec_item/_single_subitem.html' requirement_spec_item=subitem -%]
11
  [%- END -%]
12
</ul>
13

  
14
<div id="new_subitem_form" class="subitem-form clearfix">
15
</div>
16
<div id="new_subitem_link" class="highlight-box" style="[%- 'display:none' IF requirement_spec_item.children.size -%]">
17
 [%- LxERP.t8("No function blocks have been created yet.") %]
18
</div>
19

  
20
<script type="text/javascript">
21
 <!--
22
$(function(){
23
    $.contextMenu({
24
        selector: '.section-context-menu',
25
        callback: function(key, options) {
26
            var m = "clicked: " + key;
27
            window.console && console.log(m) || alert(m);
28
        },
29
        items: {
30
          edit:   { name: "[% LxERP.t8('Edit section') %]", icon: "edit", callback: edit_section_header },
31
          delete: { name: "[% LxERP.t8('Delete section') %]", icon: "delete" },
32
          sep1:   "---------",
33
          copy:   { name: "[% LxERP.t8('Copy') %]", icon: "copy" },
34
          paste:  { name: "[% LxERP.t8('Paste') %]", icon: "paste" }
35
        }
36
      });
37

  
38
    $.contextMenu({
39
        selector: '.function-block-context-menu',
40
        callback: function(key, options) {
41
            var m = "clicked: " + key;
42
            window.console && console.log(m) || alert(m);
43
        },
44
        items: {
45
          new_item:     { name: "[% LxERP.t8('New function block') %]",     icon: "add"},
46
          new_sub_item: { name: "[% LxERP.t8('New sub function block') %]", icon: "add"},
47
          sep1:   "---------",
48
          edit:   { name: "[% LxERP.t8('Edit') %]",   icon: "edit"},
49
          delete: { name: "[% LxERP.t8('Delete') %]", icon: "delete"},
50
          sep2:   "---------",
51
          copy:   { name: "[% LxERP.t8('Copy') %]", icon: "copy" },
52
          paste:  { name: "[% LxERP.t8('Paste') %]", icon: "paste" }
53
        }
54
    });
55

  
56
    $('.section-context-menu').on('click', function(e){
57
        console.log('clicked', this);
58
    });
59
});
60

  
61
function edit_section_header() {
62
  $.post("controller.pl?action=RequirementSpecItem/edit_section&id=" + encodeURIComponent($('#active_section_id').val()), function(data) {
63
    var header = $('#section-header');
64
    header.data('old-elements', header.children().detach());
65
    header.html(data);
66
  });
67
}
68

  
69
function submit_section_form() {
70
  $.post("controller.pl?action=RequirementSpecItem/update_section&id=" + $('#section-form form').serialize(), function(data) {
71
    var header = $('#section-header');
72
    header.removeData('old-elements');
73
    header.html(data['header_html']);
74
    $('#tree').jstree('rename_node', '#fb-' + data['id'], data['node_name']);
75
  });
76
}
77

  
78
function cancel_section_form() {
79
  var header = $('#section-header');
80
  header.empty();
81
  header.append(header.data('old-elements'));
82
  header.removeData('old-elements');
83
}
84
-->
85
</script>
templates/webpages/requirement_spec_item/_single_subitem.html
1
[%- USE HTML -%][%- USE LxERP -%][%- USE P -%]
2
<li id="subitem_[%- requirement_spec_item.id -%]" class="subitem">
3

  
4
  <div id="subitem_content_[%- requirement_spec_item.id -%]" class="subitem-content[%- IF requirement_spec_item.flagged -%] flagged[%- END -%]">
5

  
6
    [%#- IF !@requirement_spec.project.nil? -%]
7
     [%#- link_to image_tag("chronometer.png"), account_time_requirement_spec_requirement_spec_item_path(requirement_spec_item.requirement_spec, requirement_spec_item) -%]
8
    [%#- END -%]
9
    [%#- link_to_new_sub(requirement_spec_item.parent) -%]
10
    [%#- link_to_remote image_tag("new_subsub.png"),
11
                       :url       => new_requirement_spec_requirement_spec_item_url(requirement_spec_item.requirement_spec, :requirement_spec_item_id => requirement_spec_item.id),
12
                       :method    => :get,
13
                       :condition => "check_for_editbox()",
14
                       :update    => "new_subsubitem_form_#{requirement_spec_item.id}" -%]
15

  
16
    <b>[%- HTML.escape(requirement_spec_item.fb_number) -%]</b>
17
    [%- HTML.escape(requirement_spec_item.description) -%]
18

  
19
    <div class="subsubitem-container" id="subsubitem_container_[%- requirement_spec_item.id -%]">
20
     <div class="subsubitem-header" id="subsubitem_header_[%- requirement_spec_item.id -%]"[%- IF !requirement_spec_item.children.size -%] style="display: none"[%- END -%]>
21
      [%- LxERP.t8("Sub function blocks") -%]
22
     </div>
23
      [%- IF requirement_spec_item.children.size -%]
24
        [%- FOREACH subsubitem = requirement_spec_item.children -%]
25
          [%#- render :partial => "requirement_spec_items/single_subsubitem", :locals => {:requirement_spec_item => subsubitem} -%]
26
        [%- END -%]
27
      [%- END -%]
28
    </div>
29

  
30
    <div id="new_subsubitem_form_[%- requirement_spec_item.id -%]" class="subsubitem_form"></div>
31

  
32
    <div class="smaller" style="text-align:right">
33
      [%- IF requirement_spec_item.dependencies.size -%]
34
        <span class="gray">
35
          [%- LxERP.t8("Dependencies") -%]: [%- P.requirement_spec_item_dependency_list(requirement_spec_item.dependencies) -%]
36
        </span><br>
37
      [%- END -%]
38
      <span class="gray">
39
        [%- LxERP.t8("Complexity") -%]: [%- requirement_spec_item.requirement_spec_complexity.description IF requirement_spec_item.requirement_spec_complexity -%]
40
        &nbsp; | &nbsp;
41
        [%- LxERP.t8("Risk") -%]: [%- requirement_spec_item.requirement_spec_risk.description IF requirement_spec_item.requirement_spec_risk -%]
42
        &nbsp; | &nbsp;
43
        [%- LxERP.t8("Effort") -%]: [%#- render :partial => 'requirement_spec_items/time_estimation_item', :locals => { :item => requirement_spec_item } -%]
44
      </span>
45

  
46
    </div>
47
  </div>
48
</li>
templates/webpages/requirement_spec_item/_sub_function_block.html
1
[%- USE HTML -%][%- USE LxERP -%][%- USE P -%]
2
<div id="sub-function-block-[% requirement_spec_item.id %]" class="sub-function-block">
3

  
4
 <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">
5
  [% INCLUDE 'requirement_spec_item/_function_block_content_top.html' id_prefix='sub-' %]
6
  [% INCLUDE 'requirement_spec_item/_function_block_content_bottom.html' id_prefix='sub-' %]
7
 </div>
8
</div>

Auch abrufbar als: Unified diff