commit babc0bda4405839690d73b9bf1353d05f8cb2e12
parent 7dd3ef8f2395097b3659bbe0587eac70b6ff7671
Author: Felicia Hummel <felicia@drachenkatze.org>
Date: Sat, 30 Jun 2018 19:04:22 +0200
Added notification bar above the parts grid if a category description was given. To see this in action, to to https://demo.partkeepr.org and go to the category "Free Space".
Diffstat:
5 files changed, 124 insertions(+), 109 deletions(-)
diff --git a/src/PartKeepr/FrontendBundle/Resources/public/css/PartKeepr.css b/src/PartKeepr/FrontendBundle/Resources/public/css/PartKeepr.css
@@ -223,3 +223,14 @@ margin-left: -75px;
width: 217px;
background-image: url(../images/become_a_patron_button.png);
}
+
+.x-panel-notification {
+ padding: 2px;
+}
+
+.x-panel-body-notification {
+ background-color: #cce5ff;
+ border: 1px solid #b8daff;
+ border-radius: .25rem;
+ padding: .25rem .75rem;
+}+
\ No newline at end of file
diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/CategoryEditor/CategoryEditorForm.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/CategoryEditor/CategoryEditorForm.js
@@ -13,7 +13,7 @@ Ext.define('PartKeepr.CategoryEditorForm', {
enableKeyEvents: true,
fieldLabel: i18n("Name")
}, {
- xtype: 'textarea',
+ xtype: 'htmleditor',
name: 'description',
anchor: '100%',
enableKeyEvents: true,
diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/CategoryEditor/CategoryEditorWindow.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/CategoryEditor/CategoryEditorWindow.js
@@ -1,7 +1,7 @@
Ext.define('PartKeepr.CategoryEditorWindow', {
extend: 'Ext.window.Window',
border: false,
- width: 400,
+ width: 650,
categoryModel: null,
layout: 'fit',
items: [
@@ -9,8 +9,7 @@ Ext.define('PartKeepr.CategoryEditorWindow', {
xtype: "CategoryEditorForm"
}
],
- initComponent: function ()
- {
+ initComponent: function () {
this.buttons = [
{
text: i18n("Save"),
@@ -23,9 +22,11 @@ Ext.define('PartKeepr.CategoryEditorWindow', {
this.callParent();
- if (!this.record.phantom) {
+ if (!this.record.phantom)
+ {
this.setTitle(i18n("Edit Category"));
- } else {
+ } else
+ {
this.record.set("parent", this.parentRecord.getId());
this.setTitle(i18n("Add Category"));
}
@@ -33,33 +34,30 @@ Ext.define('PartKeepr.CategoryEditorWindow', {
this.down("CategoryEditorForm").loadRecord(this.record);
this.down("textfield[name=name]").on("keypress", this.onEnter, this);
- this.down("textfield[name=description]").on("keypress", this.onEnter, this);
+ this.down("htmleditor[name=description]").on("keypress", this.onEnter, this);
this.on("show", Ext.bind(this._onShow, this));
},
- onEnter: function (field, e)
- {
- if (e.getKey() == e.ENTER) {
+ onEnter: function (field, e) {
+ if (e.getKey() == e.ENTER)
+ {
this.onSave();
}
},
_onShow: function () {
this.down("CategoryEditorForm").items.first().focus();
},
- onSave: function ()
- {
+ onSave: function () {
this.down("CategoryEditorForm").updateRecord(this.record);
this.record.save({
- success: Ext.bind(function (response)
- {
+ success: Ext.bind(function (response) {
this.fireEvent("save", response);
this.destroy();
}, this)
});
},
- onCancel: function ()
- {
+ onCancel: function () {
this.destroy();
}
});
diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/Editor/EditorGrid.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/Editor/EditorGrid.js
@@ -105,8 +105,7 @@ Ext.define('PartKeepr.EditorGrid', {
* Fires if a record was selected within the grid.
* @param {Object} Ext.data.Record The selected record
*/
- initComponent: function ()
- {
+ initComponent: function () {
/**
* @event itemDeselect
@@ -137,8 +136,7 @@ Ext.define('PartKeepr.EditorGrid', {
tooltip: this.deleteButtonText,
icon: this.deleteButtonIcon,
iconCls: this.deleteButtonIconCls,
- handler: Ext.bind(function ()
- {
+ handler: Ext.bind(function () {
this.fireEvent("itemDelete");
}, this),
disabled: true
@@ -149,8 +147,7 @@ Ext.define('PartKeepr.EditorGrid', {
tooltip: this.addButtonText,
icon: this.addButtonIcon,
iconCls: this.addButtonIconCls,
- handler: Ext.bind(function ()
- {
+ handler: Ext.bind(function () {
this.fireEvent("itemAdd");
}, this)
});
@@ -168,7 +165,8 @@ Ext.define('PartKeepr.EditorGrid', {
var topToolbarItems = [];
- if (this.enableEditing) {
+ if (this.enableEditing)
+ {
topToolbarItems.push(this.addButton);
topToolbarItems.push(this.deleteButton);
}
@@ -195,37 +193,48 @@ Ext.define('PartKeepr.EditorGrid', {
targetStore: this.store
});
+ this.notificationBar = Ext.create("Ext.panel.Panel", {
+ dock: 'top',
+ hidden: true,
+ ui: 'notification'
+ });
+
this.dockedItems = new Array();
this.dockedItems.push(this.bottomToolbar);
this.dockedItems.push(this.appliedFiltersToolbar);
- if (this.enableTopToolbar) {
+ if (this.enableTopToolbar)
+ {
this.dockedItems.push(this.topToolbar);
}
- if (!Ext.isArray(this.plugins)) {
+ if (!Ext.isArray(this.plugins))
+ {
this.plugins = [];
}
this.callParent();
+ this.addDocked(this.notificationBar);
this.getSelectionModel().on("select", this._onItemSelect, this);
this.getSelectionModel().on("deselect", this._onItemDeselect, this);
this.getView().on("itemkeydown", this._onItemKeyPress, this);
this.getStore().on("filterchange", this._onFilterChange, this);
- if (this.automaticPageSize) {
+ if (this.automaticPageSize)
+ {
this.on("resize", this.reassignPageSize, this);
}
},
- _onFilterChange: function ()
- {
+ _onFilterChange: function () {
var filters = this.getStore().getFilters();
- if (filters.length > 0) {
+ if (filters.length > 0)
+ {
this.bottomToolbar.down("#resetFilter").show();
- } else {
+ } else
+ {
this.bottomToolbar.down("#resetFilter").hide();
}
@@ -233,22 +242,38 @@ Ext.define('PartKeepr.EditorGrid', {
},
/**
+ * Sets a notification which is displayed on the grid's top dock
+ * @param message
+ */
+ setNotification: function (message) {
+ this.notificationBar.setHtml(message);
+ this.notificationBar.show();
+ },
+ /**
+ * Removes a previously set notification
+ */
+ removeNotification: function () {
+ this.notificationBar.hide();
+ },
+ /**
* Re-calculates and re-assigns the page size for the assigned store.
*
* Automatically reloads the store.
*/
- reassignPageSize: function ()
- {
- if (this.store.isLoading()) {
+ reassignPageSize: function () {
+ if (this.store.isLoading())
+ {
return;
}
- if (this.getView().getHeight() === 0) {
+ if (this.getView().getHeight() === 0)
+ {
return;
}
var numRecords = Math.floor(this.getView().getHeight() / this.automaticPageSizeRowHeight);
- if (numRecords < 1) {
+ if (numRecords < 1)
+ {
numRecords = 1;
}
@@ -258,65 +283,64 @@ Ext.define('PartKeepr.EditorGrid', {
var newStartPage = Math.floor(oldStartIndex / numRecords);
- if (newStartPage < 1) {
+ if (newStartPage < 1)
+ {
newStartPage = 1;
}
this.store.loadPage(newStartPage);
},
- onReconfigure: function (me, store)
- {
+ onReconfigure: function (me, store) {
this.searchField.setStore(store);
this.bottomToolbar.setStore(store);
},
- syncChanges: function ()
- {
+ syncChanges: function () {
// Simply reload the store for now
this.store.load();
},
/**
* Called when an item was selected. Enables/disables the delete button.
*/
- _updateDeleteButton: function ()
- {
+ _updateDeleteButton: function () {
/* Right now, we support delete on a single record only */
- if (this.getSelectionModel().getCount() == 1) {
+ if (this.getSelectionModel().getCount() == 1)
+ {
this.deleteButton.enable();
- } else {
+ } else
+ {
this.deleteButton.disable();
}
},
- _onItemKeyPress: function (view, record, item, index, e)
- {
- if (e.getKey() == e.ENTER || e.getKey() == e.TAB) {
+ _onItemKeyPress: function (view, record, item, index, e) {
+ if (e.getKey() == e.ENTER || e.getKey() == e.TAB)
+ {
this._onItemEdit(view, record);
}
},
/**
* Called when an item should be edited
*/
- _onItemEdit: function (view, record)
- {
- if (this.editItemAsObject) {
+ _onItemEdit: function (view, record) {
+ if (this.editItemAsObject)
+ {
this.fireEvent("itemEdit", record);
- } else {
+ } else
+ {
this.fireEvent("itemEdit", record.getId());
}
},
/**
* Called when an item was selected
*/
- _onItemSelect: function (selectionModel, record)
- {
+ _onItemSelect: function (selectionModel, record) {
this._updateDeleteButton(selectionModel, record);
this.fireEvent("itemSelect", record);
},
/**
* Called when an item was deselected
*/
- _onItemDeselect: function (selectionModel, record)
- {
+ _onItemDeselect: function (selectionModel, record) {
this._updateDeleteButton(selectionModel, record);
this.fireEvent("itemDeselect", record);
}
diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/Part/PartsManager.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/Part/PartsManager.js
@@ -25,8 +25,7 @@ Ext.define('PartKeepr.PartManager', {
selectedCategory: null,
- initComponent: function ()
- {
+ initComponent: function () {
/**
* Create the store with the default sorter "name ASC"
@@ -162,8 +161,7 @@ Ext.define('PartKeepr.PartManager', {
}
});
- this.thumbnailView.on("selectionchange", function (selModel, selection)
- {
+ this.thumbnailView.on("selectionchange", function (selModel, selection) {
var parts = [];
for (var i = 0; i < selection.length; i++)
@@ -174,16 +172,14 @@ Ext.define('PartKeepr.PartManager', {
this.grid.getSelectionModel().select(parts);
}, this);
- this.grid.store.on("update", function (store, record)
- {
+ this.grid.store.on("update", function (store, record) {
if (this.detail.record !== null && this.detail.record.getId() == record.getId())
{
this.detail.setValues(record);
}
}, this);
- this.grid.store.on("load", function ()
- {
+ this.grid.store.on("load", function () {
this.thumbnailView.getStore().removeAll();
var data = this.grid.store.getData(),
@@ -238,8 +234,7 @@ Ext.define('PartKeepr.PartManager', {
items: [this.grid, this.thumbnailPanel]
});
- this.thumbnailView.on("render", function ()
- {
+ this.thumbnailView.on("render", function () {
this.loadMask = Ext.create("Ext.LoadMask", {
store: this.grid.store,
target: this.thumbnailPanel
@@ -293,8 +288,7 @@ Ext.define('PartKeepr.PartManager', {
* @param {Ext.tree.View} tree The tree view
* @param {Ext.data.Model} record the selected record
*/
- onCategoryClick: function (tree, record)
- {
+ onCategoryClick: function (tree, record) {
this.selectedCategory = record;
var filter = Ext.create("PartKeepr.util.Filter", {
@@ -304,6 +298,14 @@ Ext.define('PartKeepr.PartManager', {
value: this.getChildrenIds(record)
});
+ if (record.get("description").trim() != "")
+ {
+ this.grid.setNotification(record.get("description"));
+ } else {
+ this.grid.removeNotification();
+ }
+
+
if (record.parentNode.isRoot())
{
// Workaround for big installations: Passing all child categories for the root node
@@ -315,8 +317,7 @@ Ext.define('PartKeepr.PartManager', {
this.store.addFilter(filter);
}
},
- getSelectedCategory: function ()
- {
+ getSelectedCategory: function () {
return this.selectedCategory;
},
/**
@@ -325,8 +326,7 @@ Ext.define('PartKeepr.PartManager', {
* @param {Ext.data.Model} node The node
* @return Array
*/
- getChildrenIds: function (node)
- {
+ getChildrenIds: function (node) {
var childNodes = [node];
if (node.hasChildNodes())
@@ -344,8 +344,7 @@ Ext.define('PartKeepr.PartManager', {
* of the selected part for a short time. We can't select the category
* as this would affect the parts grid.
*/
- onSyncCategory: function ()
- {
+ onSyncCategory: function () {
var r = this.grid.getSelectionModel().getSelection();
if (r.length != 1)
@@ -369,8 +368,7 @@ Ext.define('PartKeepr.PartManager', {
*
* Prompts the user if he really wishes to delete the part. If yes, it calls deletePart.
*/
- onItemDelete: function ()
- {
+ onItemDelete: function () {
var r = this.grid.getSelectionModel().getLastSelected();
Ext.Msg.confirm(i18n("Delete Part"), sprintf(i18n("Do you really wish to delete the part %s?"), r.get("name")),
@@ -380,8 +378,7 @@ Ext.define('PartKeepr.PartManager', {
* Creates a duplicate with the basic data only from the selected item. Loads the selected part and calls
* createPartDuplicate after the part was loaded.
*/
- onDuplicateItemWithBasicData: function ()
- {
+ onDuplicateItemWithBasicData: function () {
var r = this.grid.getSelectionModel().getLastSelected();
this.loadPart(r.getId(), Ext.bind(this.createPartDuplicate, this));
@@ -390,8 +387,7 @@ Ext.define('PartKeepr.PartManager', {
* Creates a full duplicate from the selected item. Loads the selected part and calls createPartDuplicate
* after the part was loaded.
*/
- onDuplicateItemWithAllData: function ()
- {
+ onDuplicateItemWithAllData: function () {
var r = this.grid.getSelectionModel().getLastSelected();
this.loadPart(r.getId(), Ext.bind(this.createFullPartDuplicate, this));
@@ -400,8 +396,7 @@ Ext.define('PartKeepr.PartManager', {
* Creates a part duplicate from the given record and opens the editor window.
* @param rec The record to duplicate
*/
- createPartDuplicate: function (rec)
- {
+ createPartDuplicate: function (rec) {
var data = rec.getData();
var associationData = rec.getAssociationData();
@@ -422,8 +417,7 @@ Ext.define('PartKeepr.PartManager', {
j.editor.editItem(newItem);
j.show();
},
- onAddMetaPart: function ()
- {
+ onAddMetaPart: function () {
var defaults = {};
var j = Ext.create("PartKeepr.Components.Part.Editor.MetaPartEditorWindow", {});
@@ -453,8 +447,7 @@ Ext.define('PartKeepr.PartManager', {
* Creates a part duplicate from the given record and opens the editor window.
* @param rec The record to duplicate
*/
- createFullPartDuplicate: function (rec)
- {
+ createFullPartDuplicate: function (rec) {
var data = rec.getData();
var newItem = Ext.create("PartKeepr.PartBundle.Entity.Part");
@@ -476,8 +469,7 @@ Ext.define('PartKeepr.PartManager', {
* @todo We use the current selection of the grid. If for some reason the selection changes during the user is prompted,
* we delete the wrong part. Fix that to pass the selected item to the onItemDelete then to this function.
*/
- deletePart: function (btn)
- {
+ deletePart: function (btn) {
var r = this.grid.getSelectionModel().getLastSelected();
if (btn == "yes")
@@ -490,8 +482,7 @@ Ext.define('PartKeepr.PartManager', {
/**
* Creates a new, empty part editor window
*/
- onItemAdd: function (defaults)
- {
+ onItemAdd: function (defaults) {
var j = Ext.create("PartKeepr.PartEditorWindow", {
partMode: 'create'
});
@@ -521,8 +512,7 @@ Ext.define('PartKeepr.PartManager', {
/**
* Called when a part was edited. Refreshes the grid.
*/
- onEditPart: function (part)
- {
+ onEditPart: function (part) {
var editorWindow;
if (part.get("metaPart") === true)
@@ -537,19 +527,16 @@ Ext.define('PartKeepr.PartManager', {
editorWindow.editor.editItem(part);
editorWindow.show();
},
- onNewPartSaved: function ()
- {
+ onNewPartSaved: function () {
this.grid.getStore().reload();
},
- onPartSaved: function (record)
- {
+ onPartSaved: function (record) {
this.detail.setValues(record);
},
/**
* Called when a part was selected in the grid. Displays the details for this part.
*/
- onItemSelect: function ()
- {
+ onItemSelect: function () {
if (this.grid.getSelection().length > 1)
{
this.detailPanel.collapse();
@@ -580,8 +567,7 @@ Ext.define('PartKeepr.PartManager', {
* @param {Integer} id The ID of the part to load
* @param {Function} handler The callback to call when the part was loaded
*/
- loadPart: function (id, handler)
- {
+ loadPart: function (id, handler) {
// @todo we have this method duplicated in PartEditor
PartKeepr.PartBundle.Entity.Part.load(id, {
@@ -592,8 +578,7 @@ Ext.define('PartKeepr.PartManager', {
/**
* Creates the store
*/
- createStore: function (config)
- {
+ createStore: function (config) {
Ext.Object.merge(config, {
autoLoad: true,
autoSync: false, // Do not change. If true, new (empty) records would be immediately commited to the database.
@@ -605,13 +590,11 @@ Ext.define('PartKeepr.PartManager', {
this.store = Ext.create('Ext.data.Store', config);
// Workaround for bug http://www.sencha.com/forum/showthread.php?133767-Store.sync()-does-not-update-dirty-flag&p=607093#post607093
- this.store.on('write', function (store, operation)
- {
+ this.store.on('write', function (store, operation) {
var success = operation.wasSuccessful();
if (success)
{
- Ext.each(operation.records, function (record)
- {
+ Ext.each(operation.records, function (record) {
if (record.dirty)
{
record.commit();
@@ -623,13 +606,11 @@ Ext.define('PartKeepr.PartManager', {
/**
* Returns the store
*/
- getStore: function ()
- {
+ getStore: function () {
return this.store;
},
statics: {
- formatParameter: function (partParameter)
- {
+ formatParameter: function (partParameter) {
var minSiPrefix = "", siPrefix = "", maxSiPrefix = "", unit = "", minValue = "", maxValue = "", value = "",
minMaxCombined = "";