Revision e2f753a4
Von Moritz Bunkus vor mehr als 10 Jahren hinzugefügt
SL/Controller/RequirementSpec.pm | ||
---|---|---|
23 | 23 |
); |
24 | 24 |
|
25 | 25 |
__PACKAGE__->run_before('setup'); |
26 |
__PACKAGE__->run_before('load_requirement_spec', only => [ qw( edit update show destroy tree) ]);
|
|
26 |
__PACKAGE__->run_before('load_requirement_spec', only => [ qw( edit update show destroy) ]); |
|
27 | 27 |
__PACKAGE__->run_before('load_select_options', only => [ qw(new edit create update list) ]); |
28 | 28 |
__PACKAGE__->run_before('load_search_select_options', only => [ qw( list) ]); |
29 | 29 |
|
... | ... | |
118 | 118 |
$self->render('1;', { type => 'js', inline => 1 }); |
119 | 119 |
} |
120 | 120 |
|
121 |
sub action_tree { |
|
122 |
my ($self) = @_; |
|
123 |
my $r = $self->render('requirement_spec/tree', now => DateTime->now); |
|
124 |
} |
|
125 |
|
|
126 | 121 |
# |
127 | 122 |
# filters |
128 | 123 |
# |
SL/Controller/RequirementSpecTextBlock.pm | ||
---|---|---|
4 | 4 |
|
5 | 5 |
use parent qw(SL::Controller::Base); |
6 | 6 |
|
7 |
use Time::HiRes (); |
|
8 |
|
|
7 | 9 |
use SL::ClientJS; |
8 | 10 |
use SL::DB::RequirementSpec; |
9 | 11 |
use SL::DB::RequirementSpecPredefinedText; |
... | ... | |
14 | 16 |
|
15 | 17 |
use Rose::Object::MakeMethods::Generic |
16 | 18 |
( |
17 |
scalar => [ qw(requirement_spec text_block) ], |
|
19 |
scalar => [ qw(requirement_spec text_block) ], |
|
20 |
'scalar --get_set_init' => [ qw(predefined_texts) ], |
|
18 | 21 |
); |
19 | 22 |
|
20 | 23 |
__PACKAGE__->run_before('load_requirement_spec_text_block', only => [qw(ajax_edit ajax_update ajax_delete dragged_and_dropped)]); |
... | ... | |
30 | 33 |
my $current_where = $self->output_position_from_id($::form->{current_content_id}, $::form->{current_content_type}); |
31 | 34 |
my $new_where; |
32 | 35 |
|
33 |
if ($::form->{clicked_type} =~ m/^textblocks-(front|back)/) { |
|
36 |
if ($::form->{clicked_type} =~ m/^text-blocks-(front|back)/) {
|
|
34 | 37 |
$new_where = $1 eq 'front' ? 0 : 1; |
35 | 38 |
|
36 | 39 |
} else { |
... | ... | |
66 | 69 |
->val('#current_content_id', $self->text_block->id); |
67 | 70 |
} |
68 | 71 |
|
69 |
my $predefined_texts = SL::DB::Manager::RequirementSpecPredefinedText->get_all_sorted; |
|
70 |
my $html = $self->render('requirement_spec_text_block/_form', { output => 0 }, PREDEFINED_TEXTS => $predefined_texts); |
|
72 |
my $html = $self->render('requirement_spec_text_block/_form', { output => 0 }); |
|
71 | 73 |
|
72 | 74 |
$js->hide('#text-block-' . $self->text_block->id) |
73 | 75 |
->remove('#edit_text_block_' . $self->text_block->id . '_form') |
74 | 76 |
->insertAfter($html, '#text-block-' . $self->text_block->id) |
75 | 77 |
->jstree->select_node('#tree', '#tb-' . $self->text_block->id) |
78 |
->focus('#edit_text_block_' . $self->text_block->id . '_title') |
|
76 | 79 |
->render($self); |
77 | 80 |
} |
78 | 81 |
|
... | ... | |
97 | 100 |
->render($self); |
98 | 101 |
} |
99 | 102 |
|
103 |
sub action_ajax_create { |
|
104 |
# TODO: ajax_create |
|
105 |
my ($self, %params) = @_; |
|
106 |
|
|
107 |
my $prefix = $::form->{form_prefix} || 'text_block'; |
|
108 |
my $attributes = $::form->{$prefix} || {}; |
|
109 |
|
|
110 |
foreach (qw(requirement_spec_id output_position)) { |
|
111 |
delete $attributes->{$_} if !defined $attributes->{$_}; |
|
112 |
} |
|
113 |
|
|
114 |
$self->text_block->update_attributes(%{ $attributes }); |
|
115 |
|
|
116 |
my $html = $self->render('requirement_spec_text_block/_text_block', { output => 0 }, text_block => $self->text_block); |
|
117 |
|
|
118 |
SL::ClientJS->new |
|
119 |
->remove('#' . $prefix . '_form') |
|
120 |
->replaceWith('#text-block-' . $self->text_block->id, $html) |
|
121 |
->jstree->rename_node('#tree', '#tb-' . $self->text_block->id, $self->text_block->title) |
|
122 |
->render($self); |
|
123 |
} |
|
124 |
|
|
100 | 125 |
sub action_ajax_delete { |
101 | 126 |
my ($self) = @_; |
102 | 127 |
|
... | ... | |
116 | 141 |
->render($self); |
117 | 142 |
} |
118 | 143 |
|
144 |
sub action_ajax_add { |
|
145 |
my ($self) = @_; |
|
146 |
|
|
147 |
my $js = SL::ClientJS->new; |
|
148 |
|
|
149 |
my $current_where = $self->output_position_from_id($::form->{current_content_id}, $::form->{current_content_type}) // -1; |
|
150 |
my $new_where = $self->output_position_from_id($::form->{id}) // $::form->{output_position}; |
|
151 |
|
|
152 |
if ($new_where != $current_where) { |
|
153 |
my $text_blocks = SL::DB::Manager::RequirementSpecTextBlock->get_all_sorted(where => [ output_position => $new_where, requirement_spec_id => $::form->{requirement_spec_id} ]); |
|
154 |
my $html = $self->render('requirement_spec_text_block/ajax_list', { output => 0 }, TEXT_BLOCKS => $text_blocks, output_position => $new_where); |
|
155 |
|
|
156 |
$js->html('#column-content', $html); |
|
157 |
} |
|
158 |
|
|
159 |
$self->text_block(SL::DB::RequirementSpecTextBlock->new( |
|
160 |
requirement_spec_id => $::form->{requirement_spec_id}, |
|
161 |
output_position => $::form->{output_position}, |
|
162 |
)); |
|
163 |
|
|
164 |
my $id_base = join('_', 'new_text_block', Time::HiRes::gettimeofday(), int rand 1000000000000); |
|
165 |
my $html = $self->render('requirement_spec_text_block/_form', { output => 0 }, id_base => $id_base); |
|
166 |
|
|
167 |
$js->action($::form->{id} ? 'insertAfter' : 'appendTo', $html, '#text-block-' . ($::form->{id} || 'list')) |
|
168 |
->focus('#' . $id_base . '_title') |
|
169 |
->render($self); |
|
170 |
} |
|
171 |
|
|
119 | 172 |
sub action_dragged_and_dropped { |
120 | 173 |
my ($self) = @_; |
121 | 174 |
|
122 | 175 |
my $position = $::form->{position} =~ m/^ (?: before | after | last ) $/x ? $::form->{position} : die "Unknown 'position' parameter"; |
123 | 176 |
my $dropped_text_block = $position =~ m/^ (?: before | after ) $/x ? SL::DB::RequirementSpecTextBlock->new(id => $::form->{dropped_id})->load : undef; |
124 | 177 |
|
125 |
my $dropped_type = $position ne 'last' ? undef : $::form->{dropped_type} =~ m/^ textblocks- (?:front|back) $/x ? $::form->{dropped_type} : die "Unknown 'dropped_type' parameter"; |
|
178 |
my $dropped_type = $position ne 'last' ? undef : $::form->{dropped_type} =~ m/^ text-blocks- (?:front|back) $/x ? $::form->{dropped_type} : die "Unknown 'dropped_type' parameter";
|
|
126 | 179 |
my $old_where = $self->text_block->output_position; |
127 | 180 |
|
128 | 181 |
$self->text_block->db->do_transaction(sub { |
129 | 182 |
1; |
130 | 183 |
$self->text_block->remove_from_list; |
131 |
$self->text_block->output_position($position =~ m/before|after/ ? $dropped_text_block->output_position : $::form->{dropped_type} eq 'textblocks-front' ? 0 : 1); |
|
184 |
$self->text_block->output_position($position =~ m/before|after/ ? $dropped_text_block->output_position : $::form->{dropped_type} eq 'text-blocks-front' ? 0 : 1);
|
|
132 | 185 |
$self->text_block->add_to_list(position => $position, reference => $dropped_text_block ? $dropped_text_block->id : undef); |
133 | 186 |
}); |
134 | 187 |
|
135 |
return $self->render(\'', { type => 'json' }) if $::form->{current_content_type} !~ m/^textblock/;
|
|
188 |
# $::lxdebug->dump(0, "form", $::form);
|
|
136 | 189 |
|
137 |
my $current_where = $self->output_position_from_id($::form->{current_content_id}, $::form->{current_content_type}); |
|
190 |
return $self->render(\'', { type => 'json' }) if $::form->{current_content_type} !~ m/^text-block/; |
|
191 |
|
|
192 |
my $current_where = $self->output_position_from_id($::form->{current_content_id}, $::form->{current_content_type}) // -1; |
|
138 | 193 |
my $new_where = $self->text_block->output_position; |
139 | 194 |
my $id = $self->text_block->id; |
140 | 195 |
my $js = SL::ClientJS->new; |
... | ... | |
146 | 201 |
my $text_blocks = SL::DB::Manager::RequirementSpecTextBlock->get_all_sorted(where => [ output_position => $new_where ]); |
147 | 202 |
my $html = $self->render('requirement_spec_text_block/ajax_list', { output => 0 }, TEXT_BLOCKS => $text_blocks, output_position => $new_where); |
148 | 203 |
|
149 |
$js->val('#current_content_type', 'textblocks-' . ($new_where == 0 ? 'front' : 'back')) |
|
204 |
$js->val('#current_content_type', 'text-blocks-' . ($new_where == 0 ? 'front' : 'back'))
|
|
150 | 205 |
->html('#column-content', $html); |
151 | 206 |
|
152 | 207 |
} else { |
... | ... | |
197 | 252 |
sub output_position_from_id { |
198 | 253 |
my ($self, $id, $type, %params) = @_; |
199 | 254 |
|
200 |
if (!$id) {
|
|
201 |
return $params{default} unless $type =~ m/-(front|back)/;
|
|
202 |
return $1 eq 'front' ? 0 : 1;
|
|
255 |
if ($type) {
|
|
256 |
return $1 eq 'front' ? 0 : 1 if $type =~ m/-(front|back)$/;
|
|
257 |
return undef if $type !~ m/text-block/;
|
|
203 | 258 |
} |
204 | 259 |
|
205 | 260 |
my $text_block = SL::DB::Manager::RequirementSpecTextBlock->find_by(id => $id); |
206 | 261 |
|
207 |
return $params{default} unless $text_block; |
|
208 |
return $text_block->output_position unless $params{as} eq 'text'; |
|
209 |
return 1 == $text_block->output_position ? 'front' : 'back'; |
|
262 |
return $text_block ? $text_block->output_position : undef; |
|
263 |
} |
|
264 |
|
|
265 |
sub init_predefined_texts { |
|
266 |
return SL::DB::Manager::RequirementSpecPredefinedText->get_all_sorted; |
|
210 | 267 |
} |
211 | 268 |
|
212 | 269 |
1; |
SL/Presenter/RequirementSpecTextBlock.pm | ||
---|---|---|
16 | 16 |
|
17 | 17 |
return { |
18 | 18 |
data => $text_block->title || '', |
19 |
metadata => { id => $text_block->id, type => 'textblock' }, |
|
19 |
metadata => { id => $text_block->id, type => 'text-block' },
|
|
20 | 20 |
attr => { id => "tb-" . $text_block->id, href => $params{href} || '#', class => 'text-block-context-menu' }, |
21 | 21 |
}; |
22 | 22 |
} |
css/requirement_spec.css | ||
---|---|---|
14 | 14 |
#tree-column { |
15 | 15 |
float: left; |
16 | 16 |
width: 25%; |
17 |
border-right: 1px solid black; |
|
18 | 17 |
} |
19 | 18 |
|
20 | 19 |
#content-column { |
21 |
float: left; |
|
20 |
float: right; |
|
21 |
width: 74%; |
|
22 | 22 |
padding-left: 10px; |
23 | 23 |
} |
24 | 24 |
|
js/requirement_spec.js | ||
---|---|---|
6 | 6 |
|
7 | 7 |
// console.debug("dragged " + dragged_type + " dropped " + dropped_type + " dir " + data.p); |
8 | 8 |
|
9 |
if ((dragged_type == "sections") || (dragged_type == "textblocks-front") || (dragged_type == "textblocks-back"))
|
|
9 |
if ((dragged_type == "sections") || (dragged_type == "text-blocks-front") || (dragged_type == "text-blocks-back"))
|
|
10 | 10 |
return false; |
11 | 11 |
|
12 |
if (dragged_type == "textblock") { |
|
13 |
if ((dropped_type == "textblocks-front") || (dropped_type == "textblocks-back"))
|
|
12 |
if (dragged_type == "text-block") {
|
|
13 |
if ((dropped_type == "text-blocks-front") || (dropped_type == "text-blocks-back"))
|
|
14 | 14 |
return (data.p == "inside") || (data.p == "last"); |
15 |
if (dropped_type == "textblock") |
|
15 |
if (dropped_type == "text-block")
|
|
16 | 16 |
return (data.p == "before") || (data.p == "after"); |
17 | 17 |
|
18 | 18 |
return false; |
... | ... | |
28 | 28 |
} |
29 | 29 |
|
30 | 30 |
// dragged_type == (sub) function blocks |
31 |
if ((dropped_type == "textblock") || (dropped_type == "textblocks-front") || (dropped_type == "textblocks-back"))
|
|
31 |
if ((dropped_type == "text-block") || (dropped_type == "text-blocks-front") || (dropped_type == "text-blocks-back"))
|
|
32 | 32 |
return false; |
33 | 33 |
|
34 | 34 |
var dropped_depth = dropped_type == "sections" ? 0 : dropped_type == "section" ? 1 : data.r.parent().parent().data('type') != "functionblock" ? 2 : 3; |
... | ... | |
47 | 47 |
var move_obj = $.jstree._reference('#tree')._get_move(); |
48 | 48 |
var dragged = move_obj.o; |
49 | 49 |
var dropped = move_obj.r; |
50 |
var controller = dragged.data("type") == "textblock" ? "RequirementSpecTextBlock" : "RequirementSpecItem"; |
|
50 |
var controller = dragged.data("type") == "text-block" ? "RequirementSpecTextBlock" : "RequirementSpecItem";
|
|
51 | 51 |
var data = { |
52 | 52 |
action: controller + "/dragged_and_dropped", |
53 | 53 |
requirement_spec_id: $('#requirement_spec_id').val(), |
... | ... | |
81 | 81 |
|
82 | 82 |
var url = 'controller.pl?action=' |
83 | 83 |
$.get('controller.pl', { |
84 |
action: (/^textblock/ ? 'RequirementSpecTextBlock' : 'RequirementSpecItem') + '/ajax_list.js', |
|
84 |
action: (/^text-block/ ? 'RequirementSpecTextBlock' : 'RequirementSpecItem') + '/ajax_list.js',
|
|
85 | 85 |
requirement_spec_id: $('#requirement_spec_id').val(), |
86 | 86 |
current_content_type: $('#current_content_type').val(), |
87 | 87 |
current_content_id: $('#current_content_id').val(), |
... | ... | |
137 | 137 |
} |
138 | 138 |
|
139 | 139 |
function find_text_block_id(clicked_elt) { |
140 |
console.log("id: " + $(clicked_elt).attr('id')); |
|
140 |
// console.log("id: " + $(clicked_elt).attr('id'));
|
|
141 | 141 |
var id = $(clicked_elt).attr('id'); |
142 | 142 |
if (/^text-block-\d+$/.test(id)) { |
143 |
console.log("find_text_block_id: case 1: " + id.substr(11)); |
|
143 |
// console.log("find_text_block_id: case 1: " + id.substr(11));
|
|
144 | 144 |
return id.substr(11) * 1; |
145 | 145 |
} |
146 | 146 |
|
147 | 147 |
id = $(clicked_elt).closest("[id*=text-block-]").attr('id') |
148 | 148 |
if (/^text-block-\d+$/.test(id)) { |
149 |
console.log("find_text_block_id: case 2: " + id.substr(11)); |
|
149 |
// console.log("find_text_block_id: case 2: " + id.substr(11));
|
|
150 | 150 |
return id.substr(11) * 1; |
151 | 151 |
} |
152 | 152 |
|
153 | 153 |
id = $(clicked_elt).closest("[id*=tb-]").attr('id') |
154 | 154 |
if (/^tb-\d+$/.test(id)) { |
155 |
console.log("find_text_block_id: case 3: " + id.substr(3)); |
|
155 |
// console.log("find_text_block_id: case 3: " + id.substr(3));
|
|
156 | 156 |
return id.substr(3) * 1; |
157 | 157 |
} |
158 | 158 |
|
159 |
console.log("find_text_block_id: case undef"); |
|
159 |
// console.log("find_text_block_id: case undef");
|
|
160 | 160 |
return undefined; |
161 | 161 |
} |
162 | 162 |
|
... | ... | |
166 | 166 |
return output_position; |
167 | 167 |
|
168 | 168 |
var type = $(clicked_elt).closest('#tb-back,#tb-front').data('type'); |
169 |
if (/^textblocks-(front|back)/.test(type)) |
|
170 |
return type == "textblocks-front" ? 0 : 1; |
|
169 |
if (/^text-blocks-(front|back)/.test(type))
|
|
170 |
return type == "text-blocks-front" ? 0 : 1;
|
|
171 | 171 |
|
172 | 172 |
return undefined; |
173 | 173 |
} |
... | ... | |
176 | 176 |
return find_text_block_id(opt.$trigger) == undefined; |
177 | 177 |
} |
178 | 178 |
|
179 |
function edit_text_block(key, opt) {
|
|
179 |
function standard_text_block_ajax_call(key, opt, other_data) {
|
|
180 | 180 |
var data = { |
181 |
action: "RequirementSpecTextBlock/ajax_edit", |
|
181 |
action: "RequirementSpecTextBlock/ajax_" + key, |
|
182 |
requirement_spec_id: $('#requirement_spec_id').val(), |
|
182 | 183 |
id: find_text_block_id(opt.$trigger), |
184 |
output_position: find_text_block_output_position(opt.$trigger), |
|
183 | 185 |
current_content_type: $('#current_content_type').val(), |
184 | 186 |
current_content_id: $('#current_content_id').val() |
185 | 187 |
}; |
186 |
$.post("controller.pl", data, eval_json_result); |
|
187 |
return true; |
|
188 |
} |
|
189 | 188 |
|
190 |
function add_text_block(key, opt) { |
|
191 |
return true; |
|
192 |
} |
|
189 |
$.post("controller.pl", $.extend(data, other_data || {}), eval_json_result); |
|
193 | 190 |
|
194 |
function delete_text_block(key, opt) { |
|
195 |
var data = { |
|
196 |
action: "RequirementSpecTextBlock/ajax_delete", |
|
197 |
id: find_text_block_id(opt.$trigger), |
|
198 |
current_content_type: $('#current_content_type').val(), |
|
199 |
current_content_id: $('#current_content_id').val() |
|
200 |
}; |
|
201 |
$.post("controller.pl", data, eval_json_result); |
|
202 | 191 |
return true; |
203 | 192 |
} |
204 | 193 |
|
205 | 194 |
function submit_edit_text_block_form(id_base) { |
195 |
var id = $('#' + id_base + '_id').val(); |
|
206 | 196 |
var url = "controller.pl?" + $('#' + id_base + '_form').serialize(); |
207 | 197 |
var data = { |
208 |
action: 'RequirementSpecTextBlock/ajax_update',
|
|
209 |
id: $('#' + id_base + '_id').val(),
|
|
198 |
action: 'RequirementSpecTextBlock/ajax_' + (id ? 'update' : 'create'),
|
|
199 |
id: id,
|
|
210 | 200 |
form_prefix: id_base |
211 | 201 |
}; |
212 |
console.log("posting edit text block: " + url); |
|
213 |
console.log(data); |
|
214 | 202 |
$.post(url, data, eval_json_result); |
203 |
return true; |
|
215 | 204 |
} |
216 | 205 |
|
217 | 206 |
function cancel_edit_text_block_form(id_base) { |
locale/de/all | ||
---|---|---|
892 | 892 |
'Edit section #1' => 'Abschnitt #1 bearbeiten', |
893 | 893 |
'Edit templates' => 'Vorlagen bearbeiten', |
894 | 894 |
'Edit text block' => 'Textblock bearbeiten', |
895 |
'Edit text block \'#1\'' => 'Textblock \'#1\' bearbeiten', |
|
895 | 896 |
'Edit the Delivery Order' => 'Lieferschein bearbeiten', |
896 | 897 |
'Edit the configuration for periodic invoices' => 'Konfiguration für wiederkehrende Rechnungen bearbeiten', |
897 | 898 |
'Edit the currency names in order to rename them.' => 'Bearbeiten Sie den Namen, um eine Währung umzubennen.', |
templates/webpages/requirement_spec/show.html | ||
---|---|---|
12 | 12 |
</div> |
13 | 13 |
|
14 | 14 |
<div id="column-container"> |
15 |
<div id="tree-column" style="border-right: 1px solid black"> |
|
16 |
<div style="min-height: 32px; height: 32px;"> |
|
17 |
<div style="float: left"> |
|
18 |
[% L.button_tag("new_section_form()", LxERP.t8("New section"), id="new-section-button") %] |
|
19 |
</div> |
|
20 |
<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> |
|
21 |
</div> |
|
22 |
|
|
15 |
<div id="tree-column"> |
|
23 | 16 |
<div id="tree"></div> |
24 | 17 |
</div> |
25 | 18 |
|
... | ... | |
42 | 35 |
<!-- |
43 | 36 |
var tree_data = [ |
44 | 37 |
{ data: [% JSON.json(LxERP.t8("Text blocks front")) %], |
45 |
metadata: { type: "textblocks-front" }, |
|
38 |
metadata: { type: "text-blocks-front" },
|
|
46 | 39 |
attr: { id: "tb-front", class: "text-block-context-menu" }, |
47 | 40 |
children: [ |
48 | 41 |
[% FOREACH tb = SELF.requirement_spec.text_blocks_for_position(0) %] |
... | ... | |
63 | 56 |
}, |
64 | 57 |
|
65 | 58 |
{ data: [% JSON.json(LxERP.t8("Text blocks back")) %], |
66 |
metadata: { type: "textblocks-back" }, |
|
59 |
metadata: { type: "text-blocks-back" },
|
|
67 | 60 |
attr: { id: "tb-back", class: "text-block-context-menu" }, |
68 | 61 |
children: [ |
69 | 62 |
[% FOREACH tb = SELF.requirement_spec.text_blocks_for_position(1) %] |
... | ... | |
109 | 102 |
|
110 | 103 |
function ask_delete_text_block(key, opt) { |
111 | 104 |
if (confirm("[% LxERP.t8("Are you sure?") %]")) |
112 |
delete_text_block(key, opt);
|
|
105 |
standard_text_block_ajax_call(key, opt);
|
|
113 | 106 |
return true; |
114 | 107 |
} |
115 | 108 |
|
... | ... | |
117 | 110 |
$.contextMenu({ |
118 | 111 |
selector: '.text-block-context-menu', |
119 | 112 |
items: { |
120 |
add: { name: "[% LxERP.t8('Add text block') %]", icon: "add", callback: add_text_block },
|
|
121 |
edit: { name: "[% LxERP.t8('Edit text block') %]", icon: "edit", callback: edit_text_block, disabled: disable_edit_text_block_commands },
|
|
113 |
add: { name: "[% LxERP.t8('Add text block') %]", icon: "add", callback: standard_text_block_ajax_call },
|
|
114 |
edit: { name: "[% LxERP.t8('Edit text block') %]", icon: "edit", callback: standard_text_block_ajax_call, disabled: disable_edit_text_block_commands },
|
|
122 | 115 |
delete: { name: "[% LxERP.t8('Delete text block') %]", icon: "delete", callback: ask_delete_text_block, disabled: disable_edit_text_block_commands }, |
123 | 116 |
sep1: "---------", |
124 | 117 |
copy: { name: "[% LxERP.t8('Copy') %]", icon: "copy", disabled: disable_edit_text_block_commands }, |
templates/webpages/requirement_spec/tree.html | ||
---|---|---|
1 |
[%- USE HTML %][%- USE L %][%- USE LxERP %][% USE P %][% USE JSON %] |
|
2 |
|
|
3 |
[%- L.hidden_tag('requirement_spec_id', SELF.requirement_spec.id) -%] |
|
4 |
|
|
5 |
<div id="column-container"> |
|
6 |
<div id="tree-column"> |
|
7 |
<div style="min-height: 32px; height: 32px;"> |
|
8 |
<div style="float: left"> |
|
9 |
[% L.button_tag("new_section_form()", LxERP.t8("New section"), id="new-section-button") %] |
|
10 |
</div> |
|
11 |
<div style="clear: both"></div> |
|
12 |
</div> |
|
13 |
|
|
14 |
<div id="tree"></div> |
|
15 |
</div> |
|
16 |
|
|
17 |
<div id="content-column" class="clearfix"> |
|
18 |
<p>There's beauty in the breakdown. 0</p> |
|
19 |
<p>There's beauty in the breakdown. 1</p> |
|
20 |
<p>There's beauty in the breakdown. 2</p> |
|
21 |
<p>There's beauty in the breakdown. 3</p> |
|
22 |
<p>There's beauty in the breakdown. 4</p> |
|
23 |
<p>There's beauty in the breakdown. 5</p> |
|
24 |
<p>There's beauty in the breakdown. 6</p> |
|
25 |
<p>There's beauty in the breakdown. 7</p> |
|
26 |
<p>There's beauty in the breakdown. 8</p> |
|
27 |
<p>There's beauty in the breakdown. 9</p> |
|
28 |
<p>There's beauty in the breakdown. 10</p> |
|
29 |
<p>There's beauty in the breakdown. 11</p> |
|
30 |
<p>There's beauty in the breakdown. 12</p> |
|
31 |
<p>There's beauty in the breakdown. 13</p> |
|
32 |
<p>There's beauty in the breakdown. 14</p> |
|
33 |
<p>There's beauty in the breakdown. 15</p> |
|
34 |
<p>There's beauty in the breakdown. 16</p> |
|
35 |
<p>There's beauty in the breakdown. 17</p> |
|
36 |
<p>There's beauty in the breakdown. 18</p> |
|
37 |
<p>There's beauty in the breakdown. 19</p> |
|
38 |
<p>There's beauty in the breakdown. 20</p> |
|
39 |
<p>There's beauty in the breakdown. 21</p> |
|
40 |
<p>There's beauty in the breakdown. 22</p> |
|
41 |
<!-- <p>There's beauty in the breakdown. 23</p> --> |
|
42 |
<!-- <p>There's beauty in the breakdown. 24</p> --> |
|
43 |
<!-- <p>There's beauty in the breakdown. 25</p> --> |
|
44 |
<!-- <p>There's beauty in the breakdown. 26</p> --> |
|
45 |
<!-- <p>There's beauty in the breakdown. 27</p> --> |
|
46 |
<!-- <p>There's beauty in the breakdown. 28</p> --> |
|
47 |
<!-- <p>There's beauty in the breakdown. 29</p> --> |
|
48 |
<!-- <p>There's beauty in the breakdown. 30</p> --> |
|
49 |
<!-- <p>There's beauty in the breakdown. 31</p> --> |
|
50 |
<!-- <p>There's beauty in the breakdown. 32</p> --> |
|
51 |
<!-- <p>There's beauty in the breakdown. 33</p> --> |
|
52 |
<!-- <p>There's beauty in the breakdown. 34</p> --> |
|
53 |
<!-- <p>There's beauty in the breakdown. 35</p> --> |
|
54 |
</div> |
|
55 |
</div> |
|
56 |
|
|
57 |
<script type="text/javascript"> |
|
58 |
<!-- |
|
59 |
var tree_data = [ |
|
60 |
{ "data": [% JSON.json(LxERP.t8("Text blocks front")) %], |
|
61 |
"metadata": { "type": "textblocks-front" }, |
|
62 |
"attr": { "id": "tb-front" }, |
|
63 |
"children": [ |
|
64 |
[% FOREACH tb = SELF.requirement_spec.text_blocks_for_position(0) %] |
|
65 |
[% P.requirement_spec_text_block_jstree_data(tb).json %][% IF !loop.last %],[% END %] |
|
66 |
[% END %] |
|
67 |
] |
|
68 |
}, |
|
69 |
|
|
70 |
{ "data": [% JSON.json(LxERP.t8("Sections")) %], |
|
71 |
"metadata": { "type": "sections" }, |
|
72 |
"attr": { "id": "sections" }, |
|
73 |
"children": [ |
|
74 |
|
|
75 |
[% FOREACH section = SELF.requirement_spec.sections %] |
|
76 |
[% P.requirement_spec_item_jstree_data(section).json %][% IF !loop.last %],[% END %] |
|
77 |
[% END %] |
|
78 |
] |
|
79 |
}, |
|
80 |
|
|
81 |
{ "data": [% JSON.json(LxERP.t8("Text blocks back")) %], |
|
82 |
"metadata": { "type": "textblocks-back" }, |
|
83 |
"attr": { "id": "tb-back" }, |
|
84 |
"children": [ |
|
85 |
[% FOREACH tb = SELF.requirement_spec.text_blocks_for_position(1) %] |
|
86 |
[% P.requirement_spec_text_block_jstree_data(tb).json %][% IF !loop.last %],[% END %] |
|
87 |
[% END %] |
|
88 |
] |
|
89 |
} |
|
90 |
]; |
|
91 |
|
|
92 |
$(function() { |
|
93 |
$('#tree').jstree({ |
|
94 |
"core": { |
|
95 |
"animation": 0, |
|
96 |
"initially_open": [ "tb-front", "tb-back", "sections" |
|
97 |
[%- FOREACH section = SELF.requirement_spec.sections -%] |
|
98 |
, "fb-[% section.id %]" |
|
99 |
[%- FOREACH function_block = section.children -%] |
|
100 |
, "fb-[% function_block.id -%]" |
|
101 |
[%- END -%] |
|
102 |
[%- END -%] |
|
103 |
] |
|
104 |
}, |
|
105 |
"json_data": { |
|
106 |
"data": tree_data |
|
107 |
}, |
|
108 |
"crrm": { |
|
109 |
"move": { |
|
110 |
"check_move": check_move, |
|
111 |
"open_move": true |
|
112 |
} |
|
113 |
}, |
|
114 |
"themes": { |
|
115 |
"theme": "requirement-spec" |
|
116 |
}, |
|
117 |
"plugins": [ "themes", "json_data", "ui", "crrm", "dnd" ] |
|
118 |
}) |
|
119 |
.bind("move_node.jstree", node_moved); |
|
120 |
}); |
|
121 |
--> |
|
122 |
</script> |
templates/webpages/requirement_spec_text_block/_form.html | ||
---|---|---|
1 | 1 |
[%- USE LxERP -%][%- USE L -%][%- USE HTML -%][%- USE JavaScript -%][% SET style="width: 500px" %] |
2 | 2 |
[% DEFAULT id_base = 'edit_text_block_' _ SELF.text_block.id %] |
3 | 3 |
<form method="post" id="[% id_base %]_form"> |
4 |
<h2> |
|
5 |
[%- IF SELF.text_block.id %] |
|
6 |
[%- SET title = SELF.text_block.title || '(' _ LxERP.t8('No title yet') _ ')' %] |
|
7 |
[%- LxERP.t8("Edit text block '#1'", title) %] |
|
8 |
[%- ELSE %] |
|
9 |
[%- LxERP.t8("Add text block") %] |
|
10 |
[%- END %] |
|
11 |
</h2> |
|
12 |
|
|
4 | 13 |
[% L.hidden_tag(id_base _ '_id', SELF.text_block.id) %] |
5 | 14 |
[% L.hidden_tag(id_base _ '.requirement_spec_id', SELF.text_block.requirement_spec_id) %] |
6 | 15 |
[% L.hidden_tag(id_base _ '.output_position', SELF.text_block.output_position) %] |
... | ... | |
11 | 20 |
<td>[% L.input_tag(id_base _ '.title', SELF.text_block.title, style = style) %]</td> |
12 | 21 |
</tr> |
13 | 22 |
|
14 |
[%- IF PREDEFINED_TEXTS.size %]
|
|
23 |
[%- IF SELF.predefined_texts.size %]
|
|
15 | 24 |
<tr> |
16 | 25 |
<th align="right">[%- LxERP.t8("Pre-defined Texts") %]:</th> |
17 | 26 |
<td> |
18 |
[%- L.select_tag(id_base _ '_predefined_text_block', PREDEFINED_TEXTS, title_key='description', style=style) %]
|
|
27 |
[%- L.select_tag(id_base _ '_predefined_text_block', SELF.predefined_texts, title_key='description', style=style) %]
|
|
19 | 28 |
<a href="#" onclick="insert_selected_predefined_text()">[%- LxERP.t8("Insert") %]</a> |
20 | 29 |
</td> |
21 | 30 |
</tr> |
... | ... | |
32 | 41 |
<a href="#" onclick="cancel_edit_text_block_form('[% id_base %]')">[%- LxERP.t8("Cancel") %]</a> |
33 | 42 |
</p> |
34 | 43 |
|
35 |
[%- IF PREDEFINED_TEXTS.size %]
|
|
44 |
[%- IF SELF.predefined_texts.size %]
|
|
36 | 45 |
<script type="text/javascript"> |
37 | 46 |
<!-- |
38 | 47 |
function insert_selected_predefined_text() { |
39 | 48 |
var data = { |
40 |
[%- FOREACH pt = PREDEFINED_TEXTS %]
|
|
49 |
[%- FOREACH pt = SELF.predefined_texts %]
|
|
41 | 50 |
[% HTML.escape(pt.id) %]: { |
42 | 51 |
title: "[% JavaScript.escape(pt.title) %]", |
43 | 52 |
text: "[% JavaScript.escape(pt.text) %]" |
Auch abrufbar als: Unified diff
Textblöcke bearbeiten, verschieben: verschiedene Fixes