fat_free_crm 0.12.3 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fat_free_crm might be problematic. Click here for more details.

Files changed (521) hide show
  1. checksums.yaml +5 -13
  2. data/.travis.yml +1 -11
  3. data/Gemfile +7 -19
  4. data/Gemfile.lock +166 -166
  5. data/Procfile +1 -1
  6. data/README.md +20 -20
  7. data/app/assets/javascripts/admin/fields.js.coffee +3 -3
  8. data/app/assets/javascripts/application.js.erb +3 -0
  9. data/app/assets/javascripts/crm.js +1 -0
  10. data/app/assets/javascripts/crm_comments.js.coffee +66 -0
  11. data/app/assets/javascripts/lists.js.coffee +45 -2
  12. data/app/assets/javascripts/search.js.coffee +2 -0
  13. data/app/assets/javascripts/timeago.js +17 -0
  14. data/app/assets/stylesheets/advanced_search.css.scss +49 -25
  15. data/app/assets/stylesheets/application.css.erb +3 -0
  16. data/app/assets/stylesheets/common.scss +13 -0
  17. data/app/assets/stylesheets/format_buttons.css.scss +15 -10
  18. data/app/assets/stylesheets/header.scss +3 -0
  19. data/app/assets/stylesheets/lists.css.scss +4 -0
  20. data/app/controllers/admin/fields_controller.rb +5 -5
  21. data/app/controllers/admin/users_controller.rb +1 -3
  22. data/app/controllers/application_controller.rb +23 -23
  23. data/app/controllers/comments_controller.rb +3 -31
  24. data/app/controllers/entities/accounts_controller.rb +3 -3
  25. data/app/controllers/entities/campaigns_controller.rb +4 -4
  26. data/app/controllers/entities/contacts_controller.rb +2 -2
  27. data/app/controllers/entities/leads_controller.rb +3 -3
  28. data/app/controllers/entities/opportunities_controller.rb +4 -3
  29. data/app/controllers/entities_controller.rb +6 -6
  30. data/app/controllers/home_controller.rb +1 -1
  31. data/app/controllers/lists_controller.rb +8 -1
  32. data/app/controllers/tasks_controller.rb +1 -1
  33. data/app/controllers/users_controller.rb +46 -23
  34. data/app/helpers/admin/application_helper.rb +1 -3
  35. data/app/helpers/admin/field_groups_helper.rb +2 -1
  36. data/app/helpers/application_helper.rb +37 -16
  37. data/app/helpers/home_helper.rb +1 -2
  38. data/app/helpers/leads_helper.rb +5 -6
  39. data/app/helpers/tasks_helper.rb +36 -50
  40. data/app/models/entities/account.rb +10 -7
  41. data/app/models/entities/campaign.rb +4 -4
  42. data/app/models/entities/contact.rb +8 -5
  43. data/app/models/entities/lead.rb +8 -8
  44. data/app/models/entities/opportunity.rb +13 -18
  45. data/app/models/fields/custom_field.rb +10 -0
  46. data/app/models/fields/field.rb +3 -3
  47. data/app/models/fields/field_group.rb +1 -1
  48. data/app/models/list.rb +1 -0
  49. data/app/models/polymorphic/address.rb +3 -3
  50. data/app/models/polymorphic/comment.rb +2 -4
  51. data/app/models/polymorphic/task.rb +32 -27
  52. data/app/models/setting.rb +3 -9
  53. data/app/models/users/ability.rb +2 -13
  54. data/app/models/users/user.rb +12 -15
  55. data/app/views/accounts/_edit.html.haml +1 -1
  56. data/app/views/accounts/_index_brief.html.haml +3 -3
  57. data/app/views/accounts/_index_long.html.haml +3 -3
  58. data/app/views/accounts/_new.html.haml +1 -1
  59. data/app/views/accounts/create.js.haml +17 -0
  60. data/app/views/accounts/destroy.js.haml +6 -0
  61. data/app/views/accounts/edit.js.haml +32 -0
  62. data/app/views/accounts/index.js.haml +11 -0
  63. data/app/views/accounts/index.xls.builder +9 -7
  64. data/app/views/accounts/new.js.haml +11 -0
  65. data/app/views/accounts/show.js.haml +5 -0
  66. data/app/views/accounts/update.js.haml +17 -0
  67. data/app/views/admin/field_groups/_edit.html.haml +1 -1
  68. data/app/views/admin/field_groups/_new.html.haml +1 -1
  69. data/app/views/admin/field_groups/confirm.js.haml +7 -0
  70. data/app/views/admin/field_groups/create.js.haml +20 -0
  71. data/app/views/admin/field_groups/destroy.js.haml +9 -0
  72. data/app/views/admin/field_groups/edit.js.haml +12 -0
  73. data/app/views/admin/field_groups/new.js.haml +8 -0
  74. data/app/views/admin/field_groups/update.js.haml +8 -0
  75. data/app/views/admin/fields/_field.html.haml +2 -2
  76. data/app/views/admin/fields/_form.html.haml +2 -2
  77. data/app/views/admin/fields/create.js.haml +17 -0
  78. data/app/views/admin/fields/destroy.js.haml +8 -0
  79. data/app/views/admin/fields/edit.js.haml +3 -0
  80. data/app/views/admin/fields/update.js.haml +13 -0
  81. data/app/views/admin/groups/_edit.html.haml +1 -1
  82. data/app/views/admin/groups/_new.html.haml +1 -1
  83. data/app/views/admin/groups/create.js.haml +10 -0
  84. data/app/views/admin/groups/destroy.js.haml +9 -0
  85. data/app/views/admin/groups/edit.js.haml +14 -0
  86. data/app/views/admin/groups/index.html.haml +1 -1
  87. data/app/views/admin/groups/index.js.haml +2 -0
  88. data/app/views/admin/groups/new.js.haml +9 -0
  89. data/app/views/admin/groups/update.js.haml +9 -0
  90. data/app/views/admin/tags/_edit.html.haml +1 -1
  91. data/app/views/admin/tags/_new.html.haml +1 -1
  92. data/app/views/admin/tags/confirm.js.haml +7 -0
  93. data/app/views/admin/tags/create.js.haml +11 -0
  94. data/app/views/admin/tags/destroy.js.haml +10 -0
  95. data/app/views/admin/tags/edit.js.haml +20 -0
  96. data/app/views/admin/tags/new.js.haml +7 -0
  97. data/app/views/admin/tags/update.js.haml +9 -0
  98. data/app/views/admin/users/_edit.html.haml +1 -1
  99. data/app/views/admin/users/_new.html.haml +1 -1
  100. data/app/views/admin/users/_user.html.haml +1 -1
  101. data/app/views/admin/users/confirm.js.haml +7 -0
  102. data/app/views/admin/users/create.js.haml +10 -0
  103. data/app/views/admin/users/destroy.js.haml +10 -0
  104. data/app/views/admin/users/edit.js.haml +20 -0
  105. data/app/views/admin/users/index.js.haml +2 -0
  106. data/app/views/admin/users/new.js.haml +9 -0
  107. data/app/views/admin/users/reactivate.js.haml +3 -0
  108. data/app/views/admin/users/suspend.js.haml +3 -0
  109. data/app/views/admin/users/update.js.haml +9 -0
  110. data/app/views/authentications/new.html.haml +1 -1
  111. data/app/views/campaigns/_edit.html.haml +1 -1
  112. data/app/views/campaigns/_new.html.haml +1 -1
  113. data/app/views/campaigns/create.js.haml +20 -0
  114. data/app/views/campaigns/destroy.js.haml +6 -0
  115. data/app/views/campaigns/edit.js.haml +33 -0
  116. data/app/views/campaigns/index.js.haml +11 -0
  117. data/app/views/campaigns/index.xls.builder +9 -7
  118. data/app/views/campaigns/new.js.haml +11 -0
  119. data/app/views/campaigns/show.js.haml +5 -0
  120. data/app/views/campaigns/update.js.haml +20 -0
  121. data/app/views/comments/_comment.html.haml +1 -1
  122. data/app/views/comments/_edit.html.haml +1 -1
  123. data/app/views/comments/_new.html.haml +3 -2
  124. data/app/views/comments/create.js.haml +14 -0
  125. data/app/views/comments/destroy.js.haml +5 -0
  126. data/app/views/comments/edit.js.haml +11 -0
  127. data/app/views/comments/update.js.haml +9 -0
  128. data/app/views/contacts/_edit.html.haml +1 -1
  129. data/app/views/contacts/_index_full.html.haml +1 -1
  130. data/app/views/contacts/_index_long.html.haml +2 -1
  131. data/app/views/contacts/_new.html.haml +1 -1
  132. data/app/views/contacts/_section_general.html.haml +3 -3
  133. data/app/views/contacts/create.js.haml +23 -0
  134. data/app/views/contacts/destroy.js.haml +9 -0
  135. data/app/views/contacts/edit.js.haml +35 -0
  136. data/app/views/contacts/index.js.haml +11 -0
  137. data/app/views/contacts/index.xls.builder +9 -7
  138. data/app/views/contacts/new.js.haml +13 -0
  139. data/app/views/contacts/show.js.haml +5 -0
  140. data/app/views/contacts/update.js.haml +22 -0
  141. data/app/views/emails/destroy.js.haml +5 -0
  142. data/app/views/entities/_permissions.html.haml +1 -1
  143. data/app/views/entities/attach.js.haml +21 -0
  144. data/app/views/entities/contacts.js.haml +3 -0
  145. data/app/views/entities/discard.js.haml +6 -0
  146. data/app/views/entities/leads.js.haml +3 -0
  147. data/app/views/entities/opportunities.js.haml +3 -0
  148. data/app/views/entities/subscription_update.js.haml +4 -0
  149. data/app/views/entities/versions.js.haml +3 -0
  150. data/app/views/fields/group.js.erb +3 -0
  151. data/app/views/home/_account.html.haml +3 -3
  152. data/app/views/home/_opportunity.html.haml +3 -3
  153. data/app/views/home/index.atom.builder +3 -3
  154. data/app/views/home/index.js.haml +7 -0
  155. data/app/views/home/index.rss.builder +2 -2
  156. data/app/views/home/options.js.haml +7 -0
  157. data/app/views/layouts/_footer.html.haml +0 -4
  158. data/app/views/layouts/_sidebar.html.haml +1 -0
  159. data/app/views/layouts/_tabbed.html.haml +1 -4
  160. data/app/views/layouts/admin/application.html.haml +0 -1
  161. data/app/views/layouts/application.html.haml +5 -7
  162. data/app/views/leads/_convert.html.haml +1 -1
  163. data/app/views/leads/_edit.html.haml +1 -1
  164. data/app/views/leads/_index_long.html.haml +2 -2
  165. data/app/views/leads/_new.html.haml +1 -1
  166. data/app/views/leads/convert.js.haml +35 -0
  167. data/app/views/leads/create.js.haml +21 -0
  168. data/app/views/leads/destroy.js.haml +9 -0
  169. data/app/views/leads/edit.js.haml +35 -0
  170. data/app/views/leads/index.js.haml +11 -0
  171. data/app/views/leads/index.xls.builder +9 -7
  172. data/app/views/leads/new.js.haml +11 -0
  173. data/app/views/leads/promote.js.haml +26 -0
  174. data/app/views/leads/reject.js.haml +12 -0
  175. data/app/views/leads/show.js.haml +5 -0
  176. data/app/views/leads/update.js.haml +26 -0
  177. data/app/views/lists/_personal_sidebar.html.haml +28 -0
  178. data/app/views/lists/_sidebar.html.haml +10 -7
  179. data/app/views/lists/create.js.haml +10 -0
  180. data/app/views/lists/destroy.js.haml +1 -0
  181. data/app/views/opportunities/_edit.html.haml +1 -1
  182. data/app/views/opportunities/_index_brief.html.haml +3 -3
  183. data/app/views/opportunities/_index_long.html.haml +3 -3
  184. data/app/views/opportunities/_new.html.haml +1 -2
  185. data/app/views/opportunities/_top_section.html.haml +4 -0
  186. data/app/views/opportunities/contacts.js.haml +3 -0
  187. data/app/views/opportunities/create.js.haml +29 -0
  188. data/app/views/opportunities/destroy.js.haml +13 -0
  189. data/app/views/opportunities/edit.js.haml +35 -0
  190. data/app/views/opportunities/index.js.haml +11 -0
  191. data/app/views/opportunities/index.xls.builder +9 -7
  192. data/app/views/opportunities/new.js.haml +13 -0
  193. data/app/views/opportunities/show.js.haml +5 -0
  194. data/app/views/opportunities/update.js.haml +25 -0
  195. data/app/views/passwords/edit.html.haml +1 -1
  196. data/app/views/passwords/new.html.haml +1 -1
  197. data/app/views/shared/_comment.html.haml +1 -1
  198. data/app/views/shared/_inline_styles.html.haml +1 -1
  199. data/app/views/tasks/_edit.html.haml +1 -1
  200. data/app/views/tasks/_new.html.haml +1 -1
  201. data/app/views/tasks/complete.js.haml +14 -0
  202. data/app/views/tasks/create.js.haml +39 -0
  203. data/app/views/tasks/destroy.js.haml +7 -0
  204. data/app/views/tasks/discard.js.haml +1 -0
  205. data/app/views/tasks/edit.js.haml +26 -0
  206. data/app/views/tasks/filter.js.haml +4 -0
  207. data/app/views/tasks/index.xls.builder +7 -5
  208. data/app/views/tasks/new.js.haml +8 -0
  209. data/app/views/tasks/update.js.haml +19 -0
  210. data/app/views/users/_password.html.haml +1 -1
  211. data/app/views/users/_profile.html.haml +1 -1
  212. data/app/views/users/avatar.js.haml +9 -0
  213. data/app/views/users/change_password.js.haml +13 -0
  214. data/app/views/users/edit.js.haml +9 -0
  215. data/app/views/users/new.html.haml +1 -1
  216. data/app/views/users/password.js.haml +10 -0
  217. data/app/views/users/update.js.haml +9 -0
  218. data/app/views/users/upload_avatar.js.haml +7 -0
  219. data/app/views/versions/_version.html.haml +1 -1
  220. data/config/application.rb +1 -4
  221. data/config/environments/production.rb +3 -2
  222. data/config/initializers/custom_field_ransack_translations.rb +15 -0
  223. data/config/initializers/locale.rb +9 -1
  224. data/config/initializers/secret_token.rb +1 -25
  225. data/config/initializers/views.rb +20 -20
  226. data/config/locales/cz.yml +245 -211
  227. data/config/locales/cz_fat_free_crm.yml +105 -181
  228. data/config/locales/de.yml +162 -118
  229. data/config/locales/de_fat_free_crm.yml +760 -731
  230. data/config/locales/de_ransack.yml +91 -0
  231. data/config/locales/en-GB.yml +158 -119
  232. data/config/locales/en-GB_fat_free_crm.yml +161 -279
  233. data/config/locales/en-US.yml +158 -121
  234. data/config/locales/en-US_fat_free_crm.yml +185 -179
  235. data/config/locales/en-US_ransack.yml +81 -82
  236. data/config/locales/es.yml +164 -123
  237. data/config/locales/es_fat_free_crm.yml +151 -209
  238. data/config/locales/fr-CA.yml +167 -130
  239. data/config/locales/fr-CA_fat_free_crm.yml +142 -202
  240. data/config/locales/fr.yml +170 -125
  241. data/config/locales/fr_fat_free_crm.yml +199 -302
  242. data/config/locales/it.yml +158 -122
  243. data/config/locales/it_fat_free_crm.yml +105 -168
  244. data/config/locales/ja.yml +162 -131
  245. data/config/locales/ja_fat_free_crm.yml +118 -188
  246. data/config/locales/pl.yml +168 -132
  247. data/config/locales/pl_fat_free_crm.yml +115 -186
  248. data/config/locales/pt-BR.yml +160 -127
  249. data/config/locales/pt-BR_fat_free_crm.yml +125 -182
  250. data/config/locales/ru.yml +256 -233
  251. data/config/locales/ru_fat_free_crm.yml +136 -193
  252. data/config/locales/sv-SE.yml +164 -181
  253. data/config/locales/sv-SE_fat_free_crm.yml +129 -193
  254. data/config/locales/th_fat_free_crm.yml +114 -194
  255. data/config/locales/zh-CN.yml +176 -149
  256. data/config/locales/zh-CN_fat_free_crm.yml +78 -167
  257. data/config/routes.rb +1 -1
  258. data/config/settings.default.yml +74 -23
  259. data/custom_plan.rb +11 -0
  260. data/db/migrate/20131207033244_add_user_id_to_lists.rb +6 -0
  261. data/db/schema.rb +4 -1
  262. data/fat_free_crm.gemspec +3 -3
  263. data/lib/fat_free_crm.rb +1 -11
  264. data/lib/fat_free_crm/export_csv.rb +3 -3
  265. data/lib/fat_free_crm/fields.rb +10 -0
  266. data/lib/fat_free_crm/gem_dependencies.rb +1 -2
  267. data/lib/fat_free_crm/i18n.rb +9 -5
  268. data/lib/fat_free_crm/version.rb +2 -2
  269. data/lib/fat_free_crm/view_factory.rb +8 -5
  270. data/lib/tasks/ffcrm/config.rake +9 -12
  271. data/lib/tasks/ffcrm/missing_translations.rake +2 -1
  272. data/spec/controllers/admin/users_controller_spec.rb +6 -4
  273. data/spec/controllers/applications_controller_spec.rb +4 -4
  274. data/spec/controllers/authentications_controller_spec.rb +15 -15
  275. data/spec/controllers/comments_controller_spec.rb +9 -87
  276. data/spec/controllers/emails_controller_spec.rb +1 -1
  277. data/spec/controllers/entities/accounts_controller_spec.rb +7 -7
  278. data/spec/controllers/entities/campaigns_controller_spec.rb +5 -5
  279. data/spec/controllers/entities/contacts_controller_spec.rb +7 -7
  280. data/spec/controllers/entities/leads_controller_spec.rb +14 -14
  281. data/spec/controllers/entities/opportunities_controller_spec.rb +8 -8
  282. data/spec/controllers/home_controller_spec.rb +6 -6
  283. data/spec/controllers/tasks_controller_spec.rb +7 -7
  284. data/spec/controllers/users_controller_spec.rb +22 -50
  285. data/spec/features/support/selector_helpers.rb +1 -6
  286. data/spec/features/tasks_spec.rb +2 -2
  287. data/spec/helpers/application_helper_spec.rb +15 -15
  288. data/spec/lib/fields_spec.rb +29 -29
  289. data/spec/lib/mail_processor/base_spec.rb +7 -7
  290. data/spec/lib/mail_processor/dropbox_spec.rb +3 -3
  291. data/spec/lib/view_factory_spec.rb +14 -14
  292. data/spec/models/entities/opportunity_spec.rb +1 -1
  293. data/spec/models/fields/custom_field_date_pair_spec.rb +14 -14
  294. data/spec/models/fields/custom_field_pair_spec.rb +13 -13
  295. data/spec/models/fields/custom_field_spec.rb +5 -5
  296. data/spec/models/fields/field_spec.rb +2 -2
  297. data/spec/models/observers/entity_observer_spec.rb +2 -2
  298. data/spec/models/users/user_spec.rb +7 -7
  299. data/spec/routing/comments_routing_spec.rb +0 -9
  300. data/spec/shared/controllers.rb +75 -77
  301. data/spec/shared/models.rb +1 -1
  302. data/spec/spec_helper.rb +1 -2
  303. data/spec/support/auth_macros.rb +3 -3
  304. data/spec/support/mail_processor_mocks.rb +13 -13
  305. data/spec/views/accounts/_edit.haml_spec.rb +1 -1
  306. data/spec/views/accounts/{create.rjs_spec.rb → create.js.haml_spec.rb} +9 -14
  307. data/spec/views/accounts/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -8
  308. data/spec/views/accounts/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +10 -18
  309. data/spec/views/accounts/{index.rjs_spec.rb → index.js.haml_spec.rb} +7 -11
  310. data/spec/views/accounts/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
  311. data/spec/views/accounts/show.haml_spec.rb +1 -1
  312. data/spec/views/accounts/{update.rjs_spec.rb → update.js.haml_spec.rb} +16 -25
  313. data/spec/views/admin/field_groups/create.js.haml_spec.rb +31 -0
  314. data/spec/views/admin/field_groups/destroy.js.haml_spec.rb +31 -0
  315. data/spec/views/admin/field_groups/edit.js.haml_spec.rb +24 -0
  316. data/spec/views/admin/field_groups/new.js.haml_spec.rb +25 -0
  317. data/spec/views/admin/field_groups/update.js.haml_spec.rb +30 -0
  318. data/spec/views/admin/users/_create.haml_spec.rb +1 -1
  319. data/spec/views/admin/users/{create.rjs_spec.rb → create.js.haml_spec.rb} +6 -9
  320. data/spec/views/admin/users/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -7
  321. data/spec/views/admin/users/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +6 -12
  322. data/spec/views/admin/users/index.haml_spec.rb +0 -0
  323. data/spec/views/admin/users/{index.rjs_spec.rb → index.js.haml_spec.rb} +3 -5
  324. data/spec/views/admin/users/{new.rjs_spec.rb → new.js.haml_spec.rb} +4 -6
  325. data/spec/views/admin/users/{reactivate.rjs_spec.rb → reactivate.js.haml_spec.rb} +2 -4
  326. data/spec/views/admin/users/show.haml_spec.rb +0 -0
  327. data/spec/views/admin/users/{suspend.rjs_spec.rb → suspend.js.haml_spec.rb} +2 -4
  328. data/spec/views/admin/users/{update.rjs_spec.rb → update.js.haml_spec.rb} +6 -10
  329. data/spec/views/campaigns/{create.rjs_spec.rb → create.js.haml_spec.rb} +9 -14
  330. data/spec/views/campaigns/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -7
  331. data/spec/views/campaigns/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +11 -19
  332. data/spec/views/campaigns/{index.rjs_spec.rb → index.js.haml_spec.rb} +5 -9
  333. data/spec/views/campaigns/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
  334. data/spec/views/campaigns/{update.rjs_spec.rb → update.js.haml_spec.rb} +14 -21
  335. data/spec/views/comments/{new.rjs_spec.rb → edit.js.haml_spec.rb} +12 -9
  336. data/spec/views/contacts/{create.rjs_spec.rb → create.js.haml_spec.rb} +9 -16
  337. data/spec/views/contacts/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -8
  338. data/spec/views/contacts/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +12 -19
  339. data/spec/views/contacts/index.haml_spec.rb +1 -1
  340. data/spec/views/contacts/{index.rjs_spec.rb → index.js.html_spec.rb} +7 -11
  341. data/spec/views/contacts/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -7
  342. data/spec/views/contacts/{update.rjs_spec.rb → update.js.haml_spec.rb} +20 -35
  343. data/spec/views/home/{index.rjs_spec.rb → index.js.haml_spec.rb} +2 -4
  344. data/spec/views/home/{options.rjs_spec.rb → options.js.haml_spec.rb} +7 -12
  345. data/spec/views/leads/{convert.rjs_spec.rb → convert.js.haml_spec.rb} +12 -20
  346. data/spec/views/leads/{create.rjs_spec.rb → create.js.haml_spec.rb} +13 -19
  347. data/spec/views/leads/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +9 -12
  348. data/spec/views/leads/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +12 -20
  349. data/spec/views/leads/{index.rjs_spec.rb → index.js.haml_spec.rb} +5 -9
  350. data/spec/views/leads/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
  351. data/spec/views/leads/{promote.rjs_spec.rb → promote.js.haml_spec.rb} +28 -43
  352. data/spec/views/leads/{reject.rjs_spec.rb → reject.js.haml_spec.rb} +10 -17
  353. data/spec/views/leads/{update.rjs_spec.rb → update.js.haml_spec.rb} +25 -38
  354. data/spec/views/opportunities/{create.rjs_spec.rb → create.js.haml_spec.rb} +16 -26
  355. data/spec/views/opportunities/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +13 -16
  356. data/spec/views/opportunities/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +10 -18
  357. data/spec/views/opportunities/{index.rjs_spec.rb → index.js.haml_spec.rb} +7 -12
  358. data/spec/views/opportunities/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
  359. data/spec/views/opportunities/{update.rjs_spec.rb → update.js.haml_spec.rb} +29 -46
  360. data/spec/views/tasks/_edit.haml_spec.rb +1 -1
  361. data/spec/views/tasks/{complete.rjs_spec.rb → complete.js.haml_spec.rb} +9 -14
  362. data/spec/views/tasks/{create.rjs_spec.rb → create.js.haml_spec.rb} +25 -33
  363. data/spec/views/tasks/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +9 -11
  364. data/spec/views/tasks/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +9 -14
  365. data/spec/views/tasks/index.haml_spec.rb +1 -2
  366. data/spec/views/tasks/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
  367. data/spec/views/tasks/{update.rjs_spec.rb → update.js.haml_spec.rb} +28 -41
  368. data/spec/views/users/{avatar.rjs_spec.rb → avatar.js.haml_spec.rb} +7 -9
  369. data/spec/views/users/{change_password.rjs_spec.rb → change_password.js.haml_spec.rb} +10 -12
  370. data/spec/views/users/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +8 -10
  371. data/spec/views/users/{password.rjs_spec.rb → password.js.haml_spec.rb} +9 -11
  372. data/spec/views/users/{update.rjs_spec.rb → update.js.haml_spec.rb} +7 -15
  373. data/spec/views/users/{upload_avatar.rjs_spec.rb → upload_avatar.js.haml_spec.rb} +8 -10
  374. data/vendor/assets/javascripts/ajax-chosen-jquery.js +2 -0
  375. data/vendor/assets/javascripts/ajax-chosen-prototype.js +2 -0
  376. data/vendor/assets/javascripts/ajax-chosen.jquery.coffee +81 -0
  377. data/vendor/assets/javascripts/ajax-chosen.proto.coffee +98 -0
  378. data/vendor/assets/javascripts/jquery_timeago/index.js +17 -0
  379. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.cz.js +18 -0
  380. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.de.js +18 -0
  381. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-GB.js +20 -0
  382. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-US.js +20 -0
  383. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.es.js +18 -0
  384. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr-CA.js +17 -0
  385. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr.js +17 -0
  386. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.it.js +16 -0
  387. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ja.js +19 -0
  388. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.js +194 -0
  389. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pl.js +31 -0
  390. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pt-BR.js +18 -0
  391. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ru.js +34 -0
  392. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.sv-SE.js +18 -0
  393. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.th.js +20 -0
  394. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.zh-CN.js +20 -0
  395. data/zeus.json +2 -1
  396. metadata +240 -245
  397. data/app/assets/images/delete.png +0 -0
  398. data/app/assets/images/iconset_attribution.png +0 -0
  399. data/app/views/accounts/create.js.rjs +0 -14
  400. data/app/views/accounts/destroy.js.rjs +0 -3
  401. data/app/views/accounts/edit.js.rjs +0 -33
  402. data/app/views/accounts/index.js.rjs +0 -8
  403. data/app/views/accounts/new.js.rjs +0 -9
  404. data/app/views/accounts/show.js.erb +0 -2
  405. data/app/views/accounts/update.js.rjs +0 -17
  406. data/app/views/admin/field_groups/confirm.js.rjs +0 -6
  407. data/app/views/admin/field_groups/create.js.rjs +0 -20
  408. data/app/views/admin/field_groups/destroy.js.rjs +0 -11
  409. data/app/views/admin/field_groups/edit.js.rjs +0 -14
  410. data/app/views/admin/field_groups/new.js.rjs +0 -9
  411. data/app/views/admin/field_groups/update.js.rjs +0 -9
  412. data/app/views/admin/fields/create.js.erb +0 -19
  413. data/app/views/admin/fields/destroy.js.erb +0 -9
  414. data/app/views/admin/fields/edit.js.erb +0 -1
  415. data/app/views/admin/fields/update.js.erb +0 -13
  416. data/app/views/admin/groups/create.js.rjs +0 -11
  417. data/app/views/admin/groups/destroy.js.rjs +0 -11
  418. data/app/views/admin/groups/edit.js.rjs +0 -21
  419. data/app/views/admin/groups/index.js.rjs +0 -2
  420. data/app/views/admin/groups/new.js.rjs +0 -9
  421. data/app/views/admin/groups/update.js.rjs +0 -10
  422. data/app/views/admin/tags/confirm.js.rjs +0 -6
  423. data/app/views/admin/tags/create.js.rjs +0 -12
  424. data/app/views/admin/tags/destroy.js.rjs +0 -11
  425. data/app/views/admin/tags/edit.js.rjs +0 -21
  426. data/app/views/admin/tags/new.js.rjs +0 -8
  427. data/app/views/admin/tags/update.js.rjs +0 -10
  428. data/app/views/admin/users/confirm.js.rjs +0 -6
  429. data/app/views/admin/users/create.js.rjs +0 -11
  430. data/app/views/admin/users/destroy.js.rjs +0 -11
  431. data/app/views/admin/users/edit.js.rjs +0 -21
  432. data/app/views/admin/users/index.js.rjs +0 -3
  433. data/app/views/admin/users/new.js.rjs +0 -8
  434. data/app/views/admin/users/reactivate.js.rjs +0 -3
  435. data/app/views/admin/users/suspend.js.rjs +0 -3
  436. data/app/views/admin/users/update.js.rjs +0 -10
  437. data/app/views/campaigns/create.js.rjs +0 -18
  438. data/app/views/campaigns/destroy.js.rjs +0 -3
  439. data/app/views/campaigns/edit.js.rjs +0 -34
  440. data/app/views/campaigns/index.js.rjs +0 -8
  441. data/app/views/campaigns/new.js.rjs +0 -9
  442. data/app/views/campaigns/show.js.erb +0 -2
  443. data/app/views/campaigns/update.js.rjs +0 -21
  444. data/app/views/comments/create.js.rjs +0 -11
  445. data/app/views/comments/destroy.js.rjs +0 -6
  446. data/app/views/comments/edit.js.rjs +0 -11
  447. data/app/views/comments/new.js.rjs +0 -14
  448. data/app/views/comments/update.js.rjs +0 -11
  449. data/app/views/contacts/create.js.rjs +0 -19
  450. data/app/views/contacts/destroy.js.rjs +0 -7
  451. data/app/views/contacts/edit.js.rjs +0 -36
  452. data/app/views/contacts/index.js.rjs +0 -8
  453. data/app/views/contacts/new.js.rjs +0 -11
  454. data/app/views/contacts/show.js.erb +0 -2
  455. data/app/views/contacts/update.js.rjs +0 -22
  456. data/app/views/emails/destroy.js.rjs +0 -6
  457. data/app/views/entities/attach.js.rjs +0 -24
  458. data/app/views/entities/contacts.js.rjs +0 -3
  459. data/app/views/entities/discard.js.rjs +0 -7
  460. data/app/views/entities/leads.js.rjs +0 -3
  461. data/app/views/entities/opportunities.js.rjs +0 -3
  462. data/app/views/entities/subscription_update.js.rjs +0 -4
  463. data/app/views/entities/versions.js.erb +0 -3
  464. data/app/views/fields/group.js.rjs +0 -7
  465. data/app/views/home/index.js.rjs +0 -7
  466. data/app/views/home/options.js.rjs +0 -8
  467. data/app/views/leads/convert.js.rjs +0 -37
  468. data/app/views/leads/create.js.rjs +0 -19
  469. data/app/views/leads/destroy.js.rjs +0 -7
  470. data/app/views/leads/edit.js.rjs +0 -36
  471. data/app/views/leads/index.js.rjs +0 -8
  472. data/app/views/leads/new.js.rjs +0 -9
  473. data/app/views/leads/promote.js.rjs +0 -27
  474. data/app/views/leads/reject.js.rjs +0 -10
  475. data/app/views/leads/show.js.erb +0 -2
  476. data/app/views/leads/update.js.rjs +0 -27
  477. data/app/views/lists/create.js.rjs +0 -9
  478. data/app/views/lists/destroy.js.rjs +0 -1
  479. data/app/views/opportunities/contacts.js.rjs +0 -3
  480. data/app/views/opportunities/create.js.rjs +0 -29
  481. data/app/views/opportunities/destroy.js.rjs +0 -11
  482. data/app/views/opportunities/edit.js.rjs +0 -36
  483. data/app/views/opportunities/index.js.rjs +0 -8
  484. data/app/views/opportunities/new.js.rjs +0 -12
  485. data/app/views/opportunities/show.js.erb +0 -2
  486. data/app/views/opportunities/update.js.rjs +0 -26
  487. data/app/views/tasks/complete.js.rjs +0 -17
  488. data/app/views/tasks/create.js.rjs +0 -41
  489. data/app/views/tasks/destroy.js.rjs +0 -7
  490. data/app/views/tasks/discard.rjs +0 -1
  491. data/app/views/tasks/edit.js.rjs +0 -23
  492. data/app/views/tasks/filter.js.rjs +0 -1
  493. data/app/views/tasks/new.js.rjs +0 -9
  494. data/app/views/tasks/update.js.rjs +0 -21
  495. data/app/views/users/avatar.js.rjs +0 -10
  496. data/app/views/users/change_password.js.rjs +0 -15
  497. data/app/views/users/edit.js.rjs +0 -10
  498. data/app/views/users/password.js.rjs +0 -11
  499. data/app/views/users/update.js.rjs +0 -10
  500. data/app/views/users/upload_avatar.js.rjs +0 -8
  501. data/lib/fat_free_crm/secret_token_generator.rb +0 -65
  502. data/spec/lib/secret_token_generator_spec.rb +0 -79
  503. data/spec/models/users/abilities/user_ability_spec.rb +0 -58
  504. data/spec/support/rjs_support.rb +0 -14
  505. data/vendor/assets/images/brief.png +0 -0
  506. data/vendor/assets/images/full.png +0 -0
  507. data/vendor/assets/images/long.png +0 -0
  508. data/vendor/assets/images/tab_icons/accounts.png +0 -0
  509. data/vendor/assets/images/tab_icons/accounts_active.png +0 -0
  510. data/vendor/assets/images/tab_icons/campaigns.png +0 -0
  511. data/vendor/assets/images/tab_icons/campaigns_active.png +0 -0
  512. data/vendor/assets/images/tab_icons/contacts.png +0 -0
  513. data/vendor/assets/images/tab_icons/contacts_active.png +0 -0
  514. data/vendor/assets/images/tab_icons/dashboard.png +0 -0
  515. data/vendor/assets/images/tab_icons/dashboard_active.png +0 -0
  516. data/vendor/assets/images/tab_icons/leads.png +0 -0
  517. data/vendor/assets/images/tab_icons/leads_active.png +0 -0
  518. data/vendor/assets/images/tab_icons/opportunities.png +0 -0
  519. data/vendor/assets/images/tab_icons/opportunities_active.png +0 -0
  520. data/vendor/assets/images/tab_icons/tasks.png +0 -0
  521. data/vendor/assets/images/tab_icons/tasks_active.png +0 -0
