view_helpers.coffee 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. # Top-level shortcuts for various view template helper methods,
  2. # to be included in view templates via
  3. #
  4. # JST["path/to/template"](_.extend(App.ViewHelpers))
  5. App.ViewHelpers =
  6. # define print name helper
  7. P: (object, attributeName, attributes, table = false) ->
  8. App.viewPrint(object, attributeName, attributes, table)
  9. # define date format helper
  10. date: (time) ->
  11. return '' if !time
  12. timeObject = new Date(time)
  13. d = App.Utils.formatTime(timeObject.getDate(), 2)
  14. m = App.Utils.formatTime(timeObject.getMonth() + 1, 2)
  15. y = timeObject.getFullYear()
  16. "#{y}-#{m}-#{d}"
  17. # define datetime format helper
  18. datetime: (time) ->
  19. return '' if !time
  20. timeObject = new Date(time)
  21. d = App.Utils.formatTime(timeObject.getDate(), 2)
  22. m = App.Utils.formatTime(timeObject.getMonth() + 1, 2)
  23. y = timeObject.getFullYear()
  24. S = App.Utils.formatTime(timeObject.getSeconds(), 2)
  25. M = App.Utils.formatTime(timeObject.getMinutes(), 2)
  26. H = App.Utils.formatTime(timeObject.getHours(), 2)
  27. "#{y}-#{m}-#{d} #{H}:#{M}:#{S}"
  28. # define decimal format helper
  29. decimal: (data, positions = 2) ->
  30. App.Utils.decimal(data, positions)
  31. # define time_duration / mm:ss / hh:mm:ss format helper
  32. time_duration: (time) ->
  33. return '' if !time
  34. return '' if isNaN(parseInt(time))
  35. # Hours, minutes and seconds
  36. hrs = ~~parseInt((time / 3600))
  37. mins = ~~parseInt(((time % 3600) / 60))
  38. secs = parseInt(time % 60)
  39. # Output like "1:01" or "4:03:59" or "123:03:59"
  40. mins = "0#{mins}" if mins < 10
  41. secs = "0#{secs}" if secs < 10
  42. if hrs > 0
  43. return "#{hrs}:#{mins}:#{secs}"
  44. "#{mins}:#{secs}"
  45. # define time_duration / hh:mm
  46. time_duration_hh_mm: (time_in_minutes) ->
  47. return '' if !time_in_minutes
  48. return '' if isNaN(parseInt(time_in_minutes))
  49. # Hours, minutes and seconds
  50. hrs = ~~parseInt((time_in_minutes / 60))
  51. mins = ~~parseInt((time_in_minutes % 60))
  52. hrs = "0#{hrs}" if hrs < 10
  53. mins = "0#{mins}" if mins < 10
  54. "#{hrs}:#{mins}"
  55. # define mask helper
  56. # mask an value like 'a***********yz'
  57. M: (item, start = 1, end = 2) ->
  58. return '' if !item
  59. string = ''
  60. end = item.length - end - 1
  61. for n in [0..item.length-1]
  62. if start <= n && end >= n
  63. string += '*'
  64. else
  65. string += item[n]
  66. string
  67. # define translation helper
  68. T: (item, args...) ->
  69. App.i18n.translateContent(item, args...)
  70. # define translation inline helper
  71. Ti: (item, args...) ->
  72. App.i18n.translateInline(item, args...)
  73. # define translation for date helper
  74. Tdate: (item, args...) ->
  75. App.i18n.translateDate(item, args...)
  76. # define translation for timestamp helper
  77. Ttimestamp: (item, args...) ->
  78. App.i18n.translateTimestamp(item, args...)
  79. # define linkify helper
  80. L: (item) ->
  81. if item && typeof item is 'string'
  82. return App.Utils.linkify(item)
  83. item
  84. # define config helper
  85. C: (key) ->
  86. App.Config.get(key)
  87. # define session helper
  88. S: (key) ->
  89. App.Session.get(key)
  90. # define view helper for rendering partial views
  91. V: (name, params) ->
  92. App.view(name)(params)
  93. # define address line helper
  94. AddressLine: (line) ->
  95. return '' if !line
  96. items = emailAddresses.parseAddressList(line)
  97. # line was not parsable
  98. return App.Utils.htmlEscape(line) if !items
  99. # set markup
  100. result = ''
  101. for item in items
  102. if result
  103. result = result + ', '
  104. if item.name
  105. item.name = item.name
  106. .replace(',', '')
  107. .replace(';', '')
  108. .replace('"', '')
  109. .replace('\'', '')
  110. if item.name.match(/\@|,|;|\^|\+|#|§|\$|%|&|\/|\(|\)|=|\?|\*/)
  111. item.name = "\"#{item.name}\""
  112. result = "#{result}#{App.Utils.htmlEscape(item.name)} "
  113. if item.address
  114. result = result + " <span class=\"text-muted\">&lt;#{App.Utils.htmlEscape(item.address)}&gt</span>"
  115. result
  116. # define file size helper
  117. humanFileSize: (size) ->
  118. App.Utils.humanFileSize(size)
  119. # define pretty/human time helper
  120. humanTime: (time, escalation = false, cssClass = '', setTitle = true) ->
  121. timestamp = App.i18n.translateTimestamp(time)
  122. if escalation
  123. cssClass += ' escalation'
  124. humanTime = App.PrettyDate.humanTime(time, escalation)
  125. title = " title=\"#{timestamp}\""
  126. if !setTitle
  127. title = ''
  128. cssClass += ' noTitle'
  129. "<time class=\"humanTimeFromNow #{cssClass}\" datetime=\"#{time}\"#{title}>#{humanTime}</time>"
  130. # Why not just use `Icon: App.Utils.icon`?
  131. # Because App.Utils isn't loaded until after this file.
  132. Icon: (name, className = '') ->
  133. App.Utils.icon(name, className)
  134. fontIcon: (name, font, className = '') ->
  135. App.Utils.fontIcon(name, font, className)
  136. # define richtext helper
  137. RichText: (string) ->
  138. return string if !string
  139. if string.match(/@T\('/)
  140. string = string.replace(/@T\('(.+?)'\)/g, (match, capture) ->
  141. App.i18n.translateContent(capture)
  142. )
  143. return marked(string)
  144. App.i18n.translateContent(string)
  145. ContentOrMimeType: (attachment) ->
  146. types = ['Content-Type', 'content_type', 'Mime-Type', 'mime_type']
  147. _.values(_.pick(attachment?.preferences, types))[0]
  148. ContentTypeIcon: (contentType) ->
  149. contentType = App.Utils.contentTypeCleanup(contentType)
  150. icons =
  151. # image
  152. 'image/jpeg': 'file-image'
  153. 'image/jpg': 'file-image'
  154. 'image/png': 'file-image'
  155. 'image/svg': 'file-image'
  156. 'image/gif': 'file-image'
  157. # documents
  158. 'application/pdf': 'file-pdf'
  159. 'application/msword': 'file-word' # .doc, .dot
  160. 'application/vnd.ms-word': 'file-word'
  161. 'application/vnd.oasis.opendocument.text': 'file-word'
  162. 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'file-word' # .docx
  163. 'application/vnd.openxmlformats-officedocument.wordprocessingml.template': 'file-word' # .dotx
  164. 'application/vnd.ms-excel': 'file-excel' # .xls
  165. 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'file-excel' # .xlsx
  166. 'application/vnd.oasis.opendocument.spreadsheet': 'file-excel'
  167. 'application/vnd.ms-powerpoint': 'file-powerpoint' # .ppt
  168. 'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'file-powerpoint' # .pptx
  169. 'application/vnd.oasis.opendocument.presentation': 'file-powerpoint'
  170. 'text/plain': 'file-text'
  171. 'text/html': 'file-code'
  172. 'application/json': 'file-code'
  173. 'message/rfc822': 'file-email'
  174. # code
  175. 'application/json': 'file-code'
  176. # text
  177. 'text/plain': 'file-text'
  178. 'text/rtf': 'file-text'
  179. # archives
  180. 'application/gzip': 'file-archive'
  181. 'application/zip': 'file-archive'
  182. return icons[contentType]
  183. canDownload: (contentType) ->
  184. contentType = App.Utils.contentTypeCleanup(contentType)
  185. return false if contentType is 'application/pdf'
  186. contentType != 'text/html'
  187. canPreview: (contentType) ->
  188. return false if _.isEmpty(contentType)
  189. return true if contentType.match(/image\/(png|jpg|jpeg|gif)/i)
  190. false
  191. unique_avatar: (seed, text, size = 40) ->
  192. baseSize = 40
  193. width = 300 * size/baseSize
  194. height = 226 * size/baseSize
  195. rng = new Math.seedrandom(seed)
  196. x = rng() * (width - size)
  197. y = rng() * (height - size)
  198. return App.view('avatar_unique')
  199. x: x
  200. y: y
  201. initials: text
  202. # icon with modifier based on visibility state
  203. # params: className, iconset, addStateClass
  204. iconWithModifier: (item, params) ->
  205. if !params.className
  206. params.className = ''
  207. if params.addStateClass
  208. params.className += " state-#{item.state}"
  209. App.view('knowledge_base/_icon_with_modifier')(
  210. item: item
  211. className: params.className
  212. iconset: params.iconset
  213. )
  214. replacePlaceholder: (template, items, encodeLink = false) ->
  215. App.Utils.replaceTags(template, items, encodeLink)
  216. # prints value depending on direction of active locale
  217. dir: (ltr, rtl) ->
  218. if App.i18n.dir() == 'ltr'
  219. ltr
  220. else
  221. rtl