1 Ext.ns('Gilbert.lib.plugins.models.ui');
4 Ext.override(Gilbert.lib.models.Model, {
5 create_new_form: function (callback, config) {
8 model.api.get_form({}, function (formspec) {
9 var formspec = formspec;
10 for (var item_index in formspec.items) {
11 var item = formspec.items[item_index];
16 var form_panel = new Gilbert.lib.ui.DjangoForm(Ext.applyIf(Ext.applyIf(config||{},{
17 title: 'New '+model.verbose_name,
23 submit: model.api.save_form,
29 create_edit_form: function (callback, pk, config) {
32 model.api.get_form({'pk': pk}, function (formspec) {
33 var formspec = formspec;
34 for (var item_index in formspec.items) {
35 var item = formspec.items[item_index];
40 callback(new Gilbert.lib.ui.DjangoForm(Ext.applyIf(Ext.applyIf(config||{},{
41 title: 'Editing '+model.verbose_name.capfirst()+' ('+pk+')',
43 iconCls: 'icon-pencil',
47 submit: model.api.save_form,
58 Gilbert.lib.plugins.models.ui.ForeignKeyColumn = Ext.extend(Ext.grid.Column, {
59 renderer: function(v) {
65 Ext.grid.Column.types['foreignkeycolumn'] = Gilbert.lib.plugins.models.ui.ForeignKeyColumn
68 Gilbert.lib.plugins.models.ui.ModelPanel = Ext.extend(Ext.Panel, {
69 constructor: function (model, plugin, config) {
70 var model = this.model = model;
71 var plugin = this.plugin = plugin;
72 var application = this.application = plugin.application;
75 var store = this.store = model.create_store({
85 var grid = this.grid = new Ext.grid.GridPanel({
86 ddGroup: model.drag_drop_group,
90 columns: model.columns,
96 selModel: new Ext.grid.RowSelectionModel(),
97 bbar: new Ext.PagingToolbar({
101 displayMsg: 'Displaying '+model.verbose_name_plural+' {0} - {1} of {2}',
102 emptyMsg: 'No '+model.verbose_name_plural+' to display',
103 items: (function () {
104 if (model.searchable) {
107 xtype: 'tbseparator',
109 new Ext.ux.form.SearchField({
120 var new_action = this.new_action = new Ext.Action({
121 text: 'New ' + model.verbose_name,
122 iconCls: 'icon-plus',
123 handler: function () {
124 plugin.create_instance_window(model, undefined, function (win) {
125 win.on('saved', function () {
133 var edit_action = this.edit_action = new Ext.Action({
136 iconCls: 'icon-pencil',
137 handler: function () {
138 Ext.each(grid.getSelectionModel().getSelections(), function (record, index) {
139 plugin.create_instance_window(model, record.id, function (win) {
140 win.on('saved', function () {
149 var delete_action = this.delete_action = new Ext.Action({
152 iconCls: 'icon-minus',
153 handler: function () {
154 var records = grid.getSelectionModel().getSelections();
156 Ext.each(records, function (record, index) {
159 model.api.data_destroy_consequences(pks, function (consequences) {
160 var convert_consequences_array = function (consequences) {
161 var last_parent = consequences[0];
162 Ext.each(consequences, function (consequence, index) {
164 if (!Ext.isArray(consequence)) {
165 last_parent = consequence;
167 last_parent['children'] = convert_consequences_array(consequence);
168 delete consequences[index];
172 new_consequences = [];
173 Ext.each(consequences, function (consequence) {
175 var new_consequence = {};
176 if (!consequence['children']) {
177 new_consequence['leaf'] = true;
179 new_consequence['leaf'] = false;
180 new_consequence['children'] = consequence['children'];
182 var app_label = consequence['app_label'];
183 var name = consequence['name'];
184 var model = Gilbert.get_model(app_label, name);
186 new_consequence['text'] = consequence['__unicode__'];
187 new_consequence['iconCls'] = model.iconCls;
189 new_consequence['text'] = '(' + consequence['name'] + ') ' + consequence['__unicode__'];
190 new_consequence['iconCls'] = 'icon-block';
192 new_consequence['disabled'] = true;
193 new_consequences.push(new_consequence);
196 return new_consequences;
199 var new_consequences = convert_consequences_array(consequences);
200 var nested_consequences = false;
201 for(var i=0;i<new_consequences.length;i++){
202 if (!new_consequences[i]['leaf']) {
203 nested_consequences = true;
208 var tree = this.tree = new Ext.tree.TreePanel({
209 loader: new Ext.tree.TreeLoader(),
212 trackMouseOver: false,
216 'text': 'To be deleted',
217 'iconCls': 'icon-minus',
219 'children': new_consequences,
226 var consequences_win = application.create_window({
231 title: 'Delete ' + model.verbose_name_plural,
232 iconCls: 'icon-minus',
237 html: 'Are you sure you want to delete these ' + model.verbose_name_plural + '?' + (nested_consequences ? ' Nested objects will also be deleted.' : ''),
238 bodyStyle: 'padding: 15px;',
246 handler: function () {
247 consequences_win.close();
254 handler: function () {
255 consequences_win.close();
256 store.remove(records);
264 consequences_win.show();
269 grid.on('cellcontextmenu', function (grid, rowIndex, cellIndex, e) {
271 selmodel = grid.getSelectionModel();
272 if (!selmodel.isSelected(rowIndex)) {
273 selmodel.selectRow(rowIndex, false);
275 var contextmenu = new Ext.menu.Menu({
281 contextmenu.showAt(e.xy);
284 grid.on('rowdblclick', function(grid, rowIndex, e) {
285 var record = grid.getStore().getAt(rowIndex)
286 plugin.create_instance_window(model, record.id, function (win) {
287 win.on('saved', function () {
294 grid.getSelectionModel().on('selectionchange', function (selmodel) {
295 if (selmodel.hasSelection()) {
296 edit_action.setDisabled(false);
297 delete_action.setDisabled(false);
299 edit_action.setDisabled(true);
300 delete_action.setDisabled(true);
304 Gilbert.lib.plugins.models.ui.ModelPanel.superclass.constructor.call(this, Ext.applyIf(config||{}, {
306 tbar: new Ext.Toolbar({
309 { xtype: 'tbseparator' },
315 // iconCls: 'icon-gear',
327 Gilbert.lib.plugins.models.Plugin = Ext.extend(Gilbert.lib.plugins.Plugin, {
329 init: function (application) {
330 Gilbert.lib.plugins.models.Plugin.superclass.init.call(this, application);
332 var new_menu = this.new_menu = new Ext.menu.Menu();
333 var manage_menu = this.manage_menu = new Ext.menu.Menu();
335 application.mainmenu.insert(2, {
337 iconCls: 'icon-plus',
342 application.mainmenu.insert(3, {
344 iconCls: 'icon-databases',
349 application.do_layout();
351 Ext.iterate(application.models, function (app_label, models) {
352 Ext.iterate(models, function (name, model) {
353 this.handle_new_model(model);
357 application.on('model_registered', function (model) {
358 this.handle_new_model(model);
361 this.instance_windows = {}
364 handle_new_model: function (model) {
366 model.api.has_add_permission(function (has_add_permission) {
367 if (has_add_permission) {
368 outer.add_to_new_menu(model);
371 model.api.has_read_permission(function (has_read_permission) {
372 if (has_read_permission) {
373 outer.add_to_manage_menu(model);
378 add_to_new_menu: function (model) {
381 text: model.verbose_name.capfirst(),
382 iconCls: model.iconCls,
384 handler: function (button, event) {
385 outer.create_instance_window(this.model, undefined, function (win) {
392 add_to_manage_menu: function (model) {
394 this.manage_menu.add({
395 text: model.verbose_name_plural.capfirst(),
396 iconCls: model.iconCls,
398 handler: function (button, event) {
399 var win = outer.create_model_management_window(this.model);
405 create_model_management_window: function (model, config, cls) {
407 var panel = new Gilbert.lib.plugins.models.ui.ModelPanel(model, this);
408 var win = this.application.create_window(Ext.applyIf(config||{},{
410 title: model.verbose_name_plural.capfirst(),
411 iconCls: model.iconCls,
420 create_instance_window: function (model, pk, callback, config, cls) {
421 if (pk != undefined) {
422 var win = this.instance_windows[[model.app_label, model.name, pk]];
423 if (win != undefined){
429 var callback = callback;
430 var application = this.application;
433 var form_callback = function (form) {
435 var win = application.create_window({
438 iconCls: form.iconCls,
439 bodyStyle: 'padding: 5px; background: solid;',
448 text: 'Save and Close',
449 iconCls: 'icon-database-import',
450 handler: function (button) {
451 var loading_mask = new Ext.LoadMask(win.body, {
456 win.items.items[0].getForm().submit({
457 success: function (form, action) {
459 win.fireEvent('saved');
462 failure: function (form, action) {
471 iconCls: 'icon-database-import',
472 handler: function (button) {
473 var loading_mask = new Ext.LoadMask(win.body, {
478 win.items.items[0].getForm().submit({
479 success: function (form, action) {
480 win.fireEvent('saved');
481 var pk = action.result.pk;
482 model.create_edit_form(function (newform) {
486 win.setTitle(newform.title);
487 win.setIconClass(newform.iconCls);
491 failure: function (form, action) {
499 if (pk != undefined) {
500 outer.instance_windows[[model.app_label, model.name, pk]] = win
501 win.on('close', function(){
502 delete outer.instance_windows[[model.app_label, model.name, pk]];
512 model.create_edit_form(form_callback, pk, {
513 bodyStyle: 'padding: 10px;',
516 model.create_new_form(form_callback, {
517 bodyStyle: 'padding: 10px;',
525 Gilbert.on('ready', function (application) {
526 application.register_plugin('models', new Gilbert.lib.plugins.models.Plugin());