@@ -9,9 +9,7 @@ module Admin::ApplicationHelper
9
9
  link_to(t(:yes_button),
10
10
  url_for([:admin, model]),
11
11
  :method => :delete,
12
- :remote => true,
13
- :onclick => visual_effect(:highlight, dom_id(model), :startcolor => "#ffe4e1")
12
+ :remote => true
14
13
  )
15
14
  end
16
15
  end
17
-
@@ -4,6 +4,7 @@
4
4
  # See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
5
  #------------------------------------------------------------------------------
6
6
  module Admin::FieldGroupsHelper
7
+
7
8
  def field_group_subtitle(field_group)
8
9
  asset = field_group.klass_name.downcase
9
10
  html = t(field_group.name, :default => field_group.label)
@@ -16,7 +17,7 @@ module Admin::FieldGroupsHelper
16
17
  end
17
18
  html.html_safe
18
19
  end
19
-
20
+
20
21
  def link_to_confirm(field_group)
21
22
  link_to(t(:delete) + "?", confirm_admin_field_group_path(field_group), :method => :get, :remote => true)
22
23
  end
@@ -109,7 +109,7 @@ module ApplicationHelper
109
109
  link_to(t(:edit),
110
110
  options[:url] || polymorphic_url(record, :action => :edit),
111
111
  :remote => true,
112
- :onclick => "this.href = this.href.split('?')[0] + '?previous='+crm.find_form('edit_#{name}');"
112
+ :onclick => "this.href = this.href.split('?')[0] + '?previous='+crm.find_form('edit_#{name}');".html_safe
113
113
  )
