]> git.proxmox.com Git - extjs.git/blame - extjs/build/examples/classic/personel-review/reviewapp.js
add extjs 6.0.1 sources
[extjs.git] / extjs / build / examples / classic / personel-review / reviewapp.js
CommitLineData
6527f429
DM
1Ext.require([\r
2 '*'\r
3]);\r
4\r
5Ext.BLANK_IMAGE_URL = '../libs/ext-4.0/resources/themes/images/default/tree/s.gif';\r
6\r
7Ext.onReady(function() {\r
8\r
9 // Employee Data Model\r
10 Ext.regModel('Employee', {\r
11 fields: [\r
12 {name:'id', type:'int'},\r
13 {name:'first_name', type:'string'},\r
14 {name:'last_name', type:'string'},\r
15 {name:'title', type:'string'}\r
16 ],\r
17 \r
18 hasMany: {model:'Review', name:'reviews'}\r
19 });\r
20 \r
21 // Review Data Model \r
22 Ext.regModel('Review', {\r
23 fields: [\r
24 {name:'review_date', label:'Date', type:'date', dateFormat:'d-m-Y'},\r
25 {name:'attendance', label:'Attendance', type:'int'},\r
26 {name:'attitude', label:'Attitude', type:'int'},\r
27 {name:'communication', label:'Communication', type:'int'},\r
28 {name:'excellence', label:'Excellence', type:'int'},\r
29 {name:'skills', label:'Skills', type:'int'},\r
30 {name:'teamwork', label:'Teamwork', type:'int'},\r
31 {name:'employee_id', label:'Employee ID', type:'int'}\r
32 ],\r
33 \r
34 belongsTo: 'Employee'\r
35 });\r
36 \r
37 // Instance of a Data Store to hold Employee records\r
38 var employeeStore = new Ext.data.Store({\r
39 storeId:'employeeStore',\r
40 model:'Employee',\r
41 data:[\r
42 {id:1, first_name:'Michael', last_name:'Scott', title:'Regional Manager'},\r
43 {id:2, first_name:'Dwight', last_name:'Schrute', title:'Sales Rep'},\r
44 {id:3, first_name:'Jim', last_name:'Halpert', title:'Sales Rep'},\r
45 {id:4, first_name:'Pam', last_name:'Halpert', title:'Office Administrator'},\r
46 {id:5, first_name:'Andy', last_name:'Bernard', title:'Sales Rep'},\r
47 {id:6, first_name:'Stanley', last_name:'Hudson', title:'Sales Rep'},\r
48 {id:7, first_name:'Phyllis', last_name:'Lapin-Vance', title:'Sales Rep'},\r
49 {id:8, first_name:'Kevin', last_name:'Malone', title:'Accountant'},\r
50 {id:9, first_name:'Angela', last_name:'Martin', title:'Senior Accountant'}, \r
51 {id:10, first_name:'Meredith', last_name:'Palmer', title:'Supplier Relations Rep'} \r
52 ],\r
53 autoLoad:true \r
54 }); \r
55 \r
56 /**\r
57 * App.RadarStore\r
58 * @extends Ext.data.Store\r
59 * This is a specialized Data Store with dynamically generated fields\r
60 * data reformating capabilities to transform Employee and Review data\r
61 * into the format required by the Radar Chart.\r
62 *\r
63 * The constructor demonstrates dynamically generating store fields.\r
64 * populateReviewScores() populates the store using records from \r
65 * the reviewStore which holds all the employee review scores.\r
66 *\r
67 * calculateAverageScores() iterates through each metric in the\r
68 * review and calculates an average across all available reviews.\r
69 * \r
70 * Most of the actual data population and updates done by\r
71 * addUpdateRecordFromReviews() and removeRecordFromReviews()\r
72 * called when add/update/delete events are triggered on the ReviewStore. \r
73 */ \r
74 Ext.define('App.RadarStore', {\r
75 extend: 'Ext.data.Store',\r
76 \r
77 constructor: function(config) {\r
78 config = config || {};\r
79 var dynamicFields = ['metric', 'avg']; // initalize the non-dynamic fields first\r
80\r
81 employeeStore.each(function(record){ // loops through all the employees to setup the dynamic fields\r
82 dynamicFields.push('eid_' + record.get('id'));\r
83 });\r
84 \r
85 Ext.apply(config, {\r
86 storeId:'radarStore', // let's us look it up later using Ext.data.StoreMgr.lookup('radarStore')\r
87 fields:dynamicFields,\r
88 data:[]\r
89 });\r
90 \r
91 App.RadarStore.superclass.constructor.call(this, config);\r
92 },\r
93 \r
94 addUpdateRecordFromReviews: function(reviews) {\r
95 var me = this;\r
96 \r
97 Ext.Array.each(reviews, function(review, recordIndex, all) { // add a new radarStore record for each review record \r
98 var eid = 'eid_' + review.get('employee_id'); // creates a unique id for each employee column in the store \r
99 \r
100 review.fields.each(function(field) {\r
101 \r
102 if(field.name !== "employee_id" && field.name !== "review_date") { // filter out the fields we don't need\r
103 var metricRecord = me.findRecord('metric', field.name); // checks for an existing metric record in the store\r
104 if(metricRecord) {\r
105 metricRecord.set(eid, review.get(field.name)); // updates existing record with field value from review\r
106 } else {\r
107 var newRecord = {}; // creates a new object we can populate with dynamic keys and values to create a new record\r
108 newRecord[eid] = review.get(field.name);\r
109 newRecord['metric'] = field.label;\r
110 me.add(newRecord);\r
111 }\r
112 }\r
113 });\r
114 });\r
115 \r
116 this.calculateAverageScores(); // update average scores\r
117 },\r
118 \r
119 /**\r
120 * Calculates an average for each metric across all employees.\r
121 * We use this to create the average series always shown in the Radar Chart. \r
122 */ \r
123 calculateAverageScores: function() {\r
124 var me = this; // keeps the store in scope during Ext.Array.each\r
125 var reviewStore = Ext.data.StoreMgr.lookup('reviewStore');\r
126 \r
127 var Review = Ext.ModelMgr.getModel('Review');\r
128 \r
129 Ext.Array.each(Review.prototype.fields.keys, function(fieldName) { // loop through the Review model fields and calculate average scores\r
130 if(fieldName !== "employee_id" && fieldName !== "review_date") { // ignore non-score fields\r
131 var avgScore = Math.round(reviewStore.average(fieldName)); // takes advantage of Ext.data.Store.average()\r
132 var record = me.findRecord('metric', fieldName);\r
133 \r
134 if(record) {\r
135 record.set('avg', avgScore);\r
136 } else {\r
137 me.add({metric:fieldName, avg:avgScore});\r
138 }\r
139 }\r
140 });\r
141 },\r
142 \r
143 populateReviewScores: function() {\r
144 var reviewStore = Ext.data.StoreMgr.lookup('reviewStore');\r
145 this.addUpdateRecordFromReviews(reviewStore.data.items); // add all the review records to this store\r
146 },\r
147 \r
148 removeRecordFromReviews: function(reviews) {\r
149 var me = this;\r
150 Ext.Array.each(reviews, function(review, recordIndex, all) {\r
151 var eid = 'eid_' + review.get('employee_id');\r
152 \r
153 me.each(function(record) {\r
154 delete record.data[eid];\r
155 });\r
156 });\r
157 \r
158 // upate average scores\r
159 this.calculateAverageScores(); \r
160 }\r
161 }); // end App.RadarStore definition\r
162 \r
163 \r
164 /** Creates an instance of App.RadarStore here so we\r
165 * here so we can re-use it during the life of the app.\r
166 * Otherwise we'd have to create a new instance everytime\r
167 * refreshRadarChart() is run.\r
168 */\r
169 var radarStore = new App.RadarStore();\r
170 \r
171 var reviewStore = new Ext.data.Store({\r
172 storeId:'reviewStore',\r
173 model:'Review',\r
174 data:[\r
175 {review_date:'01-04-2011', attendance:10, attitude:6, communication:6, excellence:3, skills:3, teamwork:3, employee_id:1},\r
176 {review_date:'01-04-2011', attendance:6, attitude:5, communication:2, excellence:8, skills:9, teamwork:5, employee_id:2},\r
177 {review_date:'01-04-2011', attendance:5, attitude:4, communication:3, excellence:5, skills:6, teamwork:2, employee_id:3},\r
178 {review_date:'01-04-2011', attendance:8, attitude:2, communication:4, excellence:2, skills:5, teamwork:6, employee_id:4},\r
179 {review_date:'01-04-2011', attendance:4, attitude:1, communication:5, excellence:7, skills:5, teamwork:5, employee_id:5},\r
180 {review_date:'01-04-2011', attendance:5, attitude:2, communication:4, excellence:7, skills:9, teamwork:8, employee_id:6},\r
181 {review_date:'01-04-2011', attendance:10, attitude:7, communication:8, excellence:7, skills:3, teamwork:4, employee_id:7}, \r
182 {review_date:'01-04-2011', attendance:10, attitude:8, communication:8, excellence:4, skills:8, teamwork:7, employee_id:8},\r
183 {review_date:'01-04-2011', attendance:6, attitude:4, communication:9, excellence:7, skills:6, teamwork:5, employee_id:9},\r
184 {review_date:'01-04-2011', attendance:7, attitude:5, communication:9, excellence:4, skills:2, teamwork:4, employee_id:10} \r
185 ],\r
186 listeners: {\r
187 add:function(store, records, storeIndex) {\r
188 var radarStore = Ext.data.StoreMgr.lookup('radarStore');\r
189 \r
190 if(radarStore) { // only add records if an instance of the rardarStore already exists\r
191 radarStore.addUpdateRecordFromReviews(records); // add a new radarStore records for new review records \r
192 }\r
193 }, // end add listener\r
194 update: function(store, record, operation) {\r
195 radarStore.addUpdateRecordFromReviews([record]);\r
196 refreshRadarChart();\r
197 },\r
198 remove: function(store, records, storeIndex) {\r
199 // update the radarStore and regenerate the radarChart\r
200 Ext.data.StoreMgr.lookup('radarStore').removeRecordFromReviews(records);\r
201 refreshRadarChart();\r
202 } // end remove listener\r
203 }\r
204 });\r
205 \r
206 /**\r
207 * App.PerformanceRadar\r
208 * @extends Ext.chart.Chart\r
209 * This is a specialized Radar Chart which we use to display employee \r
210 * performance reviews.\r
211 *\r
212 * The class will be registered with an xtype of 'performanceradar'\r
213 */ \r
214 Ext.define('App.PerformanceRadar', {\r
215 extend: 'Ext.chart.Chart',\r
216 alias: 'widget.performanceradar', // register xtype performanceradar\r
217 constructor: function(config) {\r
218 config = config || {};\r
219 \r
220 this.setAverageSeries(config); // make sure average is always present\r
221 \r
222 Ext.apply(config, {\r
223 id:'radarchart',\r
224 theme:'Category2',\r
225 animate:true,\r
226 store: Ext.data.StoreMgr.lookup('radarStore'),\r
227 margin:'0 0 50 0',\r
228 width:350,\r
229 height:500,\r
230 insetPadding:80,\r
231 legend:{\r
232 position: 'bottom'\r
233 },\r
234 axes: [{\r
235 type:'Radial',\r
236 position:'radial',\r
237 label:{\r
238 display: true\r
239 }\r
240 }]\r
241 }); // end Ext.apply\r
242 \r
243 App.PerformanceRadar.superclass.constructor.call(this, config);\r
244 \r
245 }, // end constructor\r
246 \r
247 setAverageSeries: function(config) {\r
248 var avgSeries = {\r
249 type: 'radar',\r
250 xField: 'metric',\r
251 yField: 'avg',\r
252 title: 'Avg',\r
253 labelDisplay:'over',\r
254 showInLegend: true,\r
255 showMarkers: true,\r
256 markerCfg: {\r
257 radius: 5,\r
258 size: 5,\r
259 stroke:'#0677BD',\r
260 fill:'#0677BD'\r
261 },\r
262 style: {\r
263 'stroke-width': 2,\r
264 'stroke':'#0677BD',\r
265 fill: 'none'\r
266 }\r
267 };\r
268 \r
269 if(config.series) { \r
270 config.series.push(avgSeries); // if a series is passed in then append the average to it\r
271 } else { \r
272 config.series = [avgSeries]; // if a series isn't passed just create average\r
273 }\r
274 } \r
275 \r
276 }); // end Ext.ux.Performance radar definition\r
277 \r
278 /**\r
279 * App.EmployeeDetail\r
280 * @extends Ext.Panel\r
281 * This is a specialized Panel which is used to show information about\r
282 * an employee and the reviews we have on record for them.\r
283 *\r
284 * This demonstrates adding 2 custom properties (tplMarkup and\r
285 * startingMarkup) to the class. It also overrides the initComponent\r
286 * method and adds a new method called updateDetail.\r
287 *\r
288 * The class will be registered with an xtype of 'employeedetail'\r
289 */\r
290 Ext.define('App.EmployeeDetail', {\r
291 extend: 'Ext.panel.Panel',\r
292 // register the App.EmployeeDetail class with an xtype of employeedetail\r
293 alias: 'widget.employeedetail',\r
294 // add tplMarkup as a new property\r
295 tplMarkup: [\r
296 '<b>{first_name}&nbsp;{last_name}</b>&nbsp;&nbsp;',\r
297 'Title: {title}<br/><br/>',\r
298 '<b>Last Review</b>&nbsp;&nbsp;',\r
299 'Attendance:&nbsp;{attendance}&nbsp;&nbsp;',\r
300 'Attitude:&nbsp;{attitude}&nbsp;&nbsp;',\r
301 'Communication:&nbsp;{communication}&nbsp;&nbsp;',\r
302 'Excellence:&nbsp;{excellence}&nbsp;&nbsp;',\r
303 'Skills:&nbsp;{skills}&nbsp;&nbsp;',\r
304 'Teamwork:&nbsp;{teamwork}' \r
305 ],\r
306 \r
307 height:90,\r
308 bodyPadding: 7,\r
309 // override initComponent to create and compile the template\r
310 // apply styles to the body of the panel\r
311 initComponent: function() {\r
312 this.tpl = new Ext.Template(this.tplMarkup);\r
313 \r
314 // call the superclass's initComponent implementation\r
315 App.EmployeeDetail.superclass.initComponent.call(this);\r
316 }\r
317 });\r
318 \r
319 Ext.define('App.ReviewWindow', {\r
320 extend: 'Ext.window.Window',\r
321\r
322 constructor: function(config) { \r
323 config = config || {};\r
324 Ext.apply(config, { \r
325 title:'Employee Performance Review',\r
326 width:320,\r
327 height:420,\r
328 layout:'fit', \r
329 items:[{\r
330 xtype:'form',\r
331 id:'employeereviewcomboform',\r
332 fieldDefaults: {\r
333 labelAlign: 'left',\r
334 labelWidth: 90,\r
335 anchor: '100%'\r
336 }, \r
337 bodyPadding:5,\r
338 items:[{\r
339 xtype:'fieldset',\r
340 title:'Employee Info',\r
341 items:[{\r
342 xtype:'hiddenfield',\r
343 name:'employee_id'\r
344 },{\r
345 xtype:'textfield',\r
346 name:'first_name',\r
347 fieldLabel:'First Name',\r
348 allowBlank:false\r
349 },{\r
350 xtype:'textfield',\r
351 name:'last_name',\r
352 fieldLabel:'Last Name',\r
353 allowBlank:false \r
354 },{\r
355 xtype:'textfield',\r
356 name:'title',\r
357 fieldLabel:'Title',\r
358 allowBlank:false \r
359 }]\r
360 },{\r
361 xtype:'fieldset',\r
362 title:'Performance Review',\r
363 items:[{\r
364 xtype:'datefield',\r
365 name:'review_date',\r
366 fieldLabel:'Review Date',\r
367 format:'d-m-Y', \r
368 maxValue: new Date(),\r
369 value: new Date(),\r
370 allowBlank:false\r
371 },{\r
372 xtype:'slider',\r
373 name:'attendance',\r
374 fieldLabel:'Attendance', \r
375 value:5,\r
376 increment:1,\r
377 minValue:1,\r
378 maxValue:10\r
379 },{\r
380 xtype:'slider',\r
381 name:'attitude',\r
382 fieldLabel:'Attitude',\r
383 value:5,\r
384 minValue: 1,\r
385 maxValue: 10\r
386 },{\r
387 xtype:'slider',\r
388 name:'communication',\r
389 fieldLabel:'Communication', \r
390 value:5,\r
391 increment:1,\r
392 minValue:1,\r
393 maxValue:10\r
394 },{\r
395 xtype:'numberfield',\r
396 name:'excellence',\r
397 fieldLabel:'Excellence',\r
398 value:5,\r
399 minValue: 1,\r
400 maxValue: 10 \r
401 },{\r
402 xtype:'numberfield',\r
403 name:'skills',\r
404 fieldLabel:'Skills',\r
405 value:5,\r
406 minValue: 1,\r
407 maxValue: 10 \r
408 },{\r
409 xtype:'numberfield',\r
410 name:'teamwork',\r
411 fieldLabel:'Teamwork',\r
412 value:5,\r
413 minValue: 1,\r
414 maxValue: 10 \r
415 }]\r
416 }]\r
417 }],\r
418 buttons:[{\r
419 text:'Cancel',\r
420 width:80,\r
421 handler:function() {\r
422 this.up('window').close();\r
423 }\r
424 },\r
425 {\r
426 text:'Save',\r
427 width:80,\r
428 handler:function(btn, eventObj) {\r
429 var window = btn.up('window');\r
430 var form = window.down('form').getForm();\r
431 \r
432 if (form.isValid()) {\r
433 window.getEl().mask('saving data...');\r
434 var vals = form.getValues();\r
435 var employeeStore = Ext.data.StoreMgr.lookup('employeeStore');\r
436 var currentEmployee = employeeStore.findRecord('id', vals['employee_id']);\r
437 \r
438 // look up id for this employee to see if they already exist\r
439 if(vals['employee_id'] && currentEmployee) {\r
440 currentEmployee.set('first_name', vals['first_name']);\r
441 currentEmployee.set('last_name', vals['last_name']);\r
442 currentEmployee.set('title', vals['title']);\r
443 \r
444 var currentReview = Ext.data.StoreMgr.lookup('reviewStore').findRecord('employee_id', vals['employee_id']);\r
445 currentReview.set('review_date', vals['review_date']);\r
446 currentReview.set('attendance', vals['attendance']);\r
447 currentReview.set('attitude', vals['attitude']);\r
448 currentReview.set('communication', vals['communication']);\r
449 currentReview.set('excellence', vals['excellence']);\r
450 currentReview.set('skills', vals['skills']);\r
451 currentReview.set('teamwork', vals['teamwork']); \r
452 } else {\r
453 var newId = employeeStore.getCount() + 1; \r
454 \r
455 employeeStore.add({\r
456 id: newId,\r
457 first_name: vals['first_name'],\r
458 last_name: vals['last_name'],\r
459 title: vals['title']\r
460 });\r
461 \r
462 Ext.data.StoreMgr.lookup('reviewStore').add({\r
463 review_date: vals['review_date'],\r
464 attendance: vals['attendance'],\r
465 attitude: vals['attitude'],\r
466 communication: vals['communication'],\r
467 excellence: vals['excellence'],\r
468 skills: vals['skills'],\r
469 teamwork: vals['teamwork'],\r
470 employee_id: newId\r
471 });\r
472 }\r
473 window.getEl().unmask();\r
474 window.close();\r
475 }\r
476 }\r
477 }]\r
478 }); // end Ext.apply\r
479 \r
480 App.ReviewWindow.superclass.constructor.call(this, config);\r
481 \r
482 } // end constructor\r
483 \r
484 });\r
485\r
486 \r
487 // adds a record to the radar chart store and \r
488 // creates a series in the chart for selected employees\r
489 function refreshRadarChart(employees) { \r
490 employees = employees || []; // in case its called with nothing we'll at least have an empty array\r
491 var existingRadarChart = Ext.getCmp('radarchart'); // grab the radar chart component (used down below)\r
492 var reportsPanel = Ext.getCmp('reportspanel'); // grab the reports panel component (used down below)\r
493 var dynamicSeries = []; // setup an array of chart series that we'll create dynamically\r
494 \r
495 for(var index = 0; index < employees.length; index++) {\r
496 var fullName = employees[index].get('first_name') + ' ' + employees[index].get('last_name');\r
497 var eid = 'eid_' + employees[index].get('id');\r
498 \r
499 // add to the dynamic series we're building\r
500 dynamicSeries.push({\r
501 type: 'radar',\r
502 title: fullName,\r
503 xField: 'metric',\r
504 yField: eid,\r
505 labelDisplay: 'over',\r
506 showInLegend: true,\r
507 showMarkers: true,\r
508 markerCfg: {\r
509 radius: 5,\r
510 size: 5\r
511 },\r
512 style: {\r
513 'stroke-width': 2,\r
514 fill: 'none'\r
515 }\r
516 });\r
517 \r
518 } // end for loop\r
519 \r
520 // destroy the existing chart\r
521 existingRadarChart.destroy();\r
522 // create the new chart using the dynamic series we just made\r
523 var newRadarChart = new App.PerformanceRadar({series:dynamicSeries});\r
524 // mask the panel while we switch out charts\r
525 reportsPanel.getEl().mask('updating chart...');\r
526 // display the new one\r
527 reportsPanel.add(newRadarChart);\r
528 // un mask the reports panel\r
529 reportsPanel.getEl().unmask();\r
530 }\r
531 \r
532 function refreshEmployeeDetails(employees) {\r
533 var detailsPanel = Ext.getCmp('detailspanel');\r
534 var reviewStore = Ext.data.StoreMgr.lookup('reviewStore');\r
535 var items = [];\r
536 \r
537 for(var index = 0; index < employees.length; index++) {\r
538 var templateData = Ext.applyIf(employees[index].data, reviewStore.findRecord('employee_id', employees[index].get('id')).data);\r
539 var employeePanel = new App.EmployeeDetail({\r
540 title:employees[index].get('first_name') + ' ' + employees[index].get('last_name'),\r
541 data:templateData // combined employee and latest review dataTransfer\r
542 });\r
543 items.push(employeePanel);\r
544 }\r
545 \r
546 detailsPanel.getEl().mask('updating details...');\r
547 detailsPanel.removeAll();\r
548 detailsPanel.add(items);\r
549 detailsPanel.getEl().unmask();\r
550 }\r
551 \r
552 // sets Up Checkbox Selection Model for the Employee Grid\r
553 var checkboxSelModel = new Ext.selection.CheckboxModel();\r
554 \r
555 var viewport = new Ext.container.Viewport({\r
556 id:'mainviewport',\r
557 layout: 'border', // sets up Ext.layout.container.Border\r
558 items: [{\r
559 xtype:'panel',\r
560 region:'center',\r
561 layout:'auto',\r
562 scrollable:true,\r
563 title:'Employee Performance Manager',\r
564 tbar:[{\r
565 text:'Add Employee',\r
566 tooltip:'Add a new employee',\r
567 iconCls:'add',\r
568 handler:function() { // display a window to add a new employee\r
569 new App.ReviewWindow().show();\r
570 }\r
571 }],\r
572 items:[{\r
573 xtype:'grid',\r
574 store:Ext.data.StoreMgr.lookup('employeeStore'),\r
575 height:300,\r
576 columns:[{\r
577 text:'First Name',\r
578 dataIndex:'first_name',\r
579 flex:2\r
580 },\r
581 {\r
582 text:'Last Name',\r
583 dataIndex:'last_name',\r
584 flex:2\r
585 },\r
586 {\r
587 text:'Title',\r
588 dataIndex:'title',\r
589 flex:3\r
590 },\r
591 {\r
592 xtype:'actioncolumn',\r
593 width:45,\r
594 items:[{\r
595 icon:'images/edit.png',\r
596 tooltip:'Edit Employee',\r
597 handler:function(grid, rowIndex, colIndex) {\r
598 var employee = grid.getStore().getAt(rowIndex);\r
599 var review = reviewStore.findRecord('employee_id', employee.get('id'));\r
600 var win = new App.ReviewWindow({hidden:true});\r
601 var form = win.down('form').getForm();\r
602 form.loadRecord(employee);\r
603 form.loadRecord(review);\r
604 win.show();\r
605 }\r
606 },\r
607 {\r
608 icon:'images/delete.png',\r
609 tooltip:'Delete Employee',\r
610 width:75,\r
611 handler:function(grid, rowIndex, colIndex) {\r
612 Ext.Msg.confirm('Remove Employee?', 'Are you sure you want to remove this employee?',\r
613 function(choice) {\r
614 if(choice === 'yes') {\r
615 var reviewStore = Ext.data.StoreMgr.lookup('reviewStore');\r
616 \r
617 var employee = grid.getStore().getAt(rowIndex);\r
618 var reviewIndex = reviewStore.find('employee_id', employee.get('id'));\r
619 reviewStore.removeAt(reviewIndex);\r
620 grid.getStore().removeAt(rowIndex);\r
621 }\r
622 }\r
623 ); \r
624 }\r
625 }]\r
626 }],\r
627 selModel: new Ext.selection.CheckboxModel(),\r
628 columnLines: true,\r
629 viewConfig: {stripeRows:true},\r
630 listeners:{\r
631 selectionchange:function(selModel, selected) {\r
632 refreshRadarChart(selected);\r
633 refreshEmployeeDetails(selected);\r
634 }\r
635 }\r
636 },{\r
637 xtype:'container',\r
638 id:'detailspanel',\r
639 layout:{\r
640 type:'vbox',\r
641 align:'stretch',\r
642 autoSize:true\r
643 }\r
644 }]\r
645 },{\r
646 xtype:'panel', // sets up the chart panel (starts collapsed)\r
647 region:'east',\r
648 id:'reportspanel',\r
649 title:'Performance Report',\r
650 width:350,\r
651 layout: 'fit',\r
652 items:[{\r
653 xtype:'performanceradar' // this instantiates a App.PerformanceRadar object\r
654 }]\r
655 }] // mainviewport items array ends here\r
656 });\r
657 \r
658});