partkeepr

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

commit ff744bd302a55e81cc364572169a058a066584c9
parent 5e9f5f378908f1a27534c6dd887a0c8130a8eda3
Author: Felicitus <felicitus@felicitus.org>
Date:   Sat, 12 May 2012 03:16:37 +0200

Merge branch 'master' of github.com:partkeepr/PartKeepr

Diffstat:
Msrc/backend/de/RaumZeitLabor/PartKeepr/Part/Part.php | 41++++++++++++++++++++++++++++++++++++-----
Msrc/backend/de/RaumZeitLabor/PartKeepr/Part/PartManager.php | 6+++++-
Msrc/frontend/js/Components/CategoryEditor/CategoryEditorTree.js | 14++++++++++++--
Msrc/frontend/js/Components/CategoryTree.js | 12+++++++++---
Msrc/frontend/js/Components/Editor/EditorGrid.js | 4++--
Msrc/frontend/js/Components/Part/Editor/PartEditor.js | 107++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/frontend/js/Components/Part/PartDisplay.js | 1+
Msrc/frontend/js/Components/Part/PartsGrid.js | 10+++++++---
Asrc/frontend/js/Components/User/Preferences/CategoryTreePreferences.js | 28++++++++++++++++++++++++++++
Msrc/frontend/js/Components/User/UserPreferences.js | 7++++---
Msrc/frontend/js/Models/Part.js | 1+
Msrc/frontend/js/PartKeepr.js | 19+++++++++++++++----
12 files changed, 215 insertions(+), 35 deletions(-)

diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/Part/Part.php b/src/backend/de/RaumZeitLabor/PartKeepr/Part/Part.php @@ -35,6 +35,13 @@ class Part extends BaseEntity implements Serializable, Deserializable { private $name; /** + * The part's short description + * @Column(type="string",nullable=true) + * @var string + */ + private $description; + + /** * The footprint of this part * @ManyToOne(targetEntity="de\RaumZeitLabor\PartKeepr\Footprint\Footprint") * @var Footprint @@ -206,6 +213,22 @@ class Part extends BaseEntity implements Serializable, Deserializable { } /** + * Sets the description for this part + * @param string $description The part's short description + */ + public function setDescription ($description) { + $this->description = $description; + } + + /** + * Returns the short description of this part + * @return string The part description + */ + public function getDescription () { + return $this->description; + } + + /** * Sets the part unit * * @param PartUnit $partUnit The part unit object to set @@ -452,6 +475,7 @@ class Part extends BaseEntity implements Serializable, Deserializable { return array( "id" => $this->getId(), "name" => $this->getName(), + "description" => $this->getDescription(), "comment" => $this->getComment(), "stockLevel" => $this->getStockLevel(), "footprint" => is_object($this->footprint) ? $this->footprint->getId() : null, @@ -485,6 +509,9 @@ class Part extends BaseEntity implements Serializable, Deserializable { case "name": $this->setName($value); break; + case "description": + $this->setDescription($value); + break; case "comment": $this->setComment($value); break; @@ -492,11 +519,15 @@ class Part extends BaseEntity implements Serializable, Deserializable { $this->setInternalPartNumber($value); break; case "footprint": - try { - $footprint = Footprint::loadById($value); - $this->setFootprint($footprint); - } catch (\Exception $e) { - // No footprint was found. Ignore it. + if ($value === 0) { + $this->setFootprint(null); + } else { + try { + $footprint = Footprint::loadById($value); + $this->setFootprint($footprint); + } catch (\Exception $e) { + // No footprint was found. Ignore it. + } } break; case "minStockLevel": diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/Part/PartManager.php b/src/backend/de/RaumZeitLabor/PartKeepr/Part/PartManager.php @@ -43,7 +43,7 @@ class PartManager extends AbstractManager { * @return array An array of all fields which should be returned */ public function getQueryFields () { - return array("name", "averagePrice", "status", "needsReview", "createDate", "id", "stockLevel", + return array("name", "description", "averagePrice", "status", "needsReview", "createDate", "id", "stockLevel", "minStockLevel", "comment", "st.id AS storageLocation_id", "c.categoryPath AS categoryPath", "st.name as storageLocationName", "f.id AS footprint_id", "f.name AS footprintName", "c.id AS category", "c.name AS categoryName", "pu.id AS partUnit", "pu.name AS partUnitName", @@ -162,6 +162,10 @@ class PartManager extends AbstractManager { $part->setName($aParameters["name"]); } + if (array_key_exists("description", $aParameters)) { + $part->setDescription($aParameters["description"]); + } + if (array_key_exists("minstock", $aParameters)) { $part->setMinStockLevel($aParameters["minstock"]); } diff --git a/src/frontend/js/Components/CategoryEditor/CategoryEditorTree.js b/src/frontend/js/Components/CategoryEditor/CategoryEditorTree.js @@ -175,12 +175,21 @@ Ext.define("PartKeepr.CategoryEditorTree", { onUpdateRecord: function (record) { var currentRecord = this.getStore().getRootNode().findChild("id", record.get("id"), true); + var label; + if (PartKeepr.getApplication().getUserPreference("partkeepr.categorytree.showdescriptions") === true) { + label = record.get("name") + " - " + record.get("description"); + } else { + label = record.get("name"); + } + if (currentRecord === null) { var parentRecord = this.getStore().getRootNode().findChild("id", record.get("parent"), true); var nodeData = { id : record.get("id"), name : record.get("name"), + description : record.get("description"), + text : label, tooltip : record.get("description") }; @@ -189,6 +198,8 @@ Ext.define("PartKeepr.CategoryEditorTree", { } else { currentRecord.set("name", record.get("name")); currentRecord.set("description", record.get("description")); + currentRecord.set("text", label); + currentRecord.set("tooltip", record.get("description")); currentRecord.commit(); } @@ -204,4 +215,4 @@ Ext.define("PartKeepr.CategoryEditorTree", { }); } } -});- \ No newline at end of file +}); diff --git a/src/frontend/js/Components/CategoryTree.js b/src/frontend/js/Components/CategoryTree.js @@ -3,7 +3,6 @@ Ext.define("PartKeepr.CategoryTree", { extend: 'Ext.tree.Panel', categoryService: null, categoryModel: null, - displayField: 'name', sorters: [{ property: 'name', direction: 'ASC' @@ -63,9 +62,17 @@ Ext.define("PartKeepr.CategoryTree", { return ret; }, buildCategoryTree : function(root, data, expandedNodes) { + var label; + if ((data.id > 1) && (PartKeepr.getApplication().getUserPreference("partkeepr.categorytree.showdescriptions") === true)) { + label = data.name + " - " + data.description; + } else { + label = data.name; + } var nodeData = { id : data.id, name : data.name, + description : data.description, + text : label, tooltip : data.description }; @@ -106,4 +113,4 @@ Ext.define("PartKeepr.CategoryTree", { this.buildCategoryTree(node, data.children[i], expandedNodes); } } -});- \ No newline at end of file +}); diff --git a/src/frontend/js/Components/Editor/EditorGrid.js b/src/frontend/js/Components/Editor/EditorGrid.js @@ -103,6 +103,7 @@ Ext.define('PartKeepr.EditorGrid', { }); this.searchField = Ext.create("Ext.ux.form.SearchField",{ + id: 'thesearchfield', store: this.store }); @@ -171,4 +172,4 @@ Ext.define('PartKeepr.EditorGrid', { this._updateDeleteButton(selectionModel, record); this.fireEvent("itemDeselect", record); } -});- \ No newline at end of file +}); diff --git a/src/frontend/js/Components/Part/Editor/PartEditor.js b/src/frontend/js/Components/Part/Editor/PartEditor.js @@ -44,10 +44,60 @@ Ext.define('PartKeepr.PartEditor', { this.getForm().isValid(); }, this); + this.footprintNone = Ext.create("Ext.form.field.Radio", { + boxLabel: i18n("None"), + name: 'footprint_mode', + margin: { + right: 5 + }, + value: "unset", + listeners: { + scope: this, + change: function (field, newValue) { + if (newValue === true) { + this.footprintComboBox.clearValue(); + } + } + } + }); + + this.footprintSet = Ext.create("Ext.form.field.Radio", { + name: 'footprint_mode', + margin: { + right: 5 + }, + value: "set" + }); + + /* + * Creates the footprint combo box. We listen for the "change" event, because we need to set the footprint + * comboboxes to the right state, depending on the selection. Another way would be to patch the combobox + * to support "null" values, however, this is a major change within ExtJS and probably not supported for + * updates of ExtJS. + */ + this.footprintComboBox = Ext.create("PartKeepr.FootprintComboBox", { + name: 'footprint', + flex: 1, + listeners: { + scope: this, + change: function (field, newValue) { + console.log(newValue); + + if (newValue !== 0) { + this.footprintSet.setValue(true); + } + } + } + }); + // Defines the basic editor fields var basicEditorFields = [ this.nameField, { + xtype: 'textfield', + fieldLabel: i18n("Description"), + name: 'description' + },{ layout: 'column', bodyStyle: 'background:#DBDBDB', border: false, @@ -76,23 +126,45 @@ Ext.define('PartKeepr.PartEditor', { }, this.storageLocationComboBox, { - xtype: 'FootprintComboBox', + xtype: 'fieldcontainer', + layout: 'hbox', fieldLabel: i18n("Footprint"), - name: 'footprint' + defaults: { + hideLabel: true + }, + items: [ + this.footprintNone, + this.footprintSet, + this.footprintComboBox + ] },{ xtype: 'textarea', fieldLabel: i18n("Comment"), - name: 'comment' - },{ - xtype: 'textfield', + name: 'comment', + anchor: '100% -200' + }, + { + xtype: 'fieldcontainer', + layout: 'hbox', fieldLabel: i18n("Status"), - name: 'status' - },{ - xtype: 'checkbox', - hideEmptyLabel: false, - fieldLabel: '', - boxLabel: i18n("Needs Review"), - name: 'needsReview' + defaults: { + hideLabel: true + }, + items: [{ + xtype: 'textfield', + fieldLabel: i18n("Status"), + flex: 1, + name: 'status' + },{ + xtype: 'checkbox', + hideEmptyLabel: false, + fieldLabel: '', + margins: { + left: 5 + }, + boxLabel: i18n("Needs Review"), + name: 'needsReview' + }] },{ xtype: 'textfield', fieldLabel: i18n("Internal Part Number"), @@ -286,6 +358,11 @@ Ext.define('PartKeepr.PartEditor', { this.record.set("storageLocation", storageLocationRecord.get("id")); } + // Force footprint to be "null" when the checkbox is checked. + if (this.footprintNone.getValue() === true) { + this.record.set("footprint", 0); + } + }, onEditStart: function () { this.bindChildStores(); @@ -298,6 +375,12 @@ Ext.define('PartKeepr.PartEditor', { // This workaround is done twice; once after the store is loaded and once when we start editing, // because we don't know which event will come first this.getForm().isValid(); + + if (this.record.get("footprint") == 0) { + this.footprintNone.setValue(true); + } else { + this.footprintSet.setValue(true); + } }, _onItemSaved: function () { this.fireEvent("partSaved", this.record); diff --git a/src/frontend/js/Components/Part/PartDisplay.js b/src/frontend/js/Components/Part/PartDisplay.js @@ -15,6 +15,7 @@ Ext.define('PartKeepr.PartDisplay', { */ this.tpl = new Ext.XTemplate( '<h1>{name}</h1>', + '<h2>{description}</h2>', '<table>', '<tr>', '<td class="o">'+i18n("Category")+':</td>', diff --git a/src/frontend/js/Components/Part/PartsGrid.js b/src/frontend/js/Components/Part/PartsGrid.js @@ -147,9 +147,14 @@ Ext.define('PartKeepr.PartsGrid', { header: i18n("Name"), dataIndex: 'name', flex: 1, - minWidth: 200, + minWidth: 150, renderer: Ext.util.Format.htmlEncode },{ + header: i18n("Description"), + dataIndex: 'description', + flex: 2, + minWidth: 150 + },{ header: i18n("Storage Location"), dataIndex: 'storageLocationName' },{ @@ -366,4 +371,4 @@ Ext.define('PartKeepr.PartsGrid', { rec.set("stockLevel", record.get("stockLevel")); } } -});- \ No newline at end of file +}); diff --git a/src/frontend/js/Components/User/Preferences/CategoryTreePreferences.js b/src/frontend/js/Components/User/Preferences/CategoryTreePreferences.js @@ -0,0 +1,28 @@ +Ext.define('PartKeepr.CategoryTreePreferencesPanel', { + extend: 'Ext.form.FormPanel', + title: i18n("Category Tree"), + bodyStyle: 'background:#DBDBDB;padding: 10px;', + initComponent: function () { + this.showDescriptionsCheckbox = Ext.create("Ext.form.field.Checkbox", { + boxLabel: i18n("Show category descriptions"), + handler: Ext.bind(this.showDescriptionsHandler, this) + }); + + if (PartKeepr.getApplication().getUserPreference("partkeepr.categorytree.showdescriptions") === false) { + this.showDescriptionsCheckbox.setValue(false); + } else { + this.showDescriptionsCheckbox.setValue(true); + } + + this.items = [ this.showDescriptionsCheckbox ]; + + this.callParent(); + }, + /** + * Handler when the "show descriptions" checkbox is clicked. + */ + showDescriptionsHandler: function (checkbox, checked) { + PartKeepr.getApplication().setUserPreference("partkeepr.categorytree.showdescriptions", checked); + } +}); + diff --git a/src/frontend/js/Components/User/UserPreferences.js b/src/frontend/js/Components/User/UserPreferences.js @@ -7,8 +7,10 @@ Ext.define('PartKeepr.UserPreferencePanel', { this.passwordChangePanel = Ext.create("PartKeepr.UserPasswordChangePanel"); this.tipsPanel = Ext.create("PartKeepr.TipOfTheDayPreferencesPanel"); + this.categoryTreePanel = Ext.create("PartKeepr.CategoryTreePreferencesPanel"); this.stockPanel = Ext.create("PartKeepr.StockPreferencesPanel"); - this.items = [ this.tipsPanel, this.passwordChangePanel, this.stockPanel ]; + this.items = [ this.tipsPanel, this.categoryTreePanel, this.passwordChangePanel, this.stockPanel ]; this.callParent(); } -});- \ No newline at end of file +}); + diff --git a/src/frontend/js/Models/Part.js b/src/frontend/js/Models/Part.js @@ -8,6 +8,7 @@ Ext.define("PartKeepr.Part", { { name: 'partUnit', type: 'int'}, { name: 'averagePrice', type: 'float'}, { name: 'name', type: 'string'}, + { name: 'description', type: 'string'}, { name: 'comment', type: 'string'}, { name: 'status', type: 'string'}, { name: 'stockLevel', type: 'int'}, diff --git a/src/frontend/js/PartKeepr.js b/src/frontend/js/PartKeepr.js @@ -38,8 +38,20 @@ Ext.application({ } } - - + new Ext.util.KeyMap(Ext.get(document), { + key: 'x', + ctrl: false, + alt: true, + fn: function(e) { + var searchBox = Ext.getCmp('thesearchfield'); + if (Ext.get(document).activeElement != searchBox) { + searchBox.focus('',10); + } + searchBox.setValue(''); + }, + stopEvent: true + }); + Ext.fly(document.body).on('contextmenu', this.onContextMenu, this); }, onContextMenu: function (e, target) { @@ -595,4 +607,4 @@ PartKeepr.serializeRecords = function (records) { } return finalData; -}; - \ No newline at end of file +};