114
114
  end
115
115
 
@@ -122,7 +122,6 @@ module ApplicationHelper
122
122
  options[:url] || url_for(record),
123
123
  :method => :delete,
124
124
  :remote => true,
125
- :onclick => visual_effect(:highlight, dom_id(object), :startcolor => "#ffe4e1"),
126
125
  :confirm => confirm
127
126
  )
128
127
  end
@@ -135,8 +134,7 @@ module ApplicationHelper
135
134
  link_to(t(:discard),
136
135
  url_for(:controller => parent, :action => :discard, :id => parent_id, :attachment => object.class.name, :attachment_id => object.id),
137
136
  :method => :post,
138
- :remote => true,
139
- :onclick => visual_effect(:highlight, dom_id(object), :startcolor => "#ffe4e1")
137
+ :remote => true
140
138
  )
141
139
  end
142
140
 
@@ -197,8 +195,8 @@ module ApplicationHelper
197
195
  def visible; { :style => "visibility:visible;" }; end
198
196
 
199
197
  #----------------------------------------------------------------------------
200
- def one_submit_only(form)
201
- { :onsubmit => "$$('#'+this.id+' input[type=\"submit\"]')[0].disabled = true" }
198
+ def one_submit_only(form='')
199
+ { :onsubmit => "jQuery('#'+this.id+' input[type=\\'submit\\']').disable()".html_safe }
202
200
  end
