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:
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
+};