index.coffee 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
  2. #= require_self
  3. #= require_tree ./lib/app_init
  4. #= require ./config.coffee
  5. #= require_tree ./models
  6. #= require_tree ./controllers
  7. #= require_tree ./views
  8. #= require_tree ./lib/app_post
  9. class App extends Spine.Controller
  10. helper =
  11. # define print name helper
  12. P: (object, attributeName, attributes, table = false) ->
  13. App.viewPrint(object, attributeName, attributes, table)
  14. # define date format helper
  15. date: (time) ->
  16. return '' if !time
  17. timeObject = new Date(time)
  18. d = App.Utils.formatTime(timeObject.getDate(), 2)
  19. m = App.Utils.formatTime(timeObject.getMonth() + 1, 2)
  20. y = timeObject.getFullYear()
  21. "#{y}-#{m}-#{d}"
  22. # define datetime format helper
  23. datetime: (time) ->
  24. return '' if !time
  25. timeObject = new Date(time)
  26. d = App.Utils.formatTime(timeObject.getDate(), 2)
  27. m = App.Utils.formatTime(timeObject.getMonth() + 1, 2)
  28. y = timeObject.getFullYear()
  29. S = App.Utils.formatTime(timeObject.getSeconds(), 2)
  30. M = App.Utils.formatTime(timeObject.getMinutes(), 2)
  31. H = App.Utils.formatTime(timeObject.getHours(), 2)
  32. "#{y}-#{m}-#{d} #{H}:#{M}:#{S}"
  33. # define decimal format helper
  34. decimal: (data, positions = 2) ->
  35. App.Utils.decimal(data, positions)
  36. # define mask helper
  37. M: (item, start = 1, end = 2) ->
  38. return '' if !item
  39. string = ''
  40. end = item.length - end - 1
  41. for n in [0..item.length-1]
  42. if start <= n && end >= n
  43. string += '*'
  44. else
  45. string += item[n]
  46. string
  47. # define translation helper
  48. T: (item, args...) ->
  49. App.i18n.translateContent(item, args...)
  50. # define translation inline helper
  51. Ti: (item, args...) ->
  52. App.i18n.translateInline(item, args...)
  53. # define translation for date helper
  54. Tdate: (item, args...) ->
  55. App.i18n.translateDate(item, args...)
  56. # define translation for timestamp helper
  57. Ttimestamp: (item, args...) ->
  58. App.i18n.translateTimestamp(item, args...)
  59. # define linkify helper
  60. L: (item) ->
  61. if item && typeof item is 'string'
  62. return App.Utils.linkify(item)
  63. item
  64. # define config helper
  65. C: (key) ->
  66. App.Config.get(key)
  67. # define session helper
  68. S: (key) ->
  69. App.Session.get(key)
  70. # define address line helper
  71. AddressLine: (line) ->
  72. return '' if !line
  73. items = emailAddresses.parseAddressList(line)
  74. # line was not parsable
  75. return App.Utils.htmlEscape(line) if !items
  76. # set markup
  77. result = ''
  78. for item in items
  79. if result
  80. result = result + ', '
  81. if item.name
  82. item.name = item.name
  83. .replace(',', '')
  84. .replace(';', '')
  85. .replace('"', '')
  86. .replace('\'', '')
  87. if item.name.match(/\@|,|;|\^|\+|#|§|\$|%|&|\/|\(|\)|=|\?|\*/)
  88. item.name = "\"#{item.name}\""
  89. result = "#{result}#{App.Utils.htmlEscape(item.name)} "
  90. if item.address
  91. result = result + " <span class=\"text-muted\">&lt;#{App.Utils.htmlEscape(item.address)}&gt</span>"
  92. result
  93. # define file size helper
  94. humanFileSize: (size) ->
  95. App.Utils.humanFileSize(size)
  96. # define pretty/human time helper
  97. humanTime: (time, escalation = false, cssClass = '') ->
  98. timestamp = App.i18n.translateTimestamp(time)
  99. if escalation
  100. cssClass += ' escalation'
  101. humanTime = App.PrettyDate.humanTime(time, escalation)
  102. "<time class=\"humanTimeFromNow #{cssClass}\" data-time=\"#{time}\" title=\"#{timestamp}\">#{humanTime}</time>"
  103. # define icon helper
  104. Icon: (name, className = '') ->
  105. App.Utils.icon(name, className)
  106. # define richtext helper
  107. RichText: (string) ->
  108. return string if !string
  109. if string.match(/@T\('/)
  110. string = string.replace(/@T\('(.+?)'\)/g, (match, capture) ->
  111. App.i18n.translateContent(capture)
  112. )
  113. return marked(string)
  114. App.i18n.translateContent(string)
  115. ContentTypeIcon: (contentType) ->
  116. icons =
  117. # image
  118. 'image/jpeg': 'file-image'
  119. 'image/jpg': 'file-image'
  120. 'image/png': 'file-image'
  121. 'image/svg': 'file-image'
  122. # documents
  123. 'application/pdf': 'file-pdf'
  124. 'application/msword': 'file-word' # .doc, .dot
  125. 'application/vnd.ms-word': 'file-word'
  126. 'application/vnd.oasis.opendocument.text': 'file-word'
  127. 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'file-word' # .docx
  128. 'application/vnd.openxmlformats-officedocument.wordprocessingml.template': 'file-word' # .dotx
  129. 'application/vnd.ms-excel': 'file-excel' # .xls
  130. 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'file-excel' # .xlsx
  131. 'application/vnd.oasis.opendocument.spreadsheet': 'file-excel'
  132. 'application/vnd.ms-powerpoint': 'file-powerpoint' # .ppt
  133. 'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'file-powerpoint' # .pptx
  134. 'application/vnd.oasis.opendocument.presentation': 'file-powerpoint'
  135. 'text/plain': 'file-text'
  136. 'text/html': 'file-code'
  137. 'application/json': 'file-code'
  138. 'message/rfc822': 'file-email'
  139. # code
  140. 'application/json': 'file-code'
  141. # text
  142. 'text/plain': 'file-text'
  143. 'text/rtf': 'file-text'
  144. # archives
  145. 'application/gzip': 'file-archive'
  146. 'application/zip': 'file-archive'
  147. return icons[contentType]
  148. canDownload: (contentType) ->
  149. contentType != 'text/html'
  150. @viewPrint: (object, attributeName, attributes, table) ->
  151. if !attributes
  152. attributes = {}
  153. if object.constructor.attributesGet
  154. attributes = object.constructor.attributesGet()
  155. attributeConfig = attributes[attributeName]
  156. value = object[attributeName]
  157. valueRef = undefined
  158. # check if relation is requested
  159. if !attributeConfig
  160. attributeNameNew = "#{attributeName}_id"
  161. attributeConfig = attributes[attributeNameNew]
  162. if attributeConfig
  163. attributeName = attributeNameNew
  164. if object[attributeName]
  165. valueRef = value
  166. value = object[attributeName]
  167. # in case of :: key, get the sub value
  168. if !value
  169. parts = attributeName.split('::')
  170. if parts[0] && parts[1] && object[ parts[0] ]
  171. value = object[ parts[0] ][ parts[1] ]
  172. # if we have no config, get output this way
  173. if !attributeConfig
  174. return @viewPrintItem(value)
  175. # check if valueRef already exists, no lookup needed later
  176. if !valueRef
  177. if attributeName.substr(attributeName.length-3, attributeName.length) is '_id'
  178. attributeNameWithoutRef = attributeName.substr(0, attributeName.length-3)
  179. if object[attributeNameWithoutRef]
  180. valueRef = object[attributeNameWithoutRef]
  181. @viewPrintItem(value, attributeConfig, valueRef, table)
  182. # define print name helper
  183. @viewPrintItem: (item, attributeConfig = {}, valueRef, table) ->
  184. return '-' if item is undefined
  185. return '-' if item is ''
  186. return item if item is null
  187. result = ''
  188. items = [item]
  189. if _.isArray(item)
  190. items = item
  191. # lookup relation
  192. for item in items
  193. resultLocal = item
  194. if attributeConfig.relation || valueRef
  195. if valueRef
  196. item = valueRef
  197. else
  198. item = App[attributeConfig.relation].find(item)
  199. # if date is a object, get name of the object
  200. isObject = false
  201. if item && typeof item is 'object'
  202. isObject = true
  203. if item.displayNameLong
  204. resultLocal = item.displayNameLong()
  205. else if item.displayName
  206. resultLocal = item.displayName()
  207. else
  208. resultLocal = item.name
  209. # execute callback on content
  210. if attributeConfig.callback
  211. resultLocal = attributeConfig.callback(resultLocal, attributeConfig)
  212. # text2html in textarea view
  213. isHtmlEscape = false
  214. if attributeConfig.tag is 'textarea'
  215. isHtmlEscape = true
  216. resultLocal = App.Utils.text2html(resultLocal)
  217. # remember, html snippets are already escaped
  218. else if attributeConfig.tag is 'richtext'
  219. isHtmlEscape = true
  220. # fillup options
  221. if !_.isEmpty(attributeConfig.options)
  222. if attributeConfig.options[resultLocal]
  223. resultLocal = attributeConfig.options[resultLocal]
  224. # transform boolean
  225. if attributeConfig.tag is 'boolean'
  226. if resultLocal is true
  227. resultLocal = 'yes'
  228. else if resultLocal is false
  229. resultLocal = 'no'
  230. # translate content
  231. if attributeConfig.translate || (isObject && item.translate && item.translate())
  232. isHtmlEscape = true
  233. resultLocal = App.i18n.translateContent(resultLocal)
  234. # transform date
  235. if attributeConfig.tag is 'date'
  236. isHtmlEscape = true
  237. resultLocal = App.i18n.translateDate(resultLocal)
  238. # transform input tel|url to make it clickable
  239. if attributeConfig.tag is 'input'
  240. if attributeConfig.type is 'tel'
  241. resultLocal = "<a href=\"#{App.Utils.phoneify(resultLocal)}\">#{App.Utils.htmlEscape(resultLocal)}</a>"
  242. else if attributeConfig.type is 'url'
  243. resultLocal = App.Utils.linkify(resultLocal)
  244. else
  245. resultLocal = App.Utils.htmlEscape(resultLocal)
  246. isHtmlEscape = true
  247. # use pretty time for datetime
  248. else if attributeConfig.tag is 'datetime'
  249. isHtmlEscape = true
  250. timestamp = App.i18n.translateTimestamp(resultLocal)
  251. escalation = false
  252. cssClass = attributeConfig.class || ''
  253. if cssClass.match 'escalation'
  254. escalation = true
  255. humanTime = ''
  256. if !table
  257. humanTime = App.PrettyDate.humanTime(resultLocal, escalation)
  258. resultLocal = "<time class=\"humanTimeFromNow #{cssClass}\" data-time=\"#{resultLocal}\" title=\"#{timestamp}\">#{humanTime}</time>"
  259. if !isHtmlEscape && typeof resultLocal is 'string'
  260. resultLocal = App.Utils.htmlEscape(resultLocal)
  261. if !_.isEmpty(result)
  262. result += ', '
  263. result += resultLocal
  264. result
  265. @view: (name) ->
  266. template = (params = {}) ->
  267. JST["app/views/#{name}"](_.extend(params, helper))
  268. template
  269. class App.UiElement
  270. window.App = App