203
201
 
204
202
  #----------------------------------------------------------------------------
@@ -215,11 +213,10 @@ module ApplicationHelper
215
213
  def confirm_delete(model, params = {})
216
214
  question = %(<span class="warn">#{t(:confirm_delete, model.class.to_s.downcase)}</span>).html_safe
217
215
  yes = link_to(t(:yes_button), params[:url] || model, :method => :delete)
218
- no = link_to_function(t(:no_button), "$('menu').update($('confirm').innerHTML)")
219
- update_page do |page|
220
- page << "$('confirm').update($('menu').innerHTML)"
221
- page[:menu].replace_html "#{question} #{yes} : #{no}"
222
- end
216
+ no = link_to_function(t(:no_button), "jQuery('#menu').html(jQuery('#confirm').html());")
217
+ text = "jQuery('#confirm').html( jQuery('#menu').html() );\n"
218
+ text << "jQuery('#menu').html('#{question} #{yes} : #{no}');"
219
+ text.html_safe
223
220
  end
224
221
 
225
222
  #----------------------------------------------------------------------------
@@ -236,10 +233,10 @@ module ApplicationHelper
236
233
  # Refresh sidebar using the action view within an arbitrary controller.
237
234
  #----------------------------------------------------------------------------
238
235
  def refresh_sidebar_for(view, action = nil, shake = nil)
239
- update_page do |page|
240
- page[:sidebar].replace_html :partial => "layouts/sidebar", :locals => { :view => view, :action => action }
241
- page[shake].visual_effect(:shake, :duration => 0.2, :distance => 3) if shake
242
- end
236
+ text = ""
237
+ text << "jQuery('#sidebar').html('#{ j render(:partial => "layouts/sidebar", :locals => { :view => view, :action => action }) }');"
238
+ text << "jQuery('##{j shake.to_s}').effect('shake', { duration:200, distance: 3 });" if shake
239
+ text.html_safe
243
240
  end
244
241
 
245
242
  # Display web presence mini-icons for Contact or Lead.
@@ -466,11 +463,35 @@ module ApplicationHelper
466
463
  content_tag(:li) do
467
464
  url = (action == "index") ? send("redraw_#{controller}_path") : send("#{controller.singularize}_path")
468
465
  link_to('#', :title => t(view.name, :default => view.title), :"data-view" => view.name, :"data-url" => url, :"data-context" => action, :class => classes) do
469
- image_tag(view.icon || 'brief.png')
466
+ icon = view.icon || 'fa-bars'
467
+ content_tag(:i, nil, class: "fa #{icon}")
470
468
  end
471
469
  end
472
470
  end.join('').html_safe
473
471
  end
474
472
  end
475
473
 
474
+ #----------------------------------------------------------------------------
475
+ # Generate the html for jQuery.timeago function
476
+ # <span class="timeago" datetime="2008-07-17T09:24:17Z">July 17, 2008</span>
477
+ def timeago(time, options = {})
478
+ options[:class] ||= "timeago"
479
+ content_tag(:span, time.to_s, options.merge( title: time.getutc.iso8601)) if time
480
+ end
481
+
482
+ #----------------------------------------------------------------------------
483
+ # Translate List name to FontAwesome icon text
484
+ def get_icon(name)
485
+ case name
486
+ when "tasks" then "fa-check-square-o"
487
+ when "campaigns" then "fa-bar-chart-o"
488
+ when "leads" then "fa-tasks"
489
+ when "accounts" then "fa-users"
490
+ when "contacts" then "fa-user"
491
+ when "opportunities" then "fa-money"
492
+ when "team" then "fa-globe"
493
+ end
494
+ end
495
+
496
+
476
497
  end
@@ -39,7 +39,7 @@ module HomeHelper
39
39
  # Activity title for RSS/ATOM feeds.
40
40
  #----------------------------------------------------------------------------
41
41
  def activity_title(activity)
42
- user = activity.user.full_name
42
+ user = activity.user.try(:full_name) || ''
43
43
  action = t('action_' + activity.event)
44
44
  type = t('subject_' + activity.item_type.downcase)
45
45
  subject = if item = activity.item
@@ -64,4 +64,3 @@ module HomeHelper
64
64
  end
65
65
  end
66
66
  end
67
-
@@ -29,13 +29,12 @@ module LeadsHelper
29
29
 
30
30
  #----------------------------------------------------------------------------
31
31
  def confirm_reject(lead)
32
- question = %(<span class="warn">#{t(:reject_lead_confirm)}</span>).html_safe
32
+ question = %(<span class="warn">#{t(:reject_lead_confirm)}</span>)
33
33
  yes = link_to(t(:yes_button), reject_lead_path(lead), :method => :put)
34
- no = link_to_function(t(:no_button), "$('menu').update($('confirm').innerHTML)")
35
- update_page do |page|
36
- page << "$('confirm').update($('menu').innerHTML)"
37
- page[:menu].replace_html "#{question} #{yes} : #{no}"
38
- end
34
+ no = link_to_function(t(:no_button), "jQuery('#menu').html(jQuery('#confirm').html());")
35
+ text = "jQuery('#confirm').html( jQuery('#menu').html() );\n"
36
+ text << "jQuery('#menu').html('#{question} #{yes} : #{no}');"
37
+ text.html_safe
39
38
  end
40
39
 
41
40
  # Sidebar checkbox control for filtering leads by status.
@@ -17,7 +17,7 @@ module TasksHelper
17
17
  :loading => "$('loading').show()",
18
18
  :complete => "$('loading').hide()"
19
19
  )
20
- check_box_tag("filters[]", filter, checked, :onclick => onclick)
20
+ check_box_tag("filters[]", filter, checked, :onclick => onclick, :id => "filters_#{filter.to_s.underscore}")
21
21
  end
22
22
 
23
23
  #----------------------------------------------------------------------------
@@ -33,21 +33,14 @@ module TasksHelper
33
33
 
34
34
  #----------------------------------------------------------------------------
35
35
  def link_to_task_edit(task, bucket)
36
- link_to(t(:edit), edit_task_path(task),
37
- :method => :get,
38
- :with => "{ bucket: '#{bucket}', view: '#{@view}', previous: crm.find_form('edit_task') }",
39
- :remote => true
40
- )
36
+ link_to(t(:edit), edit_task_path(task, :bucket => bucket, :view => @view, :previous => "crm.find_form('edit_task')"),
37
+ :method => :get, :remote => true)
41
38
  end
42
39
 
43
40
  #----------------------------------------------------------------------------
44
41
  def link_to_task_delete(task, bucket)
45
- link_to(t(:delete) + "!", task_path(task),
46
- :method => :delete,
47
- :with => "{ bucket: '#{bucket}', view: '#{@view}' }",
48
- :before => visual_effect(:highlight, dom_id(task), :startcolor => "#ffe4e1"),
49
- :remote => true
50
- )
42
+ link_to(t(:delete) + "!", task_path(task, :bucket => bucket, :view => @view),
43
+ :method => :delete, :remote => true)
51
44
  end
52
45
 
53
46
  #----------------------------------------------------------------------------
@@ -85,64 +78,57 @@ module TasksHelper
85
78
  end
86
79
 
87
80
  #----------------------------------------------------------------------------
88
- def hide_task_and_possibly_bucket(id, bucket)
89
- update_page do |page|
90
- page[id].replace ""
91
-
92
- if Task.bucket_empty?(bucket, current_user, @view)
93
- page["list_#{bucket}"].visual_effect :fade, :duration => 0.5
94
- end
95
- end
81
+ def hide_task_and_possibly_bucket(task, bucket)
82
+ text = "jQuery('##{dom_id(task)}').remove();\n"
83
+ text << "jQuery('#list_#{h bucket.to_s}').fadeOut({ duration:500 });\n" if Task.bucket_empty?(bucket, current_user, @view)
84
+ text.html_safe
96
85
  end
97
86
 
98
87
  #----------------------------------------------------------------------------
99
88
  def replace_content(task, bucket = nil)
100
89
  partial = (task.assigned_to && task.assigned_to != current_user.id) ? "assigned" : "pending"
101
- update_page do |page|
102
- page[dom_id(task)].replace_html :partial => "tasks/#{partial}", :collection => [ task ], :locals => { :bucket => bucket }
103
- end
90
+ html = render(:partial => "tasks/#{partial}", :collection => [ task ], :locals => { :bucket => bucket })
91
+ text = "jQuery('##{dom_id(task)}').html('#{ j html }');\n".html_safe
104
92
  end
105
93
 
106
94
  #----------------------------------------------------------------------------
107
95
  def insert_content(task, bucket, view)
108
- update_page do |page|
109
- page["list_#{bucket}"].show
110
- page.insert_html :top, bucket, :partial => view, :collection => [ task ], :locals => { :bucket => bucket }
111
- page[dom_id(task)].visual_effect :highlight, :duration => 1.5
112
- end
96
+ text = "jQuery('#list_#{bucket}').show();\n".html_safe
97
+ html = render(:partial => view, :collection => [ task ], :locals => { :bucket => bucket })
98
+ text << "jQuery('##{h bucket.to_s}').prepend('#{ j html }');\n".html_safe
99
+ text << "jQuery('##{dom_id(task)}').effect('highlight', { duration:1500 });\n".html_safe
100
+ text
113
101
  end
114
102
 
115
103
  #----------------------------------------------------------------------------
116
104
  def tasks_flash(message)
117
- update_page do |page|
118
- page[:flash].replace_html message
119
- page.call "crm.flash", :notice, true
120
- end
105
+ text = "jQuery('#flash').html('#{ message }');\n"
106
+ text << "crm.flash('notice', true)\n"
107
+ text.html_safe
121
108
  end
122
109
 
123
110
  #----------------------------------------------------------------------------
124
- def reassign(id)
125
- update_page do |page|
126
- if @view == "pending" && @task.assigned_to != current_user.id
127
- page << hide_task_and_possibly_bucket(id, @task_before_update.bucket)
128
- page << tasks_flash("#{t(:task_assigned, @task.assignee.full_name)} (" << link_to(t(:view_assigned_tasks), url_for(:controller => :tasks, :view => :assigned)) << ").")
129
- elsif @view == "assigned" && @task.assigned_to.blank?
130
- page << hide_task_and_possibly_bucket(id, @task_before_update.bucket)
131
- page << tasks_flash("#{t(:task_pending)} (" << link_to(t(:view_pending_tasks), tasks_url) << ").")
132
- else
133
- page << replace_content(@task, @task.bucket)
134
- end
135
- page << refresh_sidebar(:index, :filters)
111
+ def reassign(task)
112
+ text = "".html_safe
113
+ if @view == "pending" && @task.assigned_to.present? && @task.assigned_to != current_user.id
114
+ text << hide_task_and_possibly_bucket(task, @task_before_update.bucket)
115
+ text << tasks_flash( t(:task_assigned, (h @task.assignee.try(:full_name))) + " (#{link_to(t(:view_assigned_tasks), url_for(:controller => :tasks, :view => :assigned))})" )
116
+ elsif @view == "assigned" && @task.assigned_to.blank?
117
+ text << hide_task_and_possibly_bucket(task, @task_before_update.bucket)
118
+ text << tasks_flash( t(:task_pending) + " (#{link_to(t(:view_pending_tasks), tasks_url)}.")
119
+ else
120
+ text << replace_content(@task, @task.bucket)
136
121
  end
122
+ text << refresh_sidebar(:index, :filters)
123
+ text
137
124
  end
138
125
 
139
126
  #----------------------------------------------------------------------------
140
- def reschedule(id)
141
- update_page do |page|
142
- page << hide_task_and_possibly_bucket(id, @task_before_update.bucket)
143
- page << insert_content(@task, @task.bucket, @view)
144
- page << refresh_sidebar(:index, :filters)
145
- end
127
+ def reschedule(task)
128
+ text = hide_task_and_possibly_bucket(task, @task_before_update.bucket)
129
+ text << insert_content(task, task.bucket, @view)
130
+ text << refresh_sidebar(:index, :filters)
131
+ text
146
132
  end
147
133
 
148
134
  end
@@ -43,20 +43,20 @@ class Account < ActiveRecord::Base
43
43
  accepts_nested_attributes_for :billing_address, :allow_destroy => true, :reject_if => proc {|attributes| Address.reject_address(attributes)}
44
44
  accepts_nested_attributes_for :shipping_address, :allow_destroy => true, :reject_if => proc {|attributes| Address.reject_address(attributes)}
45
45
 
46
- scope :state, lambda { |filters|
46
+ scope :state, ->(filters) {
47
47
  where('category IN (?)' + (filters.delete('other') ? ' OR category IS NULL' : ''), filters)
48
48
  }
49
- scope :created_by, lambda { |user| where(:user_id => user.id) }
50
- scope :assigned_to, lambda { |user| where(:assigned_to => user.id) }
49
+ scope :created_by, ->(user) { where(:user_id => user.id) }
50
+ scope :assigned_to, ->(user) { where(:assigned_to => user.id) }
51
51
 
52
- scope :text_search, lambda { |query| search('name_or_email_cont' => query).result }
52
+ scope :text_search, ->(query) { search('name_or_email_cont' => query).result }
53
53
 
54
- scope :visible_on_dashboard, lambda { |user|
54
+ scope :visible_on_dashboard, ->(user) {
55
55
  # Show accounts which either belong to the user and are unassigned, or are assigned to the user
56
56
  where('(user_id = :user_id AND assigned_to IS NULL) OR assigned_to = :user_id', :user_id => user.id)
57
57
  }
58
58
 
59
- scope :by_name, order(:name)
59
+ scope :by_name, -> { order(:name) }
60
60
 
61
61
  uses_user_permissions
62
62
  acts_as_commentable
@@ -71,8 +71,11 @@ class Account < ActiveRecord::Base
71
71
  ransack_can_autocomplete
72
72
 
73
73
  validates_presence_of :name, :message => :missing_account_name
74
- validates_uniqueness_of :name, :scope => :deleted_at if Setting.require_unique_account_names
74
+ validates_uniqueness_of :name, :scope => :deleted_at, :if => -> { Setting.require_unique_account_names }
75
+ validates :rating, :inclusion => { in: 0..5 }, allow_blank: true
76
+ validates :category, :inclusion => { in: Proc.new{ Setting.unroll(:account_category).map{|s| s.last.to_s} } }, allow_blank: true
75
77
  validate :users_for_shared_access
78
+
76
79
  before_save :nullify_blank_category
77
80
 
78
81
  # Default values provided through class methods.
@@ -39,13 +39,13 @@ class Campaign < ActiveRecord::Base
39
39
 
40
40
  serialize :subscribed_users, Set
41
41
 
42
- scope :state, lambda { |filters|
42
+ scope :state, ->(filters) {
43
43
  where('status IN (?)' + (filters.delete('other') ? ' OR status IS NULL' : ''), filters)
44
44
  }
45
- scope :created_by, lambda { |user| where('user_id = ?' , user.id) }
46
- scope :assigned_to, lambda { |user| where('assigned_to = ?', user.id) }
45
+ scope :created_by, ->(user) { where('user_id = ?' , user.id) }
46
+ scope :assigned_to, ->(user) { where('assigned_to = ?', user.id) }
47
47
 
48
- scope :text_search, lambda { |query| search('name_cont' => query).result }
48
+ scope :text_search, ->(query) { search('name_cont' => query).result }
49
49
 
50
50
  uses_user_permissions
51
51
  acts_as_commentable
@@ -40,6 +40,7 @@ class Contact < ActiveRecord::Base
40
40
  belongs_to :user
41
41
  belongs_to :lead
42
42
  belongs_to :assignee, :class_name => "User", :foreign_key => :assigned_to
43
+ belongs_to :reporting_user, :class_name => "User", :foreign_key => :reports_to
43
44
  has_one :account_contact, :dependent => :destroy
44
45
  has_one :account, :through => :account_contact
45
46
  has_many :contact_opportunities, :dependent => :destroy
@@ -49,6 +50,8 @@ class Contact < ActiveRecord::Base
49
50
  has_many :addresses, :dependent => :destroy, :as => :addressable, :class_name => "Address" # advanced search uses this
50
51
  has_many :emails, :as => :mediator
51
52
 
53
+ delegate :campaign, :to => :lead, :allow_nil => true
54
+
52
55
  has_ransackable_associations %w(account opportunities tags activities emails addresses comments tasks)
53
56
  ransack_can_autocomplete
54
57
 
@@ -56,10 +59,10 @@ class Contact < ActiveRecord::Base
56
59
 
57
60
  accepts_nested_attributes_for :business_address, :allow_destroy => true, :reject_if => proc {|attributes| Address.reject_address(attributes)}
58
61
 
59
- scope :created_by, lambda { |user| { :conditions => [ "user_id = ?", user.id ] } }
60
- scope :assigned_to, lambda { |user| { :conditions => ["assigned_to = ?", user.id ] } }
62
+ scope :created_by, ->(user) { where("user_id = ?", user.id) }
63
+ scope :assigned_to, ->(user) { where("assigned_to = ?", user.id) }
61
64
 
62
- scope :text_search, lambda { |query|
65
+ scope :text_search, ->(query) {
63
66
  t = Contact.arel_table
64
67
  # We can't always be sure that names are entered in the right order, so we must
65
68
  # split the query into all possible first/last name permutations.
@@ -89,8 +92,8 @@ class Contact < ActiveRecord::Base
89
92
  exportable
90
93
  sortable :by => [ "first_name ASC", "last_name ASC", "created_at DESC", "updated_at DESC" ], :default => "created_at DESC"
91
94
 
92
- validates_presence_of :first_name, :message => :missing_first_name if Setting.require_first_names
93
- validates_presence_of :last_name, :message => :missing_last_name if Setting.require_last_names
95
+ validates_presence_of :first_name, :message => :missing_first_name, :if => -> { Setting.require_first_names }
96
+ validates_presence_of :last_name, :message => :missing_last_name, :if => -> { Setting.require_last_names }
94
97
  validate :users_for_shared_access
95
98
 
96
99
  # Default values provided through class methods.
@@ -50,15 +50,15 @@ class Lead < ActiveRecord::Base
50
50
 
51
51
  accepts_nested_attributes_for :business_address, :allow_destroy => true
52
52
 
53
- scope :state, lambda { |filters|
53
+ scope :state, ->(filters) {
54
54
  where([ 'status IN (?)' + (filters.delete('other') ? ' OR status IS NULL' : ''), filters ])
55
55
  }
56
- scope :converted, where(:status => 'converted')
57
- scope :for_campaign, lambda { |id| where('campaign_id = ?', id) }
58
- scope :created_by, lambda { |user| where('user_id = ?' , user.id) }
59
- scope :assigned_to, lambda { |user| where('assigned_to = ?' , user.id) }
56
+ scope :converted, -> { where(:status => 'converted') }
57
+ scope :for_campaign, ->(id) { where('campaign_id = ?', id) }
58
+ scope :created_by, ->(user) { where('user_id = ?' , user.id) }
59
+ scope :assigned_to, ->(user) { where('assigned_to = ?' , user.id) }
60
60
 
61
- scope :text_search, lambda { |query| search('first_name_or_last_name_or_company_or_email_cont' => query).result }
61
+ scope :text_search, ->(query) { search('first_name_or_last_name_or_company_or_email_cont' => query).result }
62
62
 
63
63
  uses_user_permissions
64
64
  acts_as_commentable
@@ -72,8 +72,8 @@ class Lead < ActiveRecord::Base
72
72
  has_ransackable_associations %w(contact campaign tasks tags activities emails addresses comments)
73
73
  ransack_can_autocomplete
74
74
 
75
- validates_presence_of :first_name, :message => :missing_first_name if Setting.require_first_names
76
- validates_presence_of :last_name, :message => :missing_last_name if Setting.require_last_names
75
+ validates_presence_of :first_name, :message => :missing_first_name, :if => -> { Setting.require_first_names }
76
+ validates_presence_of :last_name, :message => :missing_last_name, :if => -> { Setting.require_last_names }
77
77
  validate :users_for_shared_access
78
78
 
79
79
  after_create :increment_leads_count
@@ -38,19 +38,19 @@ class Opportunity < ActiveRecord::Base
38
38
 
39
39
  serialize :subscribed_users, Set
40
40
 
41
- scope :state, lambda { |filters|
41
+ scope :state, ->(filters) {
42
42
  where('stage IN (?)' + (filters.delete('other') ? ' OR stage IS NULL' : ''), filters)
43
43
  }
44
- scope :created_by, lambda { |user| where('user_id = ?', user.id) }
45
- scope :assigned_to, lambda { |user| where('assigned_to = ?', user.id) }
46
- scope :won, where("opportunities.stage = 'won'")
47
- scope :lost, where("opportunities.stage = 'lost'")
48
- scope :not_lost, where("opportunities.stage <> 'lost'")
49
- scope :pipeline, where("opportunities.stage IS NULL OR (opportunities.stage != 'won' AND opportunities.stage != 'lost')")
50
- scope :unassigned, where("opportunities.assigned_to IS NULL")
44
+ scope :created_by, ->(user) { where('user_id = ?', user.id) }
45
+ scope :assigned_to, ->(user) { where('assigned_to = ?', user.id) }
46
+ scope :won, -> { where("opportunities.stage = 'won'") }
47
+ scope :lost, -> { where("opportunities.stage = 'lost'") }
48
+ scope :not_lost, -> { where("opportunities.stage <> 'lost'") }
49
+ scope :pipeline, -> { where("opportunities.stage IS NULL OR (opportunities.stage != 'won' AND opportunities.stage != 'lost')") }
50
+ scope :unassigned, -> { where("opportunities.assigned_to IS NULL") }
51
51
 
52
52
  # Search by name OR id
53
- scope :text_search, lambda { |query|
53
+ scope :text_search, ->(query) {
54
54
  # postgresql does not like to compare string to integer field
55
55
  if query =~ /^\d+$/
56
56
  query = query.gsub(/[^\w\s\-\.'\p{L}]/u, '').strip
@@ -60,13 +60,13 @@ class Opportunity < ActiveRecord::Base
60
60
  end
61
61
  }
62
62
 
63
- scope :visible_on_dashboard, lambda { |user|
63
+ scope :visible_on_dashboard, ->(user) {
64
64
  # Show opportunities which either belong to the user and are unassigned, or are assigned to the user and haven't been closed (won/lost)
65
65
  where('(user_id = :user_id AND assigned_to IS NULL) OR assigned_to = :user_id', :user_id => user.id).where("opportunities.stage != 'won'").where("opportunities.stage != 'lost'")
66
66
  }
67
67
 
68
- scope :by_closes_on, order(:closes_on)
69
- scope :by_amount, order('opportunities.amount DESC')
68
+ scope :by_closes_on, -> { order(:closes_on) }
69
+ scope :by_amount, -> { order('opportunities.amount DESC') }
70
70
 
71
71
  uses_user_permissions
72
72
  acts_as_commentable
@@ -80,17 +80,12 @@ class Opportunity < ActiveRecord::Base
80
80
  has_ransackable_associations %w(account contacts tags campaign activities emails comments)
81
81
  ransack_can_autocomplete
82
82
 
83
- validates :stage, :inclusion => { :in => Setting.unroll(:opportunity_stage).map{|s| s.last.to_s } }
83
+ validates :stage, :inclusion => { :in => Proc.new { Setting.unroll(:opportunity_stage).map{|s| s.last.to_s } } }
84
84
 
85
85
  validates_presence_of :name, :message => :missing_opportunity_name
86
86
  validates_numericality_of [ :probability, :amount, :discount ], :allow_nil => true
87
87
  validate :users_for_shared_access
88
88
 
89
- # Validate presence of account_opportunity unless the opportunity is deleted [with has_paper_trail],
90
- # in which case the account_opportunity will still exist but will be in a deleted state.
91
- # validates :account_opportunity, :presence => true, :unless => Proc.new { |o| o.destroyed? }
92
- # TODO: Mike, what do you think about the above validation?
93
-
94
89
  after_create :increment_opportunities_count
95
90
  after_destroy :decrement_opportunities_count
96
91