partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

EntityQueryPanel.js (9352B)


      1 Ext.define("PartKeepr.Widgets.EntityQueryPanel", {
      2     extend: "Ext.panel.Panel",
      3     layout: 'border',
      4     items: [
      5         {
      6             title: i18n("Results"),
      7             xtype: 'grid',
      8             region: 'center',
      9             itemId: 'grid',
     10         }, {
     11             title: i18n("Available fields"),
     12             xtype: 'treepanel',
     13             region: 'east',
     14             width: 265,
     15             itemId: 'fieldTree',
     16             plugins: {
     17                 ptype: 'cellediting',
     18                 clicksToEdit: 1,
     19                 pluginId: "cellediting",
     20             },
     21             split: true,
     22             viewConfig: {
     23                 markDirty: false
     24             },
     25             store: {
     26                 folderSort: true,
     27                 sorters: [
     28                     {
     29                         property: 'text',
     30                         direction: 'ASC'
     31                     }
     32                 ]
     33             },
     34             columns: [
     35                 {
     36                     xtype: 'treecolumn', //this is so we know which column will show the tree
     37                     text: i18n("Field"),
     38                     dataIndex: 'text',
     39                     flex: 3,
     40                 }, {
     41                     text: i18n("Index"),
     42                     flex: 1,
     43                     align: 'center',
     44                     dataIndex: 'entityIndex',
     45                     format: '0',
     46                     editor: {
     47                         xtype: 'numberfield',
     48                         minValue: 0,
     49                         maxValue: 99
     50                     },
     51                     renderer: function (val, md, record) {
     52                         if (record.get("data") instanceof Object &&
     53                                 typeof(record.get("data").type) !== "undefined" &&
     54                                 record.get("data").type !== "onetomany") {
     55                             return "";
     56                         } else {
     57                             return record.get("entityIndex");
     58                         }
     59                     }
     60                 }
     61             ],
     62             useArrows: true
     63         }
     64     ],
     65     /**
     66      * @var {Array} Contains the models already in the field tree
     67      */
     68     visitedModels: [],
     69 
     70     /**
     71      * @var {Array} All configured columns
     72      */
     73     columns: [],
     74 
     75     /**
     76      * @var {Ext.data.Store} The store
     77      */
     78     store: null,
     79 
     80     initComponent: function ()
     81     {
     82         this.callParent(arguments);
     83         this.visitedModels = [];
     84 
     85         var rootNode = this.down("#fieldTree").getRootNode();
     86         this.down("#fieldTree").on("itemdblclick", this.onTreeDblClick, this);
     87         rootNode.set("text", this.model.getName());
     88 
     89         var treeMaker = Ext.create("PartKeepr.ModelTreeMaker.ModelTreeMaker");
     90         treeMaker.addIgnoreField("@id");
     91         treeMaker.make(rootNode, this.model, "", Ext.bind(this.appendFieldData, this), ["entityIndex"]);
     92         rootNode.expand();
     93 
     94         rootNode.expand();
     95 
     96         this.store = Ext.create("Ext.data.Store", {
     97             model: this.model.getName(),
     98             autoLoad: true
     99         });
    100 
    101         this.down("#fieldTree").addDocked({
    102             xtype: 'toolbar',
    103             items: [
    104                 {
    105                     xtype: 'button',
    106                     iconCls: 'web-icon add',
    107                     handler: "onAddColumn",
    108                     scope: this
    109                 },
    110                 {
    111                     xtype: 'button',
    112                     iconCls: 'web-icon delete',
    113                     handler: "onRemoveColumn",
    114                     scope: this
    115                 }
    116             ]
    117         });
    118 
    119         this.down("#fieldTree").getPlugin("cellediting").on("beforeedit", this.onBeforeEdit, this);
    120         this.down("#grid").addDocked(this.bottomToolbar);
    121 
    122         this.down("#grid").reconfigure(this.store, this.columns);
    123     },
    124     onBeforeEdit: function (editor, context)
    125     {
    126         if (context.record.get("data") !== null &&
    127             context.record.get("data").type !== "onetomany") {
    128 
    129             return false;
    130         }
    131     },
    132     /**
    133      * @param {Ext.data.field.Field} The model
    134      */
    135     appendFieldData: function (field, node)
    136     {
    137         node.set("entityIndex", 0);
    138     },
    139     /**
    140      * Returns the parameters for the query string.
    141      * @return {Object} An object containing all parameters
    142      */
    143     getParams: function ()
    144     {
    145         var i, originalColumns, columns = [];
    146         originalColumns = this.down('#grid').getColumns();
    147         for (i = 0; i < originalColumns.length; i++) {
    148             columns.push(originalColumns[i].dataIndex);
    149         }
    150 
    151         return {
    152             itemsPerPage: 9999999,
    153             columns: Ext.encode(columns)
    154         };
    155 
    156     },
    157     /**
    158      * Event handler for the add button
    159      */
    160     onAddColumn: function ()
    161     {
    162         var selModel = this.down("#fieldTree").getSelectionModel();
    163         if (!selModel.hasSelection()) {
    164             return;
    165         }
    166 
    167         var record = this.down("#fieldTree").getSelectionModel().getSelection()[0];
    168         this.addColumn(record);
    169     },
    170     /**
    171      * Event handler for the remove button
    172      */
    173     onRemoveColumn: function ()
    174     {
    175         var selModel = this.down("#fieldTree").getSelectionModel();
    176         if (!selModel.hasSelection()) {
    177             return;
    178         }
    179 
    180         var record = this.down("#fieldTree").getSelectionModel().getSelection()[0];
    181         this.removeColumn(record);
    182     },
    183     /**
    184      * Adds a specific column to the grid. Must be a record and has the "data" property defined.
    185      *
    186      * @param {Ext.data.Model} The record to process
    187      */
    188     addColumn: function (record)
    189     {
    190         var columns, fieldPath;
    191 
    192         fieldPath = this.getFieldPath(record).join(".");
    193 
    194         if (this.hasColumn(fieldPath) || record.get("data").name === undefined) {
    195             return;
    196         }
    197 
    198         if (record.get("data").type !== "field") {
    199             return;
    200         }
    201 
    202         columns = this.down('#grid').getColumns();
    203 
    204         this.syncColumns();
    205 
    206         this.columns.push({
    207             dataIndex: fieldPath,
    208             text: fieldPath,
    209             renderer: this.columnRenderer,
    210             scope: this.down('#grid')
    211         });
    212 
    213         this.down("#grid").reconfigure(this.store, this.columns);
    214     },
    215     getFieldPath: function (record)
    216     {
    217         var fieldPath = [];
    218 
    219         if (record.parentNode !== null && !record.parentNode.isRoot()) {
    220             fieldPath = this.getFieldPath(record.parentNode);
    221         }
    222 
    223         if (typeof(record.get("data")) === "object" && record.get("data").type === "onetomany") {
    224             fieldPath.push(record.get("text") + "[" + record.get("entityIndex") + "]");
    225         } else {
    226             fieldPath.push(record.get("text"));
    227         }
    228 
    229         return fieldPath;
    230     },
    231     /**
    232      * Removes a specific column to the grid. Must be a record and has the "data" property defined.
    233      *
    234      * @param {Ext.data.Model} The record to process
    235      */
    236     removeColumn: function (record)
    237     {
    238         var i, fieldPath;
    239 
    240         fieldPath = this.getFieldPath(record).join(".");
    241 
    242         if (!this.hasColumn(fieldPath) || record.get("data").name === undefined) {
    243             return;
    244         }
    245 
    246         this.syncColumns();
    247 
    248         for (i = 0; i < this.columns.length; i++) {
    249             if (this.columns[i].dataIndex === fieldPath) {
    250                 Ext.Array.removeAt(this.columns, i);
    251             }
    252         }
    253         this.down("#grid").reconfigure(this.store, this.columns);
    254 
    255     },
    256     /**
    257      * Syncronizes the internal columns storage with the grid. The reason it is done that way is because we can't
    258      * operate on the return value of getColumns() directly, as these are instanciated objects which get removed
    259      * during a reconfigure operation.
    260      */
    261     syncColumns: function ()
    262     {
    263         var columns, i;
    264         this.columns = [];
    265 
    266         columns = this.down('#grid').getColumns();
    267 
    268         for (i = 0; i < columns.length; i++) {
    269             this.columns.push({
    270                 dataIndex: columns[i].dataIndex,
    271                 text: columns[i].text,
    272                 renderer: this.columnRenderer,
    273                 scope: this.down('#grid')
    274             });
    275         }
    276     },
    277     columnRenderer: function (value, metadata, record, rowIndex, colIndex)
    278     {
    279         var index = this.getColumns()[colIndex].dataIndex;
    280         return record.get(index);
    281     },
    282     /**
    283      * Returns if a specific column exists in the grid.Must be a record and has the "data" property defined.
    284      *
    285      * @param {Ext.data.Model} The record to process
    286      * @return {Boolean} true if the column exist, false otherwise
    287      */
    288     hasColumn: function (name)
    289     {
    290         var i, columns = this.down('#grid').getColumns();
    291 
    292         for (i = 0; i < columns.length; i++) {
    293             if (columns[i].dataIndex === name) {
    294                 return true;
    295             }
    296         }
    297 
    298         return false;
    299     },
    300     /**
    301      * Handles the double click on the tree. Adds the item if it doesn't exist, or remove it otherwise
    302      *
    303      * @param {Ext.tree.Tree} The tree panel
    304      * @param {Ext.data.Model} The double clicked record
    305      */
    306     onTreeDblClick: function (tree, record)
    307     {
    308         var fieldPath = this.getFieldPath(record).join(".");
    309 
    310         if (this.hasColumn(fieldPath)) {
    311             this.removeColumn(record);
    312         } else {
    313             this.addColumn(record);
    314         }
    315     }
    316 })
    317 ;