Author SHA1 Message Date
Jason Denney 1075c1a5b3 Merge pull request #98 from spacemunkay/denney-transaction-lower-tabs
Replacing user/customer accordion with tab panel
2013-11-09 08:29:47 -08:00
Jason Denney 65708e743d Replacing user/customer accordion with tab panel 2013-11-09 11:29:08 -05:00
Jason Denney 731d0ed3da Increase width for hour in custom time component 2013-11-09 10:45:25 -05:00
Jason Denney 592049b0e6 Merge pull request #97 from spacemunkay/denney-user-profiles-lower-tabs
Add lower tabs pane instead of splitting
2013-11-09 07:44:46 -08:00
Jason Denney c73d5f955a Add lower tabs pane instead of splitting 2013-11-09 10:44:08 -05:00
Jason Denney 966c36b563 Merge pull request #96 from spacemunkay/denney-move-checks
Move checklist to the left in the tasks view.
2013-11-09 06:48:40 -08:00
Jason Denney 20a350adf2 Move checklist to the left in the tasks view. 2013-11-09 09:48:05 -05:00
Jason Denney bca0903862 Merge pull request #87 from spacemunkay/move-brands-80
Moved brands/models tab to the lower pane of bikes
2013-11-08 21:55:16 -08:00
Jason Denney 5212011256 Merge pull request #95 from spacemunkay/denney-improve-wheel-display
Don't attempt to show a wheel size if it's blank
2013-11-04 06:39:34 -08:00
Jason Denney ea79c167eb Don't attempt to show a wheel size if it's blank 2013-11-04 09:38:53 -05:00
Jason Denney 85129dccaa Merge pull request #94 from spacemunkay/denney-add-faker-data
Denney add faker data
2013-11-03 10:59:08 -08:00
Jason Denney eeefe25227 Make sure grabbing valid ID, better faking 2013-11-03 13:58:26 -05:00
Jason Denney d0b2144b28 Adding better fake seed data 2013-11-03 13:52:43 -05:00
Jason Denney 3ba443397e Merge pull request #93 from spacemunkay/denney-disable-subpanels
Disable sub panels until item clicked
2013-11-03 08:35:32 -08:00
Jason Denney 4a67ebe77e Disable sub panels until item clicked 2013-11-03 11:34:48 -05:00
Jason Denney cda94cf955 Merge pull request #91 from spacemunkay/denney-bike-validation
Don't validate top tube on bike model
2013-11-03 07:11:18 -08:00
Jason Denney 1f9bd4f3a0 Don't validate top tube on bike model 2013-11-03 10:07:53 -05:00
Jason Denney 490c9d84b6 Merge pull request #90 from spacemunkay/denney-custom-time-field
Denney custom time field
2013-11-03 05:49:29 -08:00
Jason Denney 84ed8503d1 Remove console.log 2013-11-03 08:46:30 -05:00
Jason Denney 75f4a7980b Need end date to edit start date, fix type 2013-11-03 08:45:10 -05:00
Jason Denney 16cda6aa86 Remove unused code, add comment 2013-11-03 08:42:30 -05:00
Jason Denney de338276c0 Couldn't edit in columns, assign date correctly 2013-11-03 08:40:37 -05:00
Jason Denney 25808eb27a Boom! Meridian time component 2013-11-03 07:22:57 -05:00
Jason Denney d983647e29 Almost done, need to change minutes to textfield 2013-11-03 07:12:56 -05:00
Jason Denney cb4763c172 So close, just a minor bug left to fix
Can't put a field container within a field container, need to flatten it out.
2013-11-02 19:38:31 -04:00
Jason Denney 3d6f698fb9 Only update shop_id in migration 2013-11-02 15:12:55 -04:00
Jason Denney f7ce96152b Merge pull request #89 from spacemunkay/wheelsize-list
Wheelsize list
2013-10-19 16:34:52 -07:00
Jason Denney 4c8f74acf2 Merge branch 'master' of github.com:spacemunkay/velocipede 2013-10-19 19:26:42 -04:00
Jason Denney c2b8a13db2 Update Gemfile.lock 2013-10-19 19:26:21 -04:00
Jason Denney 77d7fad3ce Merge pull request #88 from spacemunkay/grid-sizing-79
Added forceFit option to all the grids so they resize nicely
2013-10-19 15:30:08 -07:00
Jason Denney 3bea39b53a Merge pull request #75 from spacemunkay/default-dropdown-values-67
Default dropdown values 67
2013-10-19 15:09:51 -07:00
Jason Denney 4eae374aa9 Fix column title while we're at it 2013-10-19 18:08:55 -04:00
Jason Denney dc60630d2d On second thought, don't want to default this one. 2013-10-19 18:08:32 -04:00
root 6e92d343a5 Merge branch 'wheelsize-list' of https://github.com/spacemunkay/velocipede into wheelsize-list 2013-10-19 21:43:17 +00:00
root 2ceb744925 Allow horizontal scrolling for combo list box drop down items 2013-10-19 21:42:29 +00:00
Jason Denney b27d682517 Bug caused by Bike.wheel_size no longer existing 2013-10-19 16:28:09 -04:00
Ron Warholic ba0f84a97c Added forceFit option to all the grids so they resize nicely 2013-10-19 16:19:27 -04:00
Ron Warholic 9300ef83d1 Moved brands/models tab to the lower pane of bikes 2013-10-19 16:13:44 -04:00
Jason Denney 4aed82cf80 Make wheel size an combobox option on bikes 2013-10-19 15:37:01 -04:00
Ron Warholic 83bdaf5973 Removed errant whitespace 2013-10-19 12:53:28 -04:00
Ron Warholic d94d747373 Merge branch 'master' of https://github.com/spacemunkay/velocipede 2013-10-19 12:51:10 -04:00
Ron Warholic da176e00ba Added default values for most add-item forms 2013-10-19 12:50:38 -04:00
Jason Denney f17c168d1d Merge pull request #72 from spacemunkay/sorting-and-shop-id-fix-68-63
Sorting and shop id fix 68 63
2013-10-19 07:12:57 -07:00
Ron Warholic 5e042c2577 Added migration file 2013-10-19 10:03:02 -04:00
Jason Denney bceac0543a Merge pull request #73 from spacemunkay/denney-min-chars
Denney min chars
2013-10-18 21:36:18 -07:00
Jason Denney 3faa19bc0c Adding min chars to forms 2013-10-19 00:32:08 -04:00
Jason Denney bbba67d7d5 remove trailing whitespace 2013-10-19 00:31:36 -04:00
Ron Warholic 6cbe0f8b57 Merge branch 'master' of https://github.com/spacemunkay/velocipede 2013-10-18 23:45:51 -04:00
Ron Warholic 86ada003d6 Fixed default sort and added migration for shop_id => Integer 2013-10-18 23:44:12 -04:00
Jason Denney 9a78478f1a Merge pull request #71 from spacemunkay/sequence-increment-bug-31
Fixed the seeder loading the sql incorrectly; now stubs the index out so...
2013-10-18 19:57:51 -07:00
Jason Denney 8d8058dea0 Comment for bike brands sql insert issue 2013-10-18 22:57:10 -04:00
Ron Warholic 93b8e3b055 Fixed the seeder loading the sql incorrectly; now stubs the index out so it generates the sequence number. 2013-10-18 21:24:44 -04:00
48 changed files with 613 additions and 274 deletions
+1
View File
@@ -33,6 +33,7 @@ group :development, :test do
gem 'rspec-rails', '~> 2.8.1' gem 'rspec-rails', '~> 2.8.1'
gem 'factory_girl_rails', '~> 1.2' gem 'factory_girl_rails', '~> 1.2'
gem 'pry', '~> 0.9.8' gem 'pry', '~> 0.9.8'
gem 'faker'
end end
group :test do group :test do
+6 -3
View File
@@ -1,6 +1,6 @@
GIT GIT
remote: https://github.com/spacemunkay/acts_as_loggable.git remote: https://github.com/spacemunkay/acts_as_loggable.git
revision: 49e264849ed9018445fb999cacfc55e1e28d7faa revision: 8484dc1f7a58699705c5ffb593ebdf700a9f374a
specs: specs:
acts_as_loggable (0.0.7) acts_as_loggable (0.0.7)
activerecord (>= 3.0) activerecord (>= 3.0)
@@ -77,6 +77,8 @@ GEM
factory_girl_rails (1.7.0) factory_girl_rails (1.7.0)
factory_girl (~> 2.6.0) factory_girl (~> 2.6.0)
railties (>= 3.0.0) railties (>= 3.0.0)
faker (1.2.0)
i18n (~> 0.5)
ffi (1.6.0) ffi (1.6.0)
formatador (0.2.4) formatador (0.2.4)
gherkin (2.11.6) gherkin (2.11.6)
@@ -122,7 +124,7 @@ GEM
treetop (~> 1.4.8) treetop (~> 1.4.8)
method_source (0.8.1) method_source (0.8.1)
mime-types (1.22) mime-types (1.22)
multi_json (1.7.9) multi_json (1.8.2)
netzke-basepack (0.8.4) netzke-basepack (0.8.4)
netzke-core (~> 0.8.2) netzke-core (~> 0.8.2)
netzke-cancan (0.8.2) netzke-cancan (0.8.2)
@@ -207,7 +209,7 @@ GEM
less-rails (~> 2.2.2) less-rails (~> 2.2.2)
railties (>= 3.1) railties (>= 3.1)
therubyracer (~> 0.10.1) therubyracer (~> 0.10.1)
tzinfo (0.3.37) tzinfo (0.3.38)
uglifier (2.1.2) uglifier (2.1.2)
execjs (>= 0.3.0) execjs (>= 0.3.0)
multi_json (~> 1.0, >= 1.0.2) multi_json (~> 1.0, >= 1.0.2)
@@ -231,6 +233,7 @@ DEPENDENCIES
decent_exposure (~> 1.0.1) decent_exposure (~> 1.0.1)
devise (~> 2.0.4) devise (~> 2.0.4)
factory_girl_rails (~> 1.2) factory_girl_rails (~> 1.2)
faker
guard-rspec guard-rspec
guard-spork guard-spork
haml-rails (~> 0.3.4) haml-rails (~> 0.3.4)
@@ -3,6 +3,232 @@ Ext.Ajax.on('requestexception', function(conn, response, options) {
if (response.status === 401) { window.location = '/users/sign_in'; } if (response.status === 401) { window.location = '/users/sign_in'; }
}, this); }, this);
//Override default netzke time entry field
Ext.define('Ext.ux.form.field.DateTime', {
extend:'Ext.form.FieldContainer',
mixins:{
field:'Ext.form.field.Field'
},
alias: 'widget.xdatetime',
//configurables
combineErrors: true,
msgTarget: 'under',
layout: 'hbox',
readOnly: false,
dateFormat: 'Y-m-d',
dateSubmitFormat: 'Y-m-d',
timeFormat: 'H:i:s',
timeSubmitFormat: 'H:i:s',
dateConfig:{},
timeConfig:{},
// properties
dateValue: null, // Holds the actual date
dateField: null,
hourField: null,
minuteField: null,
ampmField: null,
initComponent: function(){
var me = this
,i = 0
,key
,tab;
me.items = me.items || [];
me.dateField = Ext.create('Ext.form.field.Date', Ext.apply({
format:me.dateFormat,
flex:1,
isFormField:false, //exclude from field query's
submitValue:false,
submitFormat: me.dateSubmitFormat,
readOnly: me.readOnly
}, me.dateConfig));
me.items.push(me.dateField);
me.hourField = Ext.create('Ext.form.field.Number', {
maxWidth: 25,
allowBlank: false,
allowOnlyWhitespace: false,
blankText: "Hour cannot be blank.",
allowDecimals: false,
maxValue: 12,
minValue: 1,
maxLength: 2,
enforceMaxLength: 2,
hideTrigger: true,
submitValue:false,
flex:1,
fieldStyle: "text-align:right;",
isFormField:false, //exclude from field query's
});
me.items.push(me.hourField);
me.colon = Ext.create('Ext.draw.Text', {
text: ':',
padding: '3 3 0 3'
});
me.items.push(me.colon);
me.minuteField = Ext.create('Ext.form.field.Text', {
maxWidth: 30,
allowBlank: false,
allowOnlyWhitespace: false,
blankText: "Minutes cannot be blank.",
regex: /[012345]\d/,
maxLength: 2,
enforceMaxLength: 2,
submitValue:false,
flex:1,
isFormField:false, //exclude from field query's
});
me.items.push(me.minuteField);
me.ampmField = Ext.create('Ext.form.ComboBox', {
maxWidth: 45,
value: 'PM',
store: ['AM', 'PM'],
forceSelection: true,
flex:1,
editable: false
});
me.items.push(me.ampmField);
for (; i < me.items.length; i++) {
me.items[i].on('focus', Ext.bind(me.onItemFocus, me));
me.items[i].on('blur', Ext.bind(me.onItemBlur, me));
me.items[i].on('specialkey', function(field, event){
key = event.getKey();
tab = key == event.TAB;
if (tab && me.focussedItem == me.dateField) {
event.stopEvent();
me.timeField.focus();
return;
}
me.fireEvent('specialkey', field, event);
});
}
me.callParent();
// this dummy is necessary because Ext.Editor will not check whether an inputEl is present or not
this.inputEl = {
dom: document.createElement('div'),
swallowEvent:function(){}
};
me.initField();
},
focus:function(){
this.callParent(arguments);
this.dateField.focus();
},
onItemFocus:function(item){
if (this.blurTask){
this.blurTask.cancel();
}
this.focussedItem = item;
},
onItemBlur:function(item, e){
var me = this;
if (item != me.focussedItem){ return; }
// 100ms to focus a new item that belongs to us, otherwise we will assume the user left the field
me.blurTask = new Ext.util.DelayedTask(function(){
me.fireEvent('blur', me, e);
});
me.blurTask.delay(100);
},
getValue: function(){
var value = null
,date = this.dateField.getSubmitValue()
,time = null
,format;
hour = this.hourField.getValue();
minute = this.minuteField.getValue();
ampm = this.ampmField.getValue();
time = Ext.Date.parse(hour + " " + minute + " " + ampm, 'g i A');
time = Ext.Date.format(time, this.timeSubmitFormat);
if (date){
if (time){
format = this.getFormat();
value = Ext.Date.parse(date + ' ' + time, format);
} else {
value = this.dateField.getValue();
}
}
return value;
},
getSubmitValue: function(){
// var value = this.getValue();
// return value ? Ext.Date.format(value, this.dateTimeFormat) : null;
var me = this
,format = me.getFormat()
,value = me.getValue();
return value ? Ext.Date.format(value, format) : null;
},
setValue: function(value){
if (Ext.isString(value) || Ext.isDate(value)){
if( Ext.isDate(value)){
dt = value;
}else{
dt = new Date(value);
value = Ext.Date.parse(value, this.getFormat()); //this.dateTimeFormat
}
this.dateField.setValue(value);
hour = Ext.Date.format(dt, 'g');
minute = Ext.Date.format(dt, 'i');
ampm = Ext.Date.format(dt, 'A');
this.hourField.setValue(hour);
this.minuteField.setRawValue(minute);
this.ampmField.setValue(ampm);
}
},
getFormat: function(){
value = (this.dateField.submitFormat || this.dateField.format) + " " + (this.timeSubmitFormat || this.timeFormat);
return value;
},
// Bug? A field-mixin submits the data from getValue, not getSubmitValue
getSubmitData: function(){
var me = this
,data = null;
if (!me.disabled && me.submitValue && !me.isFileUpload()) {
data = {};
data[me.getName()] = '' + me.getSubmitValue();
}
return data;
}
});
Ext.define('Ext.ux.form.field.ColorCombo', { Ext.define('Ext.ux.form.field.ColorCombo', {
extend:'Ext.form.FieldContainer', extend:'Ext.form.FieldContainer',
mixins:{ mixins:{
+1 -5
View File
@@ -19,11 +19,7 @@ class AppTabPanel < Netzke::Basepack::TabPanel
#all users #all users
# (had to use hash for borders to get the title to display properly) # (had to use hash for borders to get the title to display properly)
@@app_tab_panel_items = [ :bikes_border, @@app_tab_panel_items = [ :bikes_border ]
{ layout: :fit,
wrappedComponent: :brands_and_models_border,
title: "Brands/Models"}
]
#for users only #for users only
if not controller.current_user.role?(:admin) if not controller.current_user.role?(:admin)
+1
View File
@@ -3,6 +3,7 @@ class BikeBrands < Netzke::Basepack::Grid
super super
c.model = "BikeBrand" c.model = "BikeBrand"
c.title = "Brands" c.title = "Brands"
c.force_fit = true
c.prohibit_update = true if cannot? :update, BikeBrand c.prohibit_update = true if cannot? :update, BikeBrand
c.prohibit_create = true if cannot? :create, BikeBrand c.prohibit_create = true if cannot? :create, BikeBrand
+4 -3
View File
@@ -6,6 +6,7 @@ class BikeLogs < Netzke::Basepack::Grid
c.model = "ActsAsLoggable::Log" c.model = "ActsAsLoggable::Log"
c.title = "Bike History" c.title = "Bike History"
c.force_fit = true
c.data_store = {auto_load: false} c.data_store = {auto_load: false}
c.scope = lambda { |rel| rel.where(:loggable_type => 'Bike',:loggable_id => session[:selected_bike_id]);} c.scope = lambda { |rel| rel.where(:loggable_type => 'Bike',:loggable_id => session[:selected_bike_id]);}
c.strong_default_attrs = { c.strong_default_attrs = {
@@ -18,9 +19,9 @@ class BikeLogs < Netzke::Basepack::Grid
c.columns = [ c.columns = [
{ :name => :start_date, :format => "g:ia - D, M j - Y", :width => 165, :default_value => Time.now.to_formatted_s(:db) }, { :name => :start_date, :format => "g:ia - D, M j - Y", :width => 165, :default_value => Time.now.to_formatted_s(:db) },
{ :name => :end_date, :hidden => true, :default_value => Time.now.to_formatted_s(:db) }, { :name => :end_date, :format => "g:ia - D, M j - Y", :width => 165, :default_value => Time.now.to_formatted_s(:db) },
:description, :description,
{ :name => :bike_action__action, :text => 'Action'}, { :name => :bike_action__action, :text => 'Action', :default_value => ::ActsAsLoggable::BikeAction.first.id},
{ :name => :logged_by, :getter => lambda{ |rec| { :name => :logged_by, :getter => lambda{ |rec|
user = User.find_by_id(rec.logger_id) user = User.find_by_id(rec.logger_id)
user.nil? ? "" : "#{user.first_name} #{user.last_name}" user.nil? ? "" : "#{user.first_name} #{user.last_name}"
@@ -47,7 +48,7 @@ class BikeLogs < Netzke::Basepack::Grid
{ :name => :start_date}, { :name => :start_date},
{ :name => :description}, { :name => :description},
#had to hack acts_as_loggable/log.rb to get this to work #had to hack acts_as_loggable/log.rb to get this to work
{ :name => :bike_action__action, :field_label => 'Action'} { :name => :bike_action__action, :field_label => 'Action', :min_chars => 1 }
] ]
end end
@@ -1,10 +0,0 @@
class BikeLogsAndTasksAccordian < Netzke::Basepack::Accordion
component :bike_logs
component :tasks
def configure(c)
c.prevent_header = true
c.items = [ :bike_logs, :tasks ]
super
end
end
+12
View File
@@ -0,0 +1,12 @@
class BikeLowerTabs < Netzke::Basepack::TabPanel
component :bike_logs
component :tasks
component :brands_and_models_border
def configure(c)
c.prevent_header = true
c.items = [ :bike_logs, :tasks,
{netzke_component: :brands_and_models_border, title: "Brands and Models"} ]
super
end
end
+1
View File
@@ -4,6 +4,7 @@ class BikeModels < Netzke::Basepack::Grid
c.model = "BikeModel" c.model = "BikeModel"
c.title = "Models" c.title = "Models"
c.force_fit = true
c.data_store = {auto_load: false} c.data_store = {auto_load: false}
c.scope = lambda { |rel| rel.where(:bike_brand_id => session[:selected_bike_brand_id]);} c.scope = lambda { |rel| rel.where(:bike_brand_id => session[:selected_bike_brand_id]);}
c.strong_default_attrs = { c.strong_default_attrs = {
+17 -11
View File
@@ -2,11 +2,12 @@ class Bikes < Netzke::Basepack::Grid
def configure(c) def configure(c)
super super
c.model = "Bike" c.model = "Bike"
c.force_fit = true
# columns with :id set, have :min_chars set in init_component # columns with :id set, have :min_chars set in init_component
# See: http://stackoverflow.com/questions/17738962/netzke-grid-filtering # See: http://stackoverflow.com/questions/17738962/netzke-grid-filtering
c.columns = [ c.columns = [
{ :name => :shop_id, :text => 'Shop ID'}, { :name => :shop_id, :text => 'Shop ID', :default_value => Bike.last.id.to_i + 1},
:serial_number, :serial_number,
{ :id => :bike_brand__brand, :name => :bike_brand__brand, :text => 'Brand'}, { :id => :bike_brand__brand, :name => :bike_brand__brand, :text => 'Brand'},
{ :name => :model, :text => 'Model', { :name => :model, :text => 'Model',
@@ -19,20 +20,25 @@ class Bikes < Netzke::Basepack::Grid
} }
}, },
#needs to have type :action or else won't work in grid, because... netzke #needs to have type :action or else won't work in grid, because... netzke
{ :name => "color", :text => "Frame Color", :type => :action, :editor => { :xtype => "xcolorcombo"}, :renderer => :color_block}, { :name => "color", :text => "Frame Color", :type => :action, :editor => { :xtype => "xcolorcombo"}, :renderer => :color_block,
{ :id => :bike_style__style, :name => :bike_style__style, :text => 'Style' }, :default_value => '000000'},
{ :id => :bike_style__style, :name => :bike_style__style, :text => 'Style', :default_value => BikeStyle.first.id},
{ :name => :seat_tube_height, :text => 'Seat Tube (in)'}, { :name => :seat_tube_height, :text => 'Seat Tube (in)'},
{ :name => :top_tube_length, :text => 'Top Tube (in)'}, { :name => :top_tube_length, :text => 'Top Tube (in)'},
{ :name => :wheel_size, :text => 'Wheel Size (in)'}, { :name => :bike_wheel_size__display_string, :text => 'Wheel Size'},
:value, :value,
{ :id => :bike_condition__condition, :name => :bike_condition__condition, :text => 'Condition'}, { :id => :bike_condition__condition, :name => :bike_condition__condition, :text => 'Condition', :default_value => BikeCondition.first.id},
{ :id => :bike_purpose__purpose, :name => :bike_purpose__purpose, :text => 'Purpose'}, { :id => :bike_purpose__purpose, :name => :bike_purpose__purpose, :text => 'Purpose', :default_value => BikePurpose.first.id},
{ :name => :owner, :getter => lambda { |rec| { :name => :owner, :getter => lambda { |rec|
user = rec.owner user = rec.owner
user.nil? ? "" : "#{user.first_name} #{user.last_name}" user.nil? ? "" : "#{user.first_name} #{user.last_name}"
} }
} }
] ]
# Default the sorting to ASC on shop_id
c.data_store.sorters = [{ property: 'shop_id', direction: 'ASC' }]
@bike = Bike.all @bike = Bike.all
c.prohibit_update = true if cannot? :update, @bike c.prohibit_update = true if cannot? :update, @bike
c.prohibit_create = true if cannot? :create, @bike c.prohibit_create = true if cannot? :create, @bike
@@ -41,18 +47,18 @@ class Bikes < Netzke::Basepack::Grid
def default_fields_for_forms def default_fields_for_forms
# :field_label MUST be defined in order for search to work # :field_label MUST be defined in order for search to work
[ [
{ :name => :bike_brand__brand, :field_label => 'Brand' }, { :name => :bike_brand__brand, :field_label => 'Brand', :min_chars => 1 },
{ :name => :model, :field_label => 'Model'}, { :name => :model, :field_label => 'Model'},
{ :name => :shop_id, :field_label => 'Shop ID'}, { :name => :shop_id, :field_label => 'Shop ID'},
{ :name => :serial_number, :field_label => 'Serial Number'}, { :name => :serial_number, :field_label => 'Serial Number'},
{ :name => "color", :xtype => "xcolorcombo"}, { :name => "color", :xtype => "xcolorcombo"},
{ :name => :bike_style__style, :field_label => 'Style' }, { :name => :bike_style__style, :field_label => 'Style', :min_chars => 1},
{ :name => :seat_tube_height, :field_label => 'Seat Tube (in)'}, { :name => :seat_tube_height, :field_label => 'Seat Tube (in)'},
{ :name => :top_tube_length, :field_label => 'Top Tube (in)'}, { :name => :top_tube_length, :field_label => 'Top Tube (in)'},
{ :name => :wheel_size, :field_label => 'Wheel Size (in)'}, { :name => :bike_wheel_size__display_string, :field_label => 'Wheel Size'},
{ :name => :value, :field_label => 'Value'}, { :name => :value, :field_label => 'Value'},
{ :name => :bike_condition__condition, :field_label => 'Condition'}, { :name => :bike_condition__condition, :field_label => 'Condition', :min_chars => 1},
{ :name => :bike_purpose__purpose, :field_label => 'Purpose'} { :name => :bike_purpose__purpose, :field_label => 'Purpose', :min_chars => 1}
] ]
end end
#override with nil to remove actions #override with nil to remove actions
@@ -3,7 +3,6 @@
// calling superclass's initComponent // calling superclass's initComponent
this.callParent(); this.callParent();
// something...
//due to Netzke bug, :min_chars attribute doesn't work //due to Netzke bug, :min_chars attribute doesn't work
var min_char_columns = [ var min_char_columns = [
"bike_brand__brand", "bike_brand__brand",
+2 -2
View File
@@ -2,7 +2,7 @@ class BikesBorder < Netzke::Base
# Remember regions collapse state and size # Remember regions collapse state and size
include Netzke::Basepack::ItemPersistence include Netzke::Basepack::ItemPersistence
component :bikes component :bikes
component :bike_logs_and_tasks_accordian component :bike_lower_tabs
def configure(c) def configure(c)
super super
@@ -10,7 +10,7 @@ class BikesBorder < Netzke::Base
c.title = "Bikes" c.title = "Bikes"
c.items = [ c.items = [
{ netzke_component: :bikes, region: :center, split: true }, { netzke_component: :bikes, region: :center, split: true },
{ netzke_component: :bike_logs_and_tasks_accordian, region: :south, height: 300, split: true} { netzke_component: :bike_lower_tabs, region: :south, height: 300, split: true}
] ]
end end
@@ -5,14 +5,30 @@
// setting the 'rowclick' event // setting the 'rowclick' event
var view = this.getComponent('bikes').getView(); var view = this.getComponent('bikes').getView();
//disable until a bike is clicked
var bike_logs_comp = this.queryById('bike_logs');
if( bike_logs_comp){
bike_logs_comp.disable();
}
var bike_tasks_comp = this.queryById('tasks');
if( bike_tasks_comp ){
bike_tasks_comp.disable();
}
view.on('itemclick', function(view, record){ view.on('itemclick', function(view, record){
// The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server! // The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server!
this.selectBike({bike_id: record.get('id')}); this.selectBike({bike_id: record.get('id')});
if( this.queryById('bike_logs') ){ // query for these components again, can change if not visible because of accordian
this.queryById('bike_logs').getStore().load(); var bike_logs_comp = this.queryById('bike_logs');
var bike_tasks_comp = this.queryById('tasks');
if( bike_logs_comp ){
bike_logs_comp.getStore().load();
bike_logs_comp.enable();
} }
if( this.queryById('tasks') ){ if( bike_tasks_comp ){
this.queryById('tasks').getStore().load(); bike_tasks_comp.getStore().load();
bike_tasks_comp.enable();
} }
}, this); }, this);
} }
+1
View File
@@ -4,6 +4,7 @@ class CheckIns < Netzke::Basepack::Grid
super super
c.header = false c.header = false
c.model = "ActsAsLoggable::Log" c.model = "ActsAsLoggable::Log"
c.force_fit = true
c.scope = lambda { |rel| rel.where(:log_action_type => ::ActsAsLoggable::UserAction). c.scope = lambda { |rel| rel.where(:log_action_type => ::ActsAsLoggable::UserAction).
where(:loggable_type => "User"). where(:loggable_type => "User").
where(:log_action_id => ::ActsAsLoggable::UserAction.find_by_action("CHECKIN")). where(:log_action_id => ::ActsAsLoggable::UserAction.find_by_action("CHECKIN")).
+1
View File
@@ -1,6 +1,7 @@
class Customers < Netzke::Basepack::Grid class Customers < Netzke::Basepack::Grid
def configure(c) def configure(c)
c.model = "Customer" c.model = "Customer"
c.force_fit = true
end end
#override with nil to remove actions #override with nil to remove actions
@@ -4,7 +4,6 @@
this.callParent(); this.callParent();
this.getView().on('itemclick', function(view, record){ this.getView().on('itemclick', function(view, record){
// The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server! // The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server!
console.log("user: " + record.get('id') );
this.selectCustomer({customer_id: record.get('id'), customer_type: 'Customer'}); this.selectCustomer({customer_id: record.get('id'), customer_type: 'Customer'});
}, this); }, this);
} }
+1
View File
@@ -4,6 +4,7 @@ class Logs < Netzke::Basepack::Grid
super super
c.header = false c.header = false
c.model = "ActsAsLoggable::Log" c.model = "ActsAsLoggable::Log"
c.force_fit = true
c.columns = [ c.columns = [
:loggable_id, :loggable_id,
:loggable_type, :loggable_type,
+7 -4
View File
@@ -2,6 +2,8 @@ class Tasks < Netzke::Basepack::Grid
def configure(c) def configure(c)
super super
#disable by default, will be enabled once bike is clicked
c.disabled = true
task_list_id = nil task_list_id = nil
if session[:selected_bike_id] if session[:selected_bike_id]
task_list_id = Bike.find_by_id(session[:selected_bike_id]).task_list.id task_list_id = Bike.find_by_id(session[:selected_bike_id]).task_list.id
@@ -9,6 +11,7 @@ class Tasks < Netzke::Basepack::Grid
c.header = false c.header = false
c.model = "Task" c.model = "Task"
c.force_fit = true
c.scope = lambda{ |rel| c.scope = lambda{ |rel|
if session[:selected_bike_id] if session[:selected_bike_id]
rel.where(:task_list_id => Bike.find_by_id(session[:selected_bike_id]).task_list.id) rel.where(:task_list_id => Bike.find_by_id(session[:selected_bike_id]).task_list.id)
@@ -21,9 +24,9 @@ class Tasks < Netzke::Basepack::Grid
:task_list_id => task_list_id :task_list_id => task_list_id
} }
c.columns = [ c.columns = [
:done,
:task, :task,
:notes, :notes
:done
] ]
end end
@@ -31,9 +34,9 @@ class Tasks < Netzke::Basepack::Grid
fields = [] fields = []
fields << { :no_binding => true, :xtype => 'displayfield', :fieldLabel => "No Bike Selected", :value => "Select a Bike First!"} fields << { :no_binding => true, :xtype => 'displayfield', :fieldLabel => "No Bike Selected", :value => "Select a Bike First!"}
fields.concat( [ fields.concat( [
:done,
:task, :task,
:notes, :notes
:done
]) ])
end end
+3 -2
View File
@@ -5,6 +5,7 @@ class TransactionLogs < Netzke::Basepack::Grid
c.model = "ActsAsLoggable::Log" c.model = "ActsAsLoggable::Log"
c.title = "Transaction Payments" c.title = "Transaction Payments"
c.force_fit = true
c.data_store = {auto_load: false} c.data_store = {auto_load: false}
c.scope = lambda { |rel| rel.where(:loggable_type => 'Transaction',:loggable_id => session[:selected_transaction_id]);} c.scope = lambda { |rel| rel.where(:loggable_type => 'Transaction',:loggable_id => session[:selected_transaction_id]);}
c.strong_default_attrs = { c.strong_default_attrs = {
@@ -20,7 +21,7 @@ class TransactionLogs < Netzke::Basepack::Grid
c.columns = [ c.columns = [
{ :name => :start_date, :format => "g:ia - D, M j - Y", :width => 165, :default_value => Time.now.to_formatted_s(:db), :text => 'Date' }, { :name => :start_date, :format => "g:ia - D, M j - Y", :width => 165, :default_value => Time.now.to_formatted_s(:db), :text => 'Date' },
{ :name => :description, :text => "Amount"} , { :name => :description, :text => "Amount"} ,
{ :name => :transaction_action__action, :text => 'Method'}, { :name => :transaction_action__action, :text => 'Method', :default_value => ::ActsAsLoggable::TransactionAction.first.id},
{ :name => :logged_by, :getter => lambda{ |rec| { :name => :logged_by, :getter => lambda{ |rec|
user = User.find_by_id(rec.logger_id) user = User.find_by_id(rec.logger_id)
user.nil? ? "" : "#{user.first_name} #{user.last_name}" user.nil? ? "" : "#{user.first_name} #{user.last_name}"
@@ -49,7 +50,7 @@ class TransactionLogs < Netzke::Basepack::Grid
{ :no_binding => true, :xtype => 'displayfield', :fieldLabel => "Payment for:", :value => "#{item.to_s}"}, { :no_binding => true, :xtype => 'displayfield', :fieldLabel => "Payment for:", :value => "#{item.to_s}"},
{ :name => :description, :xtype => 'numberfield', :field_label => 'Amount'}, { :name => :description, :xtype => 'numberfield', :field_label => 'Amount'},
#had to hack acts_as_loggable/log.rb to get this to work #had to hack acts_as_loggable/log.rb to get this to work
{ :name => :transaction_action__action, :field_label => 'Payment Method'} { :name => :transaction_action__action, :field_label => 'Payment Method', :min_chars => 1}
] ]
end end
+1
View File
@@ -2,6 +2,7 @@ class Transactions < Netzke::Basepack::Grid
def configure(c) def configure(c)
super super
c.model = "Transaction" c.model = "Transaction"
c.force_fit = true
c.strong_default_attrs = { c.strong_default_attrs = {
:vendor_id => controller.current_user.id, :vendor_id => controller.current_user.id,
:customer_id => session[:selected_customer_id], :customer_id => session[:selected_customer_id],
+2 -2
View File
@@ -4,7 +4,7 @@ class TransactionsBorder < Netzke::Base
component :transactions component :transactions
component :transaction_logs component :transaction_logs
#users and customers components are required for the transactions form #users and customers components are required for the transactions form
component :users_and_customers_accordian component :users_and_customers_lower_tabs
def configure(c) def configure(c)
super super
@@ -13,7 +13,7 @@ class TransactionsBorder < Netzke::Base
c.items = [ c.items = [
{ netzke_component: :transactions, region: :center, height: 300, split: true }, { netzke_component: :transactions, region: :center, height: 300, split: true },
{ netzke_component: :transaction_logs, region: :east, width: 300, split: true }, { netzke_component: :transaction_logs, region: :east, width: 300, split: true },
{ netzke_component: :users_and_customers_accordian, region: :south, height: 300, split: true } { netzke_component: :users_and_customers_lower_tabs, region: :south, height: 300, split: true }
] ]
end end
@@ -5,10 +5,19 @@
// setting the 'rowclick' event // setting the 'rowclick' event
var view = this.getComponent('transactions').getView(); var view = this.getComponent('transactions').getView();
if( this.queryById('transaction_logs')){
this.queryById('transaction_logs').disable();
}
view.on('itemclick', function(view, record){ view.on('itemclick', function(view, record){
// The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server! // The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server!
this.selectTransaction({transaction_id: record.get('id')}); this.selectTransaction({transaction_id: record.get('id')});
this.getComponent('transaction_logs').getStore().load(); this.getComponent('transaction_logs').getStore().load();
if( this.queryById('transaction_logs')){
this.queryById('transaction_logs').enable();
}
}, this); }, this);
} }
} }
@@ -0,0 +1,13 @@
class UserAndProfilesLowerTabs < Netzke::Basepack::TabPanel
component :user_profiles
component :user_logs
component :user_stats
def configure(c)
c.prevent_header = true
c.items = [ :user_logs,
{ netzke_component: :user_profiles, title: "User Profiles" },
{ netzke_component: :user_stats, title: "User Stats" }]
super
end
end
+19 -8
View File
@@ -1,4 +1,5 @@
class UserLogs < Netzke::Basepack::Grid class UserLogs < Netzke::Basepack::Grid
def configure(c) def configure(c)
super super
@@ -33,6 +34,7 @@ class UserLogs < Netzke::Basepack::Grid
c.model = "ActsAsLoggable::Log" c.model = "ActsAsLoggable::Log"
c.title = "User Timesheet" c.title = "User Timesheet"
c.force_fit = true
c.data_store = user_log_data_store c.data_store = user_log_data_store
c.scope = user_log_scope c.scope = user_log_scope
c.strong_default_attrs = user_log_strong_default_attrs c.strong_default_attrs = user_log_strong_default_attrs
@@ -51,10 +53,23 @@ class UserLogs < Netzke::Basepack::Grid
] ]
end end
# Overriding the defautl add in form def default_fields_for_forms
def preconfigure_record_window(c) #figure out a better way to do this
super bike_store = Bike.all.map { |b| [b.id, b.shop_id] }
c.form_config.klass = UserLogsAddItem current_user ||= User.find_by_id(session[:selected_user_id]) || controller.current_user
bike_id = current_user.bike.nil? ? nil : current_user.bike.id
[
{ :no_binding => true, :xtype => 'displayfield', :fieldLabel => "Log for:", :value => "#{current_user.to_s}"},
{ :name => :start_date},
{ :name => :end_date},
{ :name => :description},
#had to hack acts_as_loggable/log.rb to get this to work
{ :name => :user_action__action, :field_label => 'Action', :min_chars => 1},
{ :name => :for_bike, :checkboxName => :copy_log, :inputValue => true, :title => "Copy description to a Bike's History?", :xtype => 'fieldset', :checkboxToggle => true, :collapsed => true, :items => [
{:xtype => 'combo', :no_binding => true, :name => :copy_id, :title => 'Bike', :fieldLabel => 'Bike', :store => bike_store, :value => bike_id}
]
}
]
end end
#override with nil to remove actions #override with nil to remove actions
@@ -62,8 +77,4 @@ class UserLogs < Netzke::Basepack::Grid
[ :apply, :add_in_form, :search ] [ :apply, :add_in_form, :search ]
end end
js_configure do |c|
c.mixin :init_component
end
end end
@@ -2,48 +2,12 @@
initComponent: function(){ initComponent: function(){
// calling superclass's initComponent // calling superclass's initComponent
this.callParent(); this.callParent();
// TESTTING
//due to Netzke bug, :min_chars attribute doesn't work //due to Netzke bug, :min_chars attribute doesn't work
var min_char_columns = [ var min_char_columns = [
"user_action__purpose" "user_action__purpose"]
]; Ext.each(min_char_columns, function(column, index) {
Ext.ComponentManager.get(column).editor.minChars = 1;
// Ext.each(min_char_columns, function(column, index) { });
// Ext.ComponentManager.get(column).editor.minChars = 1;
// });
var view = this.getView();
view.on('itemclick', function(view, record){
console.log('clicking ');
// The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server!
// console.log('Old record', record);
}, this);
view.on('itemupdate', function(record, index, node){
console.log('Updating item');
// if('end_date' in record.data.modified){
// console.log('start', record.data.start_date);
// console.log('end', record.data.end_date);
// }else if('start_date' in record.data.modified){
// }
}, this);
// var hoursInput = Ext.getCmp('user_logs_add_form_hours-inputEl');
// console.log(hoursInput);
// hoursInput.on('change', function(field, newValue, oldValue){
// console.log('Hours changing...', newValue);
// });
},
addNewItem: function(e){
e.fireEvent('click', {});
console.log(e);
console.log('Adding new item');
} }
} }
-31
View File
@@ -1,31 +0,0 @@
# The User Log Add Item Form
class UserLogsAddItem < Netzke::Basepack::Form
def configure(c)
super
c.model = 'ActsAsLoggable::Log'
#figure out a better way to do this
bike_store = Bike.all.map { |b| [b.id, b.shop_id] }
current_user ||= User.find_by_id(session[:selected_user_id]) || controller.current_user
bike_id = current_user.bike.nil? ? nil : current_user.bike.id
c.items = [
{ :no_binding => true, :xtype => 'displayfield', :fieldLabel => "Log for:", :value => "#{current_user.to_s}"},
{ :id => :user_logs_add_form_start, :name => :start_date},
{ :id => :user_logs_add_form_time, :no_binding => true, :name => :time, :xtype => 'field', :fieldLabel => "Time:", :value => 0 },
{ :id => :user_logs_add_form_units, :xtype => 'combo', :no_binding => true, :name => :units, :fieldLabel => 'Units', :store => ['Mins', 'Hrs'], :value => 'Mins' },
{ :id => :user_logs_add_form_end, :name => :end_date, :hidden => true },
{ :name => :description},
#had to hack acts_as_loggable/log.rb to get this to work
{ :name => :user_action__action, :field_label => 'Action'},
{ :name => :for_bike, :checkboxName => :copy_log, :inputValue => true,
:title => "Copy description to a Bike's History?", :xtype => 'fieldset', :checkboxToggle => true, :collapsed => true, :items => [
{:xtype => 'combo', :no_binding => true, :name => :copy_id, :title => 'Bike', :fieldLabel => 'Bike', :store => bike_store, :value => bike_id}
]
}
]
end
js_configure do |c|
c.mixin :init_component
end
end
@@ -1,76 +0,0 @@
{
initComponent: function(){
// calling superclass's initComponent
this.callParent();
var panel = this;
var theForm = this.getForm();
var startInput = Ext.getCmp('user_logs_add_form_start');
var timeInput = Ext.getCmp('user_logs_add_form_time');
var unitsInput = Ext.getCmp('user_logs_add_form_units');
var endInput = Ext.getCmp('user_logs_add_form_end');
var startdate = startInput.items.items[0];
var starttime = startInput.items.items[1];
var enddate = endInput.items.items[0];
var endtime = endInput.items.items[1];
startdate.on('change', function(e){
var hours = timeInput.getValue();
var startTime = starttime.getValue();
if('Mins' === unitsInput.getValue()){
var calculatedEndTime = Ext.Date.add(new Date(startTime), Ext.Date.MINUTE, parseInt(hours));
}else{
var calculatedEndTime = Ext.Date.add(new Date(startTime), Ext.Date.HOUR, parseInt(hours));
}
endtime.setValue(calculatedEndTime);
enddate.setValue(calculatedEndTime);
});
starttime.on('change', function(e){
var hours = timeInput.getValue();
var startTime = starttime.getValue();
if('Mins' === unitsInput.getValue()){
var calculatedEndTime = Ext.Date.add(new Date(startTime), Ext.Date.MINUTE, parseInt(hours));
}else{
var calculatedEndTime = Ext.Date.add(new Date(startTime), Ext.Date.HOUR, parseInt(hours));
}
endtime.setValue(calculatedEndTime);
enddate.setValue(calculatedEndTime);
});
timeInput.on('change', function(e){
var hours = timeInput.getValue();
var startTime = starttime.getValue();
if('Mins' === unitsInput.getValue()){
var calculatedEndTime = Ext.Date.add(new Date(startTime), Ext.Date.MINUTE, parseInt(hours));
}else{
var calculatedEndTime = Ext.Date.add(new Date(startTime), Ext.Date.HOUR, parseInt(hours));
}
endtime.setValue(calculatedEndTime);
enddate.setValue(calculatedEndTime);
});
unitsInput.on('change', function(e){
var hours = timeInput.getValue();
var startTime = starttime.getValue();
if('Mins' === unitsInput.getValue()){
var calculatedEndTime = Ext.Date.add(new Date(startTime), Ext.Date.MINUTE, parseInt(hours));
}else{
var calculatedEndTime = Ext.Date.add(new Date(startTime), Ext.Date.HOUR, parseInt(hours));
}
endtime.setValue(calculatedEndTime);
enddate.setValue(calculatedEndTime);
});
}
}
+1
View File
@@ -19,6 +19,7 @@ class UserProfiles < Netzke::Basepack::Grid
c.model = "UserProfile" c.model = "UserProfile"
c.title = "Profile" c.title = "Profile"
c.force_fit = true
c.data_store = user_profiles_data_store c.data_store = user_profiles_data_store
c.scope = user_profiles_scope c.scope = user_profiles_scope
c.strong_default_attrs = user_profile_strong_default_attrs c.strong_default_attrs = user_profile_strong_default_attrs
+3 -2
View File
@@ -2,6 +2,7 @@ class UserRoleJoins < Netzke::Basepack::Grid
def configure(c) def configure(c)
super super
c.model = "UserRoleJoin" c.model = "UserRoleJoin"
c.force_fit = true
c.header = false c.header = false
c.title = "User Roles" c.title = "User Roles"
c.data_store.sorters = [{ :property => :user__username, :direction => :ASC}] c.data_store.sorters = [{ :property => :user__username, :direction => :ASC}]
@@ -10,9 +11,9 @@ class UserRoleJoins < Netzke::Basepack::Grid
{ :name => :name, :getter => lambda{ |rec| { :name => :name, :getter => lambda{ |rec|
user = User.find_by_id(rec.user_id) user = User.find_by_id(rec.user_id)
user.nil? ? "" : "#{user.first_name} #{user.last_name}" user.nil? ? "" : "#{user.first_name} #{user.last_name}"
}
}, },
{ :name => :role__role, :text => "Role"}, },
{ :name => :role__role, :text => "Role", :default_value => Role.exists? ? Role.first.id : nil},
:created_at, :created_at,
:updated_at, :updated_at,
:ends ] :ends ]
+1 -1
View File
@@ -40,7 +40,7 @@ class UserStats < Netzke::Base
private private
def user def user
controller.current_user User.find_by_id(session[:selected_user_id]) || controller.current_user
end end
end end
+1
View File
@@ -5,6 +5,7 @@ class UserTransactions < Netzke::Basepack::Grid
c.model = "Transaction" c.model = "Transaction"
c.title = "Transactions" c.title = "Transactions"
c.force_fit = true
c.scope = lambda { |rel| rel.where(:customer_id => controller.current_user.id, :customer_type => 'User');} c.scope = lambda { |rel| rel.where(:customer_id => controller.current_user.id, :customer_type => 'User');}
c.data_store = { auto_load: true } c.data_store = { auto_load: true }
c.columns = [ c.columns = [
@@ -5,10 +5,18 @@
// setting the 'rowclick' event // setting the 'rowclick' event
var view = this.getComponent('user_transactions').getView(); var view = this.getComponent('user_transactions').getView();
if( this.queryById('transaction_logs')){
this.queryById('transaction_logs').disable();
}
view.on('itemclick', function(view, record){ view.on('itemclick', function(view, record){
// The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server! // The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server!
this.selectTransaction({transaction_id: record.get('id')}); this.selectTransaction({transaction_id: record.get('id')});
this.getComponent('transaction_logs').getStore().load(); this.getComponent('transaction_logs').getStore().load();
if( this.queryById('transaction_logs')){
this.queryById('transaction_logs').enable();
}
}, this); }, this);
} }
} }
+2 -1
View File
@@ -12,13 +12,14 @@ class Users < Netzke::Basepack::Grid
super super
c.header = false c.header = false
c.model = "User" c.model = "User"
c.force_fit = true
c.columns = [ c.columns = [
{ :name => :username, :read_only => true }, { :name => :username, :read_only => true },
:first_name, :first_name,
:last_name, :last_name,
:email, :email,
{ :id => :bike__shop_id, :name => :bike__shop_id} { :text => "Bike - Shop ID", :id => :bike__shop_id, :name => :bike__shop_id, :default_value => Bike.exists? ? Bike.first.id : nil }
] ]
c.columns << :reset if can? :manage, User c.columns << :reset if can? :manage, User
@@ -1,10 +1,10 @@
class UsersAndCustomersAccordian < Netzke::Basepack::Accordion class UsersAndCustomersLowerTabs < Netzke::Basepack::TabPanel
component :customers component :customers
component :users component :users
def configure(c) def configure(c)
c.prevent_header = true c.prevent_header = true
c.items = [ :customers, :users ] c.items = [ :users, :customers ]
super super
end end
end end
+2 -4
View File
@@ -2,16 +2,14 @@ class UsersAndProfilesBorder < Netzke::Base
# Remember regions collapse state and size # Remember regions collapse state and size
include Netzke::Basepack::ItemPersistence include Netzke::Basepack::ItemPersistence
component :users component :users
component :user_profiles component :user_and_profiles_lower_tabs
component :user_logs
def configure(c) def configure(c)
super super
c.header = false c.header = false
c.items = [ c.items = [
{ netzke_component: :users, header: "Users", region: :center, width: 350, split: true }, { netzke_component: :users, header: "Users", region: :center, width: 350, split: true },
{ netzke_component: :user_profiles, region: :south, height: 150, split: true}, { netzke_component: :user_and_profiles_lower_tabs, region: :south, height: 300, split: true}
{ netzke_component: :user_logs, region: :east, split: true}
] ]
end end
@@ -2,18 +2,48 @@
initComponent: function(){ initComponent: function(){
// calling superclass's initComponent // calling superclass's initComponent
this.callParent(); this.callParent();
var stats = this.getComponent('user_stats'); var stats = this.queryById('user_stats');
if (stats != undefined){ if (stats != undefined){
stats.updateStats(); stats.updateStats();
} }
if( this.queryById('user_profiles')){
this.queryById('user_profiles').disable();
}
if( this.queryById('user_logs')){
this.queryById('user_logs').disable();
//update user stats
var store = this.queryById('user_logs').getStore()
store.on('load', function (store, records, operation, success){
if( this.queryById('user_stats') ){
this.queryById('user_stats').updateStats();
}
}, this);
}
if( this.queryById('user_stats') ){
this.queryById('user_stats').disable();
}
// setting the 'rowclick' event // setting the 'rowclick' event
var view = this.getComponent('users').getView(); var view = this.getComponent('users').getView();
view.on('itemclick', function(view, record){ view.on('itemclick', function(view, record){
// The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server! // The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server!
this.selectUser({user_id: record.get('id')}); this.selectUser({user_id: record.get('id')});
this.getComponent('user_profiles').getStore().load();
this.getComponent('user_logs').getStore().load(); if( this.queryById('user_profiles')){
this.queryById('user_profiles').getStore().load();
this.queryById('user_profiles').enable();
}
if( this.queryById('user_logs')){
this.queryById('user_logs').getStore().load();
this.queryById('user_logs').enable();
}
if( this.queryById('user_stats') ){
this.queryById('user_stats').updateStats();
this.queryById('user_stats').enable();
}
}, this); }, this);
} }
} }
+8 -7
View File
@@ -1,7 +1,7 @@
class Bike < ActiveRecord::Base class Bike < ActiveRecord::Base
acts_as_loggable acts_as_loggable
attr_accessible :shop_id, :serial_number, :bike_brand_id, :model, :color, :bike_style_id, :seat_tube_height, attr_accessible :shop_id, :serial_number, :bike_brand_id, :model, :color, :bike_style_id, :seat_tube_height,
:top_tube_length, :wheel_size, :value, :bike_condition_id, :bike_purpose_id :top_tube_length, :bike_wheel_size_id, :value, :bike_condition_id, :bike_purpose_id
has_many :transactions has_many :transactions
@@ -11,19 +11,16 @@ class Bike < ActiveRecord::Base
belongs_to :bike_style belongs_to :bike_style
belongs_to :bike_condition belongs_to :bike_condition
belongs_to :bike_purpose belongs_to :bike_purpose
belongs_to :bike_wheel_size
default_scope order('shop_id ASC') validates :shop_id, :presence => true, :uniqueness => true, :numericality => { :only_integer => true }
validates :shop_id, :presence => true, :uniqueness => true, :length => { :minimum => 3 }
validates :serial_number, :length => { :minimum => 3 } validates :serial_number, :length => { :minimum => 3 }
validates :model, :length => { :maximum => 50 } validates :model, :length => { :maximum => 50 }
validates :bike_brand_id, :presence => true validates :bike_brand_id, :presence => true
validates :color, :presence => true validates :color, :presence => true
validates :bike_style_id, :presence => true validates :bike_style_id, :presence => true
validates :seat_tube_height, :presence => true validates :seat_tube_height, :presence => true
validates :top_tube_length, :presence => true validates :bike_wheel_size_id, :presence => true
validates :wheel_size, :presence => true
#validates :value, :presence => true
validates :bike_condition_id, :presence => true validates :bike_condition_id, :presence => true
validates :bike_purpose_id, :presence => true validates :bike_purpose_id, :presence => true
@@ -47,6 +44,10 @@ class Bike < ActiveRecord::Base
self.bike_purpose self.bike_purpose
end end
def wheel_size
self.bike_wheel_size
end
def to_s def to_s
"#{brand} - #{model} - #{style}" "#{brand} - #{model} - #{style}"
end end
+16
View File
@@ -0,0 +1,16 @@
class BikeWheelSize < ActiveRecord::Base
belongs_to :bike
def display_string
result = []
result << "#{twmm}-#{rdmm}" unless twmm.blank? and rdmm.blank?
result << "#{rdin}x#{twin}" unless rdin.blank? and twin.blank?
result << "#{rdfr}x#{twfr}" unless rdfr.blank? and twfr.blank?
result << description unless description.blank?
result.join(" | ")
end
def to_s
"#{twmm}-#{rdmm} #{rdin}x#{twin} #{rdfr}x#{twfr} '#{description}' #{tire_common_score}"
end
end
+3
View File
@@ -11,6 +11,9 @@
body { body {
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */ padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
} }
.x-boundlist-item {
white-space: nowrap;
}
%body %body
.container .container
@@ -0,0 +1,22 @@
class ChangeBikeShopId < ActiveRecord::Migration
# We don't use change_column because we have arbitrary strings we
# need to strip the characters from to make the integer values
def up
bikes = Bike.all
remove_column :bikes, :shop_id
add_column :bikes, :shop_id, :integer, :unique => true
# deconflict shop ids
bikes.each do |bike|
new_id = bike.shop_id.gsub(/[^\d]/, '').to_i rescue 1
while bikes.map(&:shop_id).include? new_id
new_id += 1
end
bike.update_attribute(:shop_id, new_id)
end
end
def down
change_column :bikes, :shop_id, :string
end
end
@@ -0,0 +1,22 @@
class CreateBikeWheelSizes < ActiveRecord::Migration
def up
create_table(:bike_wheel_sizes) do |t|
t.string :twmm
t.string :rdmm
t.string :twin
t.string :rdin
t.string :twfr
t.string :rdfr
t.string :description
t.string :tire_common_score
end
#create the default undetermined wheel size record
BikeWheelSize.create( twmm: 0, rdmm: 0, rdin: 0, twin: 0, rdfr: 0, twfr: 0, description: "UNDETERMINED", tire_common_score: 0)
ActiveRecord::Base.connection.execute(IO.read(File.join(Rails.root, "db", "seed", "sql", "common_wheel_sizes.sql")))
end
def down
drop_table :bike_wheel_sizes
end
end
@@ -0,0 +1,34 @@
class AlterBikeWheelToId < ActiveRecord::Migration
def up
add_column :bikes, :bike_wheel_size_id, :integer
undetermined_id = BikeWheelSize.find_by_rdin("0")
Bike.find_each do |bike|
wheel_size = BikeWheelSize.find_by_rdin(bike['wheel_size'].to_s)
if wheel_size.nil?
wheel_size_id = undetermined_id
else
wheel_size_id = wheel_size.id
end
bike.bike_wheel_size_id = wheel_size_id
bike.save
end
remove_column :bikes, :wheel_size
end
def down
add_column :bikes, :wheel_size, :integer
Bike.find_each do |bike|
wheel_size = BikeWheelSize.find_by_id(bike['bike_wheel_size_id'])
bike.wheel_size = wheel_size.rdin.to_i
bike.save
end
remove_column :bikes, :bike_wheel_size_id
end
end
+14 -5
View File
@@ -11,7 +11,7 @@
# #
# It's strongly recommended to check this file into your version control system. # It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130902201853) do ActiveRecord::Schema.define(:version => 20131019170248) do
create_table "bike_actions", :force => true do |t| create_table "bike_actions", :force => true do |t|
t.string "action", :limit => 128, :null => false t.string "action", :limit => 128, :null => false
@@ -46,6 +46,17 @@ ActiveRecord::Schema.define(:version => 20130902201853) do
t.datetime "updated_at", :null => false t.datetime "updated_at", :null => false
end end
create_table "bike_wheel_sizes", :force => true do |t|
t.string "twmm"
t.string "rdmm"
t.string "twin"
t.string "rdin"
t.string "twfr"
t.string "rdfr"
t.string "description"
t.string "tire_common_score"
end
create_table "bikes", :force => true do |t| create_table "bikes", :force => true do |t|
t.string "serial_number" t.string "serial_number"
t.integer "bike_brand_id", :null => false t.integer "bike_brand_id", :null => false
@@ -54,18 +65,16 @@ ActiveRecord::Schema.define(:version => 20130902201853) do
t.integer "bike_style_id", :null => false t.integer "bike_style_id", :null => false
t.float "seat_tube_height" t.float "seat_tube_height"
t.float "top_tube_length" t.float "top_tube_length"
t.integer "wheel_size"
t.float "value" t.float "value"
t.integer "bike_condition_id", :null => false t.integer "bike_condition_id", :null => false
t.integer "bike_purpose_id", :null => false t.integer "bike_purpose_id", :null => false
t.datetime "created_at", :null => false t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false t.datetime "updated_at", :null => false
t.string "shop_id"
t.string "model" t.string "model"
t.integer "shop_id"
t.integer "bike_wheel_size_id"
end end
add_index "bikes", ["shop_id"], :name => "index_bikes_on_shop_id", :unique => true
create_table "credit_conversions", :force => true do |t| create_table "credit_conversions", :force => true do |t|
t.integer "conversion", :default => 1 t.integer "conversion", :default => 1
t.datetime "created_at", :null => false t.datetime "created_at", :null => false
+37
View File
@@ -0,0 +1,37 @@
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (54,110,'8 1/2','2','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (62,203,'12','1/2 x 2 1/4','320 ','57','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (47,305,'16','1,75 [x 2]','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (32,369,'16','1 1/4','','','Moulton',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (47,355,'18','1,75 [ x 2]','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (28,406,'20','1 1/8','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (37,406,'20','1 3/8','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (47,406,'20','1,75 [ x 2]','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (47,507,'24','1,75 [ x 2]','600 ','50C','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (37,540,'24','1 3/8 A','600 ','35A','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (25,559,'26','1','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (32,559,'26','1,3','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (37,559,'26','1,5','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (40,559,'26','1,6','','','MTB',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (44,559,'26','1,6','','','City/trekking',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (47,559,'26','1,75 [ x 2]','650 ','50','City/Trekking',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (NULL,NULL,'26','1,9','','','MTB',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (50,'559','26','1,9','','','City/Trekking',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (NULL,NULL,'26','2','','','MTB',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (54,559,'26','2,1','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (57,559,'26','2,3 [2,125]','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (20,571,'','','650 ','20C','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (23,571,'','','650 ','23C','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (28,584,'26','1 1/8 x 1 1/2 B','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (37,584,'26','1 3/8 x 1 1/2 B','650 ','38A','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (37,590,'26','1 3/8','650 [','35] A','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (20,622,'','','700 ','20C','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (23,622,'','','700 ','23C','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (25,622,'','','700 ','25C','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (28,622,'28','1 5/8 x 1 3/8','700 ','28C [700C]','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (32,622,'28','1 1/4 x 1 3/4','700 ','32C [700C Course]','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (37,622,'28','1 3/8 x 1 5/8','700 ','37C [35C]','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (42,622,'28','1,6','700 ','42C [40C]','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (47,622,'28','1,75','700 ','47C [45C]','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (28,630,'27','1 1/8 [1 1/4 fifty]','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (32,630,'27','1 1/4','','','',1);
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (40,635,'28','1 1/2 [1 3/8]','700 ','38B [35B]','',1);
+17 -10
View File
@@ -14,21 +14,28 @@ end
#Load bike brands and models from sql #Load bike brands and models from sql
if BikeBrand.all.empty? and BikeModel.all.empty? if BikeBrand.all.empty? and BikeModel.all.empty?
sql_path = File.join(Rails.root, 'db', 'seed', 'sql', 'bike_brands_and_models.sql') # Need to use DEFAULT instead of explicit IDs that are used in the sql file,
db_config = Rails.application.config.database_configuration[Rails.env] # so that the PG table ID sequence is incremented
cmd = "psql #{db_config["database"]} < #{sql_path}" #
system cmd # Note the drop(1) which assumes we have a junk PRAGMA line at the top
load_statements = File.readlines(File.join(Rails.root, 'db', 'seed', 'sql', 'bike_brands_and_models.sql')).drop(1).map do |statement|
statement.sub(/VALUES\(\d+,/, 'VALUES(DEFAULT,')
end
ActiveRecord::Base.connection.execute(load_statements.join)
end end
if Rails.env.development? if Rails.env.development?
#create default admin user #create default users
if User.all.empty? if User.all.empty?
FactoryGirl.create(:user) u = FactoryGirl.create(:user)
FactoryGirl.create(:staff) FactoryGirl.create(:user_profile, user_id: u.id)
FactoryGirl.create(:bike_admin) u = FactoryGirl.create(:staff)
FactoryGirl.create(:admin) FactoryGirl.create(:user_profile, user_id: u.id)
FactoryGirl.create(:user_profile) u = FactoryGirl.create(:bike_admin)
FactoryGirl.create(:user_profile, user_id: u.id)
u = FactoryGirl.create(:admin)
FactoryGirl.create(:user_profile, user_id: u.id)
end end
#create fake bikes #create fake bikes
+12 -14
View File
@@ -2,21 +2,19 @@
FactoryGirl.define do FactoryGirl.define do
factory :bike do factory :bike do
sequence :shop_id do |n| sequence(:shop_id) {|n| n}
"Shop ID #{n}"
end
sequence :serial_number do |n| sequence :serial_number do |n|
"S/N# #{n}" "#{Faker::Code.isbn}-#{n}"
end end
bike_brand_id 1 bike_brand_id { BikeBrand.all.sample.id }
bike_model_id 1 model { Faker::Commerce.product_name }
color "FFFFFF" color { sprintf("%06X", Random.rand(16777215) ) }
bike_style_id 1 bike_style_id { BikeStyle.all.sample.id }
seat_tube_height 5 seat_tube_height { Random.rand(25) }
top_tube_length 6 top_tube_length { Random.rand(25) }
wheel_size 27 bike_wheel_size_id { BikeWheelSize.all.sample.id }
value 100 value { Random.rand(200) }
bike_condition_id 1 bike_condition_id { BikeCondition.all.sample.id }
bike_purpose_id 1 bike_purpose_id { BikePurpose.all.sample.id }
end end
end end
+6 -6
View File
@@ -1,11 +1,11 @@
FactoryGirl.define do FactoryGirl.define do
factory :user_profile do factory :user_profile do
user_id 1 user_id 1
addrStreet1 "Charles Street" addrStreet1 { Faker::Address.street_address }
addrStreet2 "Apt #42" addrStreet2 { Faker::Address.secondary_address }
addrCity "Baltimore" addrCity { Faker::Address.city }
addrState "MD" addrState { Faker::Address.state_abbr }
addrZip "21231" addrZip { Faker::Address.zip_code }
phone "(410)8675309" phone { Faker::PhoneNumber.cell_phone }
end end
end end
+1
View File
@@ -1,5 +1,6 @@
FactoryGirl.define do FactoryGirl.define do
factory :user do factory :user do
sequence(:username) { |n| "user_#{n}" } sequence(:username) { |n| "user_#{n}" }
sequence(:email) { |n| "user_#{n}@example.com" } sequence(:email) { |n| "user_#{n}@example.com" }
password 'password' password 'password'