line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package RapidApp::Module::Grid; |
2
|
|
|
|
|
|
|
|
3
|
4
|
|
|
4
|
|
2084
|
use strict; |
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
109
|
|
4
|
4
|
|
|
4
|
|
20
|
use warnings; |
|
4
|
|
|
|
|
10
|
|
|
4
|
|
|
|
|
87
|
|
5
|
|
|
|
|
|
|
|
6
|
4
|
|
|
4
|
|
19
|
use Moose; |
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
22
|
|
7
|
|
|
|
|
|
|
extends 'RapidApp::Module::StorCmp'; |
8
|
|
|
|
|
|
|
|
9
|
4
|
|
|
4
|
|
22015
|
use RapidApp::Util qw(:all); |
|
4
|
|
|
|
|
10
|
|
|
4
|
|
|
|
|
1671
|
|
10
|
|
|
|
|
|
|
|
11
|
4
|
|
|
4
|
|
29
|
use Try::Tiny; |
|
4
|
|
|
|
|
16
|
|
|
4
|
|
|
|
|
6688
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
#has 'record_pk' => ( is => 'ro', default => 'id' ); |
14
|
|
|
|
|
|
|
#has 'DataStore_class' => ( is => 'ro', default => 'RapidApp::Module::DatStor', isa => 'ClassName' ); |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
has 'title' => ( is => 'ro', default => undef ); |
18
|
|
|
|
|
|
|
has 'title_icon_href' => ( is => 'ro', default => undef ); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
has 'open_record_class' => ( is => 'ro', default => undef, isa => 'Maybe[ClassName|HashRef]' ); |
21
|
|
|
|
|
|
|
has 'add_record_class' => ( is => 'ro', default => undef, isa => 'Maybe[ClassName|HashRef]' ); |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
has 'open_record_via_rest', is => 'ro', isa => 'Bool', default => 1; |
24
|
|
|
|
|
|
|
has 'open_record_rest_key', is => 'ro', isa => 'Maybe[Str]', lazy => 1, default => undef; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# --- |
27
|
|
|
|
|
|
|
# If true, a special "open" link column will be prepended to the column list. This is useful for clients |
28
|
|
|
|
|
|
|
# that cannot double-click, such as iPads |
29
|
|
|
|
|
|
|
has 'open_record_column', is => 'ro', isa => 'Bool', default => 1; |
30
|
|
|
|
|
|
|
has 'open_record_column_hidden', is => 'ro', isa => 'Bool', default => 1; |
31
|
|
|
|
|
|
|
# --- |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
# autoLoad needs to be false for the paging toolbar to not load the whole |
34
|
|
|
|
|
|
|
# data set |
35
|
|
|
|
|
|
|
has 'store_autoLoad' => ( is => 'ro', default => sub {\0} ); |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
has 'add_loadContentCnf' => ( is => 'ro', default => sub { |
38
|
|
|
|
|
|
|
{ |
39
|
|
|
|
|
|
|
title => 'Add', |
40
|
|
|
|
|
|
|
iconCls => 'ra-icon-add' |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
}); |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
has 'add_button_cnf' => ( is => 'ro', default => sub { |
45
|
|
|
|
|
|
|
{ |
46
|
|
|
|
|
|
|
text => 'Add', |
47
|
|
|
|
|
|
|
iconCls => 'ra-icon-add' |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
}); |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# Either based on open_record_class, or can be set manually in the constructor: |
52
|
|
|
|
|
|
|
has 'open_record_url' => ( is => 'ro', isa => 'Maybe[Str]', lazy => 1, default => sub { |
53
|
|
|
|
|
|
|
my $self = shift; |
54
|
|
|
|
|
|
|
return $self->Module('item',1)->base_url if ($self->open_record_class); |
55
|
|
|
|
|
|
|
return undef; |
56
|
|
|
|
|
|
|
}); |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
# get_record_loadContentCnf is used on a per-row basis to set the |
60
|
|
|
|
|
|
|
# options used to load the row in a tab when double-clicked |
61
|
|
|
|
|
|
|
# This should be overridden in the subclass: |
62
|
|
|
|
|
|
|
sub get_record_loadContentCnf { |
63
|
0
|
|
|
0
|
0
|
0
|
my ($self, $record) = @_; |
64
|
|
|
|
|
|
|
|
65
|
0
|
|
|
|
|
0
|
local $_ = $record; |
66
|
0
|
|
|
|
|
0
|
my $display = $self->get_record_display->($self); |
67
|
0
|
|
|
|
|
0
|
%$record = %$_; |
68
|
|
|
|
|
|
|
|
69
|
0
|
0
|
|
|
|
0
|
$display = { title => $display } unless (ref $display); |
70
|
|
|
|
|
|
|
|
71
|
0
|
|
|
|
|
0
|
return $display; |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
has 'get_record_display' => ( is => 'ro', isa => 'CodeRef', lazy => 1, default => sub { sub { |
74
|
|
|
|
|
|
|
my $self = shift; |
75
|
|
|
|
|
|
|
$self->record_pk . ': ' . $_->{$self->record_pk} |
76
|
|
|
|
|
|
|
}}); |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
has 'init_pagesize' => ( is => 'ro', isa => 'Int', default => 25 ); |
79
|
|
|
|
|
|
|
has '+max_pagesize' => ( default => 500 ); |
80
|
|
|
|
|
|
|
has 'use_column_summaries', is => 'ro', isa => 'Bool', default => 0; |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# -- autosize columns options: |
83
|
|
|
|
|
|
|
has 'use_autosize_columns', is => 'ro', isa => 'Bool', default => 1; |
84
|
|
|
|
|
|
|
has 'auto_autosize_columns', is => 'ro', isa => 'Bool', default => 0; |
85
|
|
|
|
|
|
|
has 'auto_autosize_columns_deep', is => 'ro', isa => 'Bool', default => 0; |
86
|
|
|
|
|
|
|
has 'autosize_hidden', is => 'ro', isa => 'Bool', default => 0; |
87
|
|
|
|
|
|
|
has 'autosize_maxwidth', is => 'ro', isa => 'Int', default => 450; |
88
|
|
|
|
|
|
|
# -- |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
# -- multisort options: |
91
|
|
|
|
|
|
|
has 'use_multisort', is => 'ro', isa => 'Bool', default => 1; |
92
|
|
|
|
|
|
|
# -- |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
has 'allow_edit_frozen', is => 'ro', isa => 'Bool', default => 1; |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub BUILD { |
97
|
52
|
|
|
52
|
0
|
1119
|
my $self = shift; |
98
|
|
|
|
|
|
|
|
99
|
52
|
100
|
|
|
|
1710
|
if (defined $self->open_record_class) { |
100
|
45
|
|
|
|
|
1338
|
$self->apply_init_modules( item => $self->open_record_class ); |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
# reach into the new sub-module and add a write listener to its store to |
103
|
|
|
|
|
|
|
# make it call our store.load() whenever it changes: |
104
|
|
|
|
|
|
|
### Temp disabled because this can cause a big load/hit ## |
105
|
|
|
|
|
|
|
#$self->Module('item',1)->DataStore->add_listener( write => $self->DataStore->store_load_fn ) if ( |
106
|
|
|
|
|
|
|
# $self->Module('item',1)->isa('RapidApp::Module::StorCmp') |
107
|
|
|
|
|
|
|
#); |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
52
|
50
|
|
|
|
1371
|
if (defined $self->add_record_class) { |
111
|
0
|
|
|
|
|
0
|
$self->apply_init_modules( add => $self->add_record_class ); |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# reach into the new sub-module and add a write listener to its store to |
114
|
|
|
|
|
|
|
# make it call our store.load() whenever it changes: |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
### Temp disabled because this can cause a big load/hit ## |
117
|
|
|
|
|
|
|
#$self->Module('add',1)->DataStore->add_listener( write => $self->DataStore->store_load_fn ) if ( |
118
|
|
|
|
|
|
|
# $self->Module('add',1)->isa('RapidApp::Module::StorCmp') |
119
|
|
|
|
|
|
|
#); |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
$self->apply_extconfig( |
124
|
52
|
100
|
|
|
|
1323
|
xtype => 'appgrid2', |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
125
|
|
|
|
|
|
|
pageSize => $self->init_pagesize, |
126
|
|
|
|
|
|
|
maxPageSize => $self->max_pagesize, |
127
|
|
|
|
|
|
|
stripeRows => \1, |
128
|
|
|
|
|
|
|
columnLines => \1, |
129
|
|
|
|
|
|
|
gridsearch => \1, |
130
|
|
|
|
|
|
|
column_allow_save_properties => [qw(width hidden)], |
131
|
|
|
|
|
|
|
use_column_summaries => $self->use_column_summaries ? \1 : \0, |
132
|
|
|
|
|
|
|
use_autosize_columns => $self->use_autosize_columns ? \1 : \0, |
133
|
|
|
|
|
|
|
use_multisort => $self->use_multisort ? \1 : \0, |
134
|
|
|
|
|
|
|
auto_autosize_columns => $self->auto_autosize_columns ? \1 : \0, |
135
|
|
|
|
|
|
|
auto_autosize_columns_deep => $self->auto_autosize_columns_deep ? \1 : \0, |
136
|
|
|
|
|
|
|
autosize_hidden => $self->autosize_hidden ? \1 : \0, |
137
|
|
|
|
|
|
|
autosize_maxwidth => $self->autosize_maxwidth, |
138
|
|
|
|
|
|
|
allow_edit_frozen => $self->allow_edit_frozen ? \1 : \0, |
139
|
|
|
|
|
|
|
open_record_via_rest => $self->open_record_via_rest ? \1 : \0, |
140
|
|
|
|
|
|
|
open_record_url => $self->open_record_url, |
141
|
|
|
|
|
|
|
open_record_rest_key => $self->open_record_rest_key, |
142
|
|
|
|
|
|
|
open_record_column => $self->open_record_column ? \1 : \0, |
143
|
|
|
|
|
|
|
open_record_column_hidden => $self->open_record_column_hidden ? \1 : \0, |
144
|
|
|
|
|
|
|
); |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
# The record_pk is forced to be added/included as a column: |
147
|
52
|
50
|
|
|
|
1831
|
if (defined $self->record_pk) { |
148
|
52
|
|
|
|
|
1245
|
$self->apply_columns( $self->record_pk => {} ); |
149
|
52
|
50
|
|
|
|
118
|
push @{ $self->include_columns }, $self->record_pk if (scalar @{ $self->include_columns } > 0); |
|
0
|
|
|
|
|
0
|
|
|
52
|
|
|
|
|
371
|
|
150
|
|
|
|
|
|
|
#$self->meta->find_attribute_by_name('include_columns_hash')->clear_value($self); |
151
|
52
|
|
|
|
|
110
|
%{ $self->include_columns_hash } = (); |
|
52
|
|
|
|
|
295
|
|
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
52
|
100
|
66
|
|
|
1222
|
if (defined $self->open_record_url or defined $self->add_record_class) { |
155
|
45
|
|
|
|
|
1288
|
$self->add_listener( beforerender => RapidApp::JSONFunc->new( raw => 1, func => |
156
|
|
|
|
|
|
|
'Ext.ux.RapidApp.AppTab.cnt_init_loadTarget' |
157
|
|
|
|
|
|
|
)); |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
# -- Moved into Ext.ux.RapidApp.AppTab.AppGrid2Def: |
161
|
|
|
|
|
|
|
#if (defined $self->open_record_url) { |
162
|
|
|
|
|
|
|
# $self->add_listener( rowdblclick => RapidApp::JSONFunc->new( raw => 1, func => |
163
|
|
|
|
|
|
|
# 'Ext.ux.RapidApp.AppTab.gridrow_nav' |
164
|
|
|
|
|
|
|
# )); |
165
|
|
|
|
|
|
|
#} |
166
|
|
|
|
|
|
|
# -- |
167
|
|
|
|
|
|
|
|
168
|
52
|
100
|
|
|
|
1734
|
$self->apply_actions( save_search => 'save_search' ) if ( $self->can('save_search') ); |
169
|
52
|
100
|
|
|
|
1540
|
$self->apply_actions( delete_search => 'delete_search' ) if ( $self->can('delete_search') ); |
170
|
|
|
|
|
|
|
|
171
|
52
|
|
|
|
|
1258
|
$self->DataStore->add_read_raw_mungers(RapidApp::Handler->new( scope => $self, method => 'add_loadContentCnf_read_munger' )); |
172
|
|
|
|
|
|
|
|
173
|
52
|
|
|
|
|
292
|
$self->add_ONREQUEST_calls('init_onrequest'); |
174
|
52
|
|
|
|
|
253
|
$self->add_ONREQUEST_calls_late('init_delete_enable'); |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
sub init_onrequest { |
178
|
22
|
|
|
22
|
0
|
46
|
my $self = shift; |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
$self->apply_extconfig( preload_quick_search => $self->c->req->params->{quick_search} ) |
181
|
22
|
50
|
|
22
|
|
152
|
if (try{$self->c->req->params->{quick_search}}); |
|
22
|
|
|
|
|
580
|
|
182
|
|
|
|
|
|
|
|
183
|
22
|
|
|
22
|
|
1900
|
my $quick_search_cols = try{$self->c->req->params->{quick_search_cols}}; |
|
22
|
|
|
|
|
470
|
|
184
|
22
|
50
|
33
|
|
|
1647
|
if($quick_search_cols && $quick_search_cols ne '') { |
185
|
0
|
|
|
|
|
0
|
$quick_search_cols = lc($quick_search_cols); |
186
|
0
|
|
|
|
|
0
|
my @cols = split(/\s*,\s*/,$quick_search_cols); |
187
|
0
|
|
|
|
|
0
|
$self->apply_extconfig( init_quick_search_columns => \@cols ); |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
# Added for #94: |
191
|
22
|
50
|
|
22
|
|
118
|
if(my $qs_mode = try{$self->c->req->params->{quick_search_mode}}) { |
|
22
|
|
|
|
|
455
|
|
192
|
0
|
|
|
|
|
0
|
$self->apply_extconfig( init_quick_search_mode => $qs_mode ); |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
#$self->apply_config(store => $self->JsonStore); |
197
|
22
|
100
|
|
|
|
1645
|
$self->apply_extconfig(tbar => $self->tbar_items) if (defined $self->tbar_items); |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub init_delete_enable { |
203
|
22
|
|
|
22
|
0
|
50
|
my $self = shift; |
204
|
22
|
50
|
33
|
|
|
217
|
if($self->can('action_delete_records') and $self->has_flag('can_delete')) { |
205
|
|
|
|
|
|
|
#if($self->can('action_delete_records')) { |
206
|
0
|
|
|
|
|
0
|
my $act_name = 'delete_rows'; |
207
|
0
|
|
|
|
|
0
|
$self->apply_actions( $act_name => 'action_delete_records' ); |
208
|
0
|
|
|
|
|
0
|
$self->apply_extconfig( delete_url => $self->suburl($act_name) ); |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
sub add_loadContentCnf_read_munger { |
216
|
8
|
|
|
8
|
0
|
20
|
my $self = shift; |
217
|
8
|
|
|
|
|
15
|
my $result = shift; |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
# Add a 'loadContentCnf' field to store if open_record_class is defined. |
220
|
|
|
|
|
|
|
# This data is used when a row is double clicked on to open the open_record_class |
221
|
|
|
|
|
|
|
# module in the loadContent handler (JS side object). This is currently AppTab |
222
|
|
|
|
|
|
|
# but could be other JS classes that support the same API |
223
|
8
|
100
|
|
|
|
216
|
if (defined $self->open_record_url) { |
224
|
1
|
|
|
|
|
2
|
foreach my $record (@{$result->{rows}}) { |
|
1
|
|
|
|
|
7
|
|
225
|
0
|
|
|
|
|
0
|
my $loadCfg = {}; |
226
|
|
|
|
|
|
|
# support merging from existing loadContentCnf already contained in the record data: |
227
|
0
|
0
|
|
|
|
0
|
$loadCfg = $self->json->decode($record->{loadContentCnf}) if (defined $record->{loadContentCnf}); |
228
|
|
|
|
|
|
|
|
229
|
0
|
|
|
|
|
0
|
%{ $loadCfg } = ( |
230
|
0
|
|
|
|
|
0
|
%{ $self->get_record_loadContentCnf($record) }, |
231
|
0
|
|
|
|
|
0
|
%{ $loadCfg } |
|
0
|
|
|
|
|
0
|
|
232
|
|
|
|
|
|
|
); |
233
|
|
|
|
|
|
|
|
234
|
0
|
0
|
|
|
|
0
|
unless (defined $loadCfg->{autoLoad}) { |
235
|
0
|
|
|
|
|
0
|
$loadCfg->{autoLoad} = {}; |
236
|
0
|
0
|
|
|
|
0
|
$loadCfg->{autoLoad}->{url} = $loadCfg->{url} if ($loadCfg->{url}); |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
|
239
|
0
|
0
|
|
|
|
0
|
$loadCfg->{autoLoad}->{url} = $self->open_record_url unless (defined $loadCfg->{autoLoad}->{url}); |
240
|
|
|
|
|
|
|
|
241
|
0
|
|
|
|
|
0
|
$record->{loadContentCnf} = $self->json->encode($loadCfg); |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
#around 'store_read_raw' => sub { |
248
|
|
|
|
|
|
|
# my $orig = shift; |
249
|
|
|
|
|
|
|
# my $self = shift; |
250
|
|
|
|
|
|
|
# |
251
|
|
|
|
|
|
|
# my $result = $self->$orig(@_); |
252
|
|
|
|
|
|
|
# |
253
|
|
|
|
|
|
|
# # Add a 'loadContentCnf' field to store if open_record_class is defined. |
254
|
|
|
|
|
|
|
# # This data is used when a row is double clicked on to open the open_record_class |
255
|
|
|
|
|
|
|
# # module in the loadContent handler (JS side object). This is currently AppTab |
256
|
|
|
|
|
|
|
# # but could be other JS classes that support the same API |
257
|
|
|
|
|
|
|
# if (defined $self->open_record_class) { |
258
|
|
|
|
|
|
|
# foreach my $record (@{$result->{rows}}) { |
259
|
|
|
|
|
|
|
# my $loadCfg = {}; |
260
|
|
|
|
|
|
|
# # support merging from existing loadContentCnf already contained in the record data: |
261
|
|
|
|
|
|
|
# $loadCfg = $self->json->decode($record->{loadContentCnf}) if (defined $record->{loadContentCnf}); |
262
|
|
|
|
|
|
|
# |
263
|
|
|
|
|
|
|
# %{ $loadCfg } = ( |
264
|
|
|
|
|
|
|
# %{ $self->get_record_loadContentCnf($record) }, |
265
|
|
|
|
|
|
|
# %{ $loadCfg } |
266
|
|
|
|
|
|
|
# ); |
267
|
|
|
|
|
|
|
# |
268
|
|
|
|
|
|
|
# $loadCfg->{autoLoad} = {} unless (defined $loadCfg->{autoLoad}); |
269
|
|
|
|
|
|
|
# $loadCfg->{autoLoad}->{url} = $self->Module('item')->base_url unless (defined $loadCfg->{autoLoad}->{url}); |
270
|
|
|
|
|
|
|
# |
271
|
|
|
|
|
|
|
# |
272
|
|
|
|
|
|
|
# $record->{loadContentCnf} = $self->json->encode($loadCfg); |
273
|
|
|
|
|
|
|
# } |
274
|
|
|
|
|
|
|
# } |
275
|
|
|
|
|
|
|
# |
276
|
|
|
|
|
|
|
# return $result; |
277
|
|
|
|
|
|
|
#}; |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
sub options_menu_button_Id { |
280
|
84
|
|
|
84
|
0
|
150
|
my $self = shift; |
281
|
84
|
|
|
|
|
1938
|
return $self->instance_id . '-options-menu-btn'; |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
sub options_menu_items { |
285
|
43
|
|
|
43
|
0
|
71
|
my $self = shift; |
286
|
43
|
|
|
|
|
86
|
return undef; |
287
|
|
|
|
|
|
|
} |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
sub options_menu { |
291
|
43
|
|
|
43
|
0
|
68
|
my $self = shift; |
292
|
|
|
|
|
|
|
|
293
|
43
|
100
|
|
|
|
140
|
my $items = $self->options_menu_items or return undef; |
294
|
42
|
50
|
50
|
|
|
254
|
return undef unless (ref($items) eq 'ARRAY') && scalar(@$items); |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
# Make it easy to find the options menu on the client side (JS): |
297
|
42
|
|
|
|
|
959
|
my $menu_id = $self->instance_id . '-options-menu'; |
298
|
42
|
|
|
|
|
1298
|
$self->apply_extconfig('options_menu_id' => $menu_id ); |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
return { |
301
|
42
|
|
|
|
|
310
|
xtype => 'button', |
302
|
|
|
|
|
|
|
id => $self->options_menu_button_Id, |
303
|
|
|
|
|
|
|
text => 'Options', |
304
|
|
|
|
|
|
|
iconCls => 'ra-icon-gears', |
305
|
|
|
|
|
|
|
itemId => 'options-button', |
306
|
|
|
|
|
|
|
menu => { |
307
|
|
|
|
|
|
|
items => $items, |
308
|
|
|
|
|
|
|
id => $menu_id |
309
|
|
|
|
|
|
|
} |
310
|
|
|
|
|
|
|
}; |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
sub tbar_items { |
316
|
43
|
|
|
43
|
0
|
75
|
my $self = shift; |
317
|
|
|
|
|
|
|
|
318
|
43
|
|
|
|
|
73
|
my $arrayref = []; |
319
|
|
|
|
|
|
|
|
320
|
43
|
50
|
|
|
|
1075
|
push @$arrayref, '<img src="' . $self->title_icon_href . '" />' if (defined $self->title_icon_href); |
321
|
43
|
50
|
|
|
|
985
|
push @$arrayref, '<b>' . $self->title . '</b>' if (defined $self->title); |
322
|
|
|
|
|
|
|
|
323
|
43
|
|
|
|
|
120
|
my $menu = $self->options_menu; |
324
|
43
|
50
|
66
|
|
|
189
|
push @$arrayref, ' ', '-' if (defined $menu and scalar(@$arrayref) > 0); |
325
|
43
|
100
|
|
|
|
111
|
push @$arrayref, $menu if (defined $menu); |
326
|
|
|
|
|
|
|
|
327
|
43
|
|
|
|
|
67
|
push @$arrayref, '->'; |
328
|
|
|
|
|
|
|
|
329
|
43
|
50
|
33
|
|
|
1058
|
push @$arrayref, $self->add_button if ( |
330
|
|
|
|
|
|
|
defined $self->add_record_class and |
331
|
|
|
|
|
|
|
$self->show_add_button |
332
|
|
|
|
|
|
|
); |
333
|
|
|
|
|
|
|
|
334
|
43
|
100
|
|
|
|
737
|
return (scalar @$arrayref > 1) ? $arrayref : undef; |
335
|
|
|
|
|
|
|
} |
336
|
0
|
|
|
0
|
0
|
|
sub show_add_button { 1 } |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
sub add_button { |
339
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
my $loadCfg = { |
342
|
|
|
|
|
|
|
url => $self->suburl('add'), |
343
|
0
|
|
|
|
|
|
%{ $self->add_loadContentCnf } |
|
0
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
}; |
345
|
|
|
|
|
|
|
|
346
|
0
|
|
|
|
|
|
my $handler = RapidApp::JSONFunc->new( raw => 1, func => |
347
|
|
|
|
|
|
|
'function(btn) { btn.ownerCt.ownerCt.loadTargetObj.loadContent(' . $self->json->encode($loadCfg) . '); }' |
348
|
|
|
|
|
|
|
); |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
return RapidApp::JSONFunc->new( func => 'new Ext.Button', parm => { |
351
|
|
|
|
|
|
|
handler => $handler, |
352
|
0
|
|
|
|
|
|
%{ $self->add_button_cnf } |
|
0
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
}); |
354
|
|
|
|
|
|
|
} |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
sub set_all_columns_hidden { |
360
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
361
|
0
|
|
|
|
|
|
return $self->apply_to_all_columns( |
362
|
|
|
|
|
|
|
hidden => \1 |
363
|
|
|
|
|
|
|
); |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
sub set_columns_visible { |
368
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
369
|
0
|
0
|
|
|
|
|
my @cols = (ref($_[0]) eq 'ARRAY') ? @{ $_[0] } : @_; # <-- arg as array or arrayref |
|
0
|
|
|
|
|
|
|
370
|
0
|
|
|
|
|
|
return $self->apply_columns_list(\@cols,{ |
371
|
|
|
|
|
|
|
hidden => \0 |
372
|
|
|
|
|
|
|
}); |
373
|
|
|
|
|
|
|
} |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
#### --------------------- #### |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
|
380
|
4
|
|
|
4
|
|
57
|
no Moose; |
|
4
|
|
|
|
|
12
|
|
|
4
|
|
|
|
|
20
|
|
381
|
|
|
|
|
|
|
#__PACKAGE__->meta->make_immutable; |
382
|
|
|
|
|
|
|
1; |