Added text module feature.
This commit is contained in:
parent
e4506dd1a3
commit
898ee67a88
22 changed files with 590 additions and 67 deletions
|
@ -8,27 +8,25 @@ class App.ControllerGenericNew extends App.ControllerModal
|
|||
constructor: (params) ->
|
||||
super
|
||||
@render()
|
||||
|
||||
|
||||
render: ->
|
||||
|
||||
@html App.view('generic/admin/new')( head: @pageData.object )
|
||||
|
||||
new App.ControllerForm(
|
||||
el: @el.find('#object_new'),
|
||||
model: @genericObject,
|
||||
model: App[ @genericObject ],
|
||||
params: @item,
|
||||
required: @required,
|
||||
autofocus: true,
|
||||
)
|
||||
|
||||
@modalShow()
|
||||
|
||||
submit: (e) ->
|
||||
@log 'submit'
|
||||
e.preventDefault()
|
||||
params = @formParam(e.target)
|
||||
params = @formParam( e.target )
|
||||
|
||||
object = new @genericObject
|
||||
object = new App[ @genericObject ]
|
||||
object.load(params)
|
||||
|
||||
# validate
|
||||
|
@ -53,7 +51,7 @@ class App.ControllerGenericNew extends App.ControllerModal
|
|||
ui.modalHide()
|
||||
App.Collection.find( ui.pageData.object, @id, callbackReload , true )
|
||||
|
||||
error: =>
|
||||
error: ->
|
||||
ui.log 'errors'
|
||||
ui.modalHide()
|
||||
)
|
||||
|
@ -64,28 +62,27 @@ class App.ControllerGenericEdit extends App.ControllerModal
|
|||
@log 'ControllerGenericEditWindow', params
|
||||
|
||||
# fetch item on demand
|
||||
if @genericObject.exists(params.id)
|
||||
@item = @genericObject.find(params.id)
|
||||
if App[ @genericObject ].exists( params.id )
|
||||
@item = App[ @genericObject ].find( params.id )
|
||||
@render()
|
||||
else
|
||||
@genericObject.bind 'refresh', =>
|
||||
App[ @genericObject ].bind 'refresh', =>
|
||||
@log 'changed....'
|
||||
@item = @genericObject.find(params.id)
|
||||
@item = App[ @genericObject ].find( params.id )
|
||||
@render()
|
||||
@genericObject.unbind 'refresh'
|
||||
@genericObject.fetch( id: params.id)
|
||||
App[ @genericObject ].unbind 'refresh'
|
||||
App[ @genericObject ].fetch( id: params.id )
|
||||
|
||||
render: ->
|
||||
@html App.view('generic/admin/edit')( head: @pageData.object )
|
||||
|
||||
@html App.view('generic/admin/edit')( head: @pageData.object )
|
||||
new App.ControllerForm(
|
||||
el: @el.find('#object_edit'),
|
||||
model: @genericObject,
|
||||
model: App[ @genericObject ],
|
||||
params: @item,
|
||||
required: @required,
|
||||
autofocus: true,
|
||||
)
|
||||
|
||||
@modalShow()
|
||||
|
||||
submit: (e) ->
|
||||
|
@ -139,8 +136,8 @@ class App.ControllerGenericIndex extends App.Controller
|
|||
@navupdate @pageData.navupdate
|
||||
|
||||
# bind render after a change is done
|
||||
@genericObject.bind 'refresh change', @render
|
||||
@genericObject.bind 'ajaxError', (rec, msg) =>
|
||||
App[ @genericObject ].bind 'refresh change', @render
|
||||
App[ @genericObject ].bind 'ajaxError', (rec, msg) =>
|
||||
@log 'ajax notice', msg.status
|
||||
if msg.status is 401
|
||||
@log 'ajax error', rec, msg, msg.status
|
||||
|
@ -149,16 +146,16 @@ class App.ControllerGenericIndex extends App.Controller
|
|||
@navigate 'login'
|
||||
|
||||
# execute fetch, if needed
|
||||
if !@genericObject.count() || true
|
||||
# if !@genericObject.count()
|
||||
if !App[ @genericObject ].count() || true
|
||||
# if !App[ @genericObject ].count()
|
||||
|
||||
# prerender without content
|
||||
@render()
|
||||
|
||||
# fetch all
|
||||
# @log 'oooo', @genericObject.model
|
||||
# @genericObject.deleteAll()
|
||||
@genericObject.fetch()
|
||||
# @log 'oooo', App[ @genericObject ].model
|
||||
# App[ @genericObject ].deleteAll()
|
||||
App[ @genericObject ].fetch()
|
||||
else
|
||||
@render()
|
||||
|
||||
|
@ -166,7 +163,10 @@ class App.ControllerGenericIndex extends App.Controller
|
|||
|
||||
return if Config['ActiveController'] isnt @pageData.navupdate
|
||||
|
||||
objects = @genericObject.all()
|
||||
objects = App.Collection.all(
|
||||
type: @genericObject,
|
||||
sortBy: @defaultSortBy || 'name',
|
||||
)
|
||||
|
||||
# remove ignored items from collection
|
||||
if @ignoreObjectIDs
|
||||
|
@ -185,21 +185,21 @@ class App.ControllerGenericIndex extends App.Controller
|
|||
# append content table
|
||||
new App.ControllerTable(
|
||||
el: @el.find('.table-overview'),
|
||||
model: @genericObject,
|
||||
model: App[ @genericObject ],
|
||||
objects: objects,
|
||||
)
|
||||
|
||||
edit: (e) =>
|
||||
e.preventDefault()
|
||||
item = $(e.target).item(@genericObject)
|
||||
item = $(e.target).item( App[ @genericObject ] )
|
||||
new App.ControllerGenericEdit(
|
||||
id: item.id,
|
||||
pageData: @pageData,
|
||||
id: item.id,
|
||||
pageData: @pageData,
|
||||
genericObject: @genericObject
|
||||
)
|
||||
|
||||
destroy: (e) ->
|
||||
item = $(e.target).item(@genericObject)
|
||||
item = $(e.target).item( App[ @genericObject ] )
|
||||
item.destroy() if confirm('Sure?')
|
||||
|
||||
new: (e) ->
|
||||
|
@ -221,7 +221,7 @@ class App.ControllerLevel2 extends App.Controller
|
|||
# set title
|
||||
@title @page.title
|
||||
@navupdate @page.nav
|
||||
|
||||
|
||||
@html App.view('generic/admin_level2/index')(
|
||||
page: @page,
|
||||
menus: @menu,
|
||||
|
|
|
@ -138,6 +138,11 @@ class Index extends App.Controller
|
|||
template_id: template['id'],
|
||||
)
|
||||
|
||||
# show text module UI
|
||||
new App.TextModuleUI(
|
||||
el: @el.find('#text_module'),
|
||||
)
|
||||
|
||||
localUserInfo: (params) =>
|
||||
@userInfo( user_id: params.customer_id )
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ class App.TicketHistory extends App.ControllerModal
|
|||
render: ->
|
||||
|
||||
@html App.view('agent_ticket_history')(
|
||||
objects: App.Collection.all( 'History' ),
|
||||
objects: App.Collection.all( type: 'History' ),
|
||||
)
|
||||
|
||||
@modalShow()
|
||||
|
|
|
@ -203,6 +203,12 @@ class Index extends App.Controller
|
|||
object: @ticket,
|
||||
)
|
||||
|
||||
# show text module UI
|
||||
if !@isRole('Customer')
|
||||
new App.TextModuleUI(
|
||||
el: @el.find('#text_module'),
|
||||
)
|
||||
|
||||
show_toogle: (e) ->
|
||||
e.preventDefault()
|
||||
$(e.target).hide()
|
||||
|
@ -320,12 +326,12 @@ class Index extends App.Controller
|
|||
# @log 'reply ', article, @el.find('[name="to"]')
|
||||
|
||||
# add quoted text if needed
|
||||
if window.Session['UISelection']
|
||||
selectedText = App.ClipBoard.getSelected()
|
||||
if selectedText
|
||||
body = @el.find('[name="body"]').val() || ''
|
||||
selection = window.Session['UISelection'].trim()
|
||||
selection = selection.replace /^(.*)$/mg, (match) =>
|
||||
selectedText = selectedText.replace /^(.*)$/mg, (match) =>
|
||||
'> ' + match
|
||||
body = selection + "\n" + body
|
||||
body = selectedText + "\n" + body
|
||||
@el.find('[name="body"]').val(body)
|
||||
|
||||
# update textarea size
|
||||
|
|
|
@ -10,7 +10,7 @@ class Index extends App.Controller
|
|||
new App.ControllerGenericIndex(
|
||||
el: @el,
|
||||
id: @id,
|
||||
genericObject: App.Group,
|
||||
genericObject: 'Group',
|
||||
pageData: {
|
||||
title: 'Groups',
|
||||
home: 'groups',
|
||||
|
|
|
@ -10,7 +10,7 @@ class Index extends App.Controller
|
|||
new App.ControllerGenericIndex(
|
||||
el: @el,
|
||||
id: @id,
|
||||
genericObject: App.Organization,
|
||||
genericObject: 'Organization',
|
||||
pageData: {
|
||||
title: 'Organizations',
|
||||
home: 'organizations',
|
||||
|
|
|
@ -71,7 +71,7 @@ class App.TemplateUI extends App.Controller
|
|||
params = @formParam(e.target)
|
||||
name = params['template_name']
|
||||
# delete params['template_name']
|
||||
|
||||
|
||||
template = App.Collection.findByAttribute( 'Template', 'name', name )
|
||||
if !template
|
||||
template = new App.Template
|
||||
|
@ -84,7 +84,7 @@ class App.TemplateUI extends App.Controller
|
|||
|
||||
# validate form
|
||||
errors = template.validate()
|
||||
|
||||
|
||||
# show errors in form
|
||||
if errors
|
||||
@log 'error new', errors
|
||||
|
|
31
app/assets/javascripts/app/controllers/text_module.js.coffee
Normal file
31
app/assets/javascripts/app/controllers/text_module.js.coffee
Normal file
|
@ -0,0 +1,31 @@
|
|||
$ = jQuery.sub()
|
||||
|
||||
class Index extends App.Controller
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
# check authentication
|
||||
return if !@authenticate()
|
||||
|
||||
new App.ControllerGenericIndex(
|
||||
el: @el,
|
||||
id: @id,
|
||||
genericObject: 'TextModule',
|
||||
pageData: {
|
||||
title: 'TextModules',
|
||||
home: 'text_modules',
|
||||
object: 'TextModule',
|
||||
objects: 'TextModules',
|
||||
navupdate: '#text_modules',
|
||||
notes: [
|
||||
'TextModules are ...'
|
||||
],
|
||||
buttons: [
|
||||
{ name: 'New TextModule', 'data-type': 'new', class: 'primary' },
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
Config.Routes['text_modules'] = Index
|
||||
Config.NavBar['AdminTextModule'] = { prio: 2300, parent: '#admin', name: 'Text Modules', target: '#text_modules', role: ['Admin'] }
|
||||
|
212
app/assets/javascripts/app/controllers/text_modules.js.coffee
Normal file
212
app/assets/javascripts/app/controllers/text_modules.js.coffee
Normal file
|
@ -0,0 +1,212 @@
|
|||
$ = jQuery.sub()
|
||||
|
||||
class App.TextModuleUI extends App.Controller
|
||||
events:
|
||||
'click [data-type=text_module_save]': 'create',
|
||||
'click [data-type=text_module_select]': 'select',
|
||||
'click [data-type=text_module_delete]': 'delete',
|
||||
'click [data-type=edit]': 'select',
|
||||
'dblclick [data-type=edit]': 'paste',
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
# fetch item on demand
|
||||
fetch_needed = 1
|
||||
if App.Collection.count( 'TextModule' ) > 0
|
||||
fetch_needed = 0
|
||||
@render()
|
||||
|
||||
if fetch_needed
|
||||
@reload()
|
||||
|
||||
reload: =>
|
||||
App.TextModule.bind 'refresh', =>
|
||||
@log 'loading....'
|
||||
@render()
|
||||
App.TextModule.unbind 'refresh'
|
||||
App.Collection.fetch( 'TextModule' )
|
||||
|
||||
render: =>
|
||||
|
||||
ui = @
|
||||
a = $('textarea')
|
||||
|
||||
# remember active text element
|
||||
a.bind('focusin', ->
|
||||
ui.area = $(@)
|
||||
)
|
||||
|
||||
ui.C = false
|
||||
ui.CList = ''
|
||||
a.bind('keydown', (e) ->
|
||||
|
||||
# lisen if crtl is pressed
|
||||
if ui.C
|
||||
key = App.ClipBoard.keycode( e.keyCode )
|
||||
|
||||
# remove one char
|
||||
if key is 'backspace'
|
||||
ui.CList = ui.CList.slice( 0, -1 )
|
||||
|
||||
# take over
|
||||
else if key is 'enter'
|
||||
# ui.CList = ui.CList.slice(0, -1)
|
||||
objects = ui.objectSearch( ui.CList )
|
||||
if objects[0]
|
||||
ui._insert( objects[0].content, ui )
|
||||
|
||||
# reset search
|
||||
ui.CList = ''
|
||||
ui.renderTable()
|
||||
|
||||
# add char to search selection
|
||||
else
|
||||
ui.CList = ui.CList + key
|
||||
|
||||
console.log 'CTRL+', ui.CList
|
||||
ui.el.find('#text-module-search').val( ui.CList )
|
||||
ui.renderTable( ui.CList )
|
||||
|
||||
# start current search process
|
||||
if e.ctrlKey
|
||||
ui.C = true
|
||||
)
|
||||
|
||||
# start current search process
|
||||
# do code to test other keys
|
||||
a.bind('keyup', (e) ->
|
||||
if e.keyCode == 17
|
||||
console.log 'CTRL UP - pressed ', ui.CList
|
||||
ui.CList = ''
|
||||
ui.C = false
|
||||
ui.renderTable()
|
||||
)
|
||||
|
||||
@configure_attributes = [
|
||||
{ name: 'text_module_id', display: '', tag: 'select', multiple: false, null: true, nulloption: true, relation: 'TextModule', class: 'span2', default: @text_module_id },
|
||||
]
|
||||
|
||||
text_module = {}
|
||||
if @text_module_id
|
||||
text_module = App.Collection.find( 'TextModule', @text_module_id )
|
||||
|
||||
# insert data
|
||||
@html App.view('text_module')(
|
||||
text_module: text_module,
|
||||
search: @search,
|
||||
)
|
||||
|
||||
# rerender if search phrase has changed
|
||||
@el.find('#text-module-search').unbind('keyup').bind('keyup', =>
|
||||
search = $('#text-module-search').val();
|
||||
console.log 'SEARCH', search
|
||||
@renderTable( search )
|
||||
)
|
||||
|
||||
@renderTable('')
|
||||
|
||||
objectSearch: (search) =>
|
||||
objects = App.Collection.all(
|
||||
type: 'TextModule',
|
||||
sortBy: 'name',
|
||||
filter: { active: true },
|
||||
filterExtended: [ { name: search }, { content: search }, { keywords: search } ],
|
||||
)
|
||||
|
||||
|
||||
renderTable: (search) =>
|
||||
|
||||
objects = @objectSearch(search)
|
||||
|
||||
@el.find('#form-text-module').html('')
|
||||
new App.ControllerTable(
|
||||
el: @el.find('#form-text-module'),
|
||||
# header: ['Name'],
|
||||
overview: ['name'],
|
||||
model: App.TextModule,
|
||||
objects: objects,
|
||||
# radio: true,
|
||||
)
|
||||
|
||||
paste: (e) =>
|
||||
e.preventDefault()
|
||||
id = $(e.target).parents('tr').data('id')
|
||||
text_module = App.Collection.find( 'TextModule', id )
|
||||
@_insert( text_module.content, @ )
|
||||
|
||||
delete: (e) =>
|
||||
e.preventDefault()
|
||||
|
||||
# get params
|
||||
params = @formParam(e.target)
|
||||
text_module = App.Collection.find( 'TextModule', params['text_module_id'] )
|
||||
if confirm('Sure?')
|
||||
text_module.destroy()
|
||||
@text_module_id = undefined
|
||||
@render()
|
||||
|
||||
select: (e) =>
|
||||
e.preventDefault()
|
||||
id = $(e.target).parents('tr').data('id')
|
||||
text_module = App.Collection.find( 'TextModule', id )
|
||||
@el.find('#text-module-preview-content').val( text_module.content )
|
||||
|
||||
create: (e) =>
|
||||
e.preventDefault()
|
||||
|
||||
# get params
|
||||
params = @formParam(e.target)
|
||||
name = params['text_module_name']
|
||||
# delete params['text_module_name']
|
||||
|
||||
text_module = App.Collection.findByAttribute( 'TextModule', 'name', name )
|
||||
if !text_module
|
||||
text_module = new App.TextModule
|
||||
|
||||
content = App.ClipBoard.getSelectedLast()
|
||||
if content
|
||||
text_module.load(
|
||||
name: params['text_module_name']
|
||||
content: content
|
||||
)
|
||||
|
||||
# validate form
|
||||
errors = text_module.validate()
|
||||
|
||||
# show errors in form
|
||||
if errors
|
||||
@log 'error new', errors
|
||||
else
|
||||
ui = @
|
||||
text_module.save(
|
||||
success: ->
|
||||
ui.text_module_id = @.id
|
||||
ui.render()
|
||||
ui.log 'save success!'
|
||||
|
||||
error: ->
|
||||
ui.log 'save failed!'
|
||||
)
|
||||
|
||||
_insert: (contentNew, ui) ->
|
||||
position = ui.area.prop('selectionStart')
|
||||
content = ui.area.val()
|
||||
start = content.substr( 0, position )
|
||||
end = content.substr( position, content.length )
|
||||
|
||||
# check if \n is needed
|
||||
startEnd = start.substr( start.length-2, 2 )
|
||||
|
||||
if position is 0 || startEnd is "\n\n"
|
||||
startDiver = ''
|
||||
else
|
||||
startDiver = "\n"
|
||||
content = start + startDiver + contentNew + end
|
||||
ui.area.val(content)
|
||||
|
||||
# update cursor position
|
||||
currentPosition = (position + contentNew.length + startDiver.length )
|
||||
ui.area.prop('selectionStart', currentPosition )
|
||||
ui.area.prop('selectionEnd', currentPosition )
|
||||
|
|
@ -10,7 +10,8 @@ class Index extends App.Controller
|
|||
new App.ControllerGenericIndex(
|
||||
el: @el,
|
||||
id: @id,
|
||||
genericObject: App.User,
|
||||
genericObject: 'User',
|
||||
defaultSortBy: 'login',
|
||||
ignoreObjectIDs: [1],
|
||||
pageData: {
|
||||
title: 'Users',
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#not_used= require_tree ./lib
|
||||
#= require_self
|
||||
#= require ./lib/ajax.js.coffee
|
||||
#= require ./lib/clipboard.js.coffee
|
||||
#= require ./lib/websocket.js.coffee
|
||||
#= require ./lib/auth.js.coffee
|
||||
#= require ./lib/i18n.js.coffee
|
||||
|
|
|
@ -202,14 +202,24 @@ class _Singleton
|
|||
|
||||
get: (params) ->
|
||||
console.log('get')
|
||||
App[params.type].refresh( object, options: { clear: true } )
|
||||
App[ params.type ].refresh( object, options: { clear: true } )
|
||||
|
||||
all: (type) ->
|
||||
all = App[type].all()
|
||||
all: (params) ->
|
||||
all = App[ params.type ].all()
|
||||
all_complied = []
|
||||
for item in all
|
||||
item_new = @find( type, item.id )
|
||||
item_new = @find( params.type, item.id )
|
||||
all_complied.push item_new
|
||||
|
||||
if params.filter
|
||||
all_complied = @_filter( all_complied, params.filter )
|
||||
|
||||
if params.filterExtended
|
||||
all_complied = @_filterExtended( all_complied, params.filterExtended )
|
||||
|
||||
if params.sortBy
|
||||
all_complied = @_sortBy( all_complied, params.sortBy )
|
||||
|
||||
return all_complied
|
||||
|
||||
deleteAll: (type) ->
|
||||
|
@ -223,3 +233,40 @@ class _Singleton
|
|||
|
||||
fetch: ( type ) ->
|
||||
App[type].fetch()
|
||||
|
||||
_sortBy: ( collection, attribute ) ->
|
||||
_.sortBy( collection, (item) -> return item[ attribute ].toLowerCase() )
|
||||
|
||||
_filter: ( collection, filter ) ->
|
||||
for key, value of filter
|
||||
collection = _.filter( collection, (item) ->
|
||||
if item[ key ] is value
|
||||
return item
|
||||
)
|
||||
return collection
|
||||
|
||||
_filterExtended: ( collection, filters ) ->
|
||||
collection = _.filter( collection, (item) ->
|
||||
|
||||
# check all filters
|
||||
for filter in filters
|
||||
|
||||
# all conditions need match
|
||||
matchInner = undefined
|
||||
for key, value of filter
|
||||
|
||||
if matchInner isnt false
|
||||
reg = new RegExp( value, 'i' )
|
||||
if item[ key ] isnt undefined && item[ key ] isnt null && item[ key ].match( reg )
|
||||
matchInner = true
|
||||
else
|
||||
matchInner = false
|
||||
|
||||
# if all matched, add item to new collection
|
||||
if matchInner is true
|
||||
return item
|
||||
|
||||
return
|
||||
)
|
||||
return collection
|
||||
|
||||
|
|
|
@ -22,24 +22,12 @@ class App.Run extends App.Controller
|
|||
|
||||
# start notify controller
|
||||
new App.Notify( el: @el.find('#notify') )
|
||||
|
||||
|
||||
# start content
|
||||
new App.Content( el: @el.find('#content') )
|
||||
|
||||
# bind to fill selected text into
|
||||
$(@el).bind('mouseup', =>
|
||||
window.Session['UISelection'] = @getSelected() + ''
|
||||
)
|
||||
|
||||
getSelected: ->
|
||||
text = '';
|
||||
if window.getSelection
|
||||
text = window.getSelection()
|
||||
else if document.getSelection
|
||||
text = document.getSelection()
|
||||
else if document.selection
|
||||
text = document.selection.createRange().text
|
||||
text
|
||||
App.ClipBoard.bind( @el )
|
||||
|
||||
class App.Content extends Spine.Controller
|
||||
className: 'container'
|
||||
|
|
|
@ -29,7 +29,7 @@ class _Singleton extends Spine.Controller
|
|||
|
||||
send: (data) =>
|
||||
return if !@supported
|
||||
console.log 'ws:send trying', data, @ws, @ws.readyState
|
||||
# console.log 'ws:send trying', data, @ws, @ws.readyState
|
||||
|
||||
# A value of 0 indicates that the connection has not yet been established.
|
||||
# A value of 1 indicates that the connection is established and communication is possible.
|
||||
|
@ -38,7 +38,7 @@ class _Singleton extends Spine.Controller
|
|||
if @ws.readyState is 0
|
||||
@queue.push data
|
||||
else
|
||||
console.log( 'ws:send', data )
|
||||
# console.log( 'ws:send', data )
|
||||
string = JSON.stringify( data )
|
||||
@ws.send(string)
|
||||
|
||||
|
@ -60,7 +60,7 @@ class _Singleton extends Spine.Controller
|
|||
ping: =>
|
||||
return if !@supported
|
||||
|
||||
console.log 'send websockend ping'
|
||||
# console.log 'send websockend ping'
|
||||
@send( { action: 'ping' } )
|
||||
|
||||
# check if ping is back within 2 min
|
||||
|
@ -73,8 +73,7 @@ class _Singleton extends Spine.Controller
|
|||
|
||||
pong: ->
|
||||
return if !@supported
|
||||
|
||||
console.log 'received websockend ping'
|
||||
# console.log 'received websockend ping'
|
||||
|
||||
# test again after 1 min
|
||||
@delay @ping, 60000
|
||||
|
@ -111,7 +110,7 @@ class _Singleton extends Spine.Controller
|
|||
|
||||
# empty queue
|
||||
for item in @queue
|
||||
console.log( 'ws:send queue', item )
|
||||
# console.log( 'ws:send queue', item )
|
||||
@send(item)
|
||||
@queue = []
|
||||
|
||||
|
|
16
app/assets/javascripts/app/models/text_module.js.coffee
Normal file
16
app/assets/javascripts/app/models/text_module.js.coffee
Normal file
|
@ -0,0 +1,16 @@
|
|||
class App.TextModule extends App.Model
|
||||
@configure 'TextModule', 'name', 'keywords', 'content', 'active', 'group_ids', 'user_id'
|
||||
@extend Spine.Model.Ajax
|
||||
@url: '/api/text_modules'
|
||||
@configure_attributes = [
|
||||
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, 'null': false, 'class': 'span4' },
|
||||
{ name: 'keywords', display: 'Keywords', tag: 'input', type: 'text', limit: 100, 'null': true, 'class': 'span4' },
|
||||
{ name: 'content', display: 'Content', tag: 'textarea', limit: 250, 'null': false, 'class': 'span4' },
|
||||
{ name: 'updated_at', display: 'Updated', type: 'time', readonly: 1 },
|
||||
{ name: 'active', display: 'Active', tag: 'boolean', note: 'boolean', 'default': true, 'null': false, 'class': 'span4' },
|
||||
]
|
||||
@configure_overview = [
|
||||
'name',
|
||||
'keywords',
|
||||
'content',
|
||||
]
|
|
@ -7,6 +7,7 @@
|
|||
<div class="span3">
|
||||
<div id="customer_info"></div>
|
||||
<div id="ticket_template"></div>
|
||||
<div id="text_module"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
|
|
|
@ -91,9 +91,10 @@
|
|||
</div>
|
||||
|
||||
<div class="span3">
|
||||
<div class="row" id="customer_info"></div>
|
||||
<div class="row" id="action_info"></div>
|
||||
<div class="row" id="link_info"></div>
|
||||
<div id="customer_info"></div>
|
||||
<div id="action_info"></div>
|
||||
<div id="link_info"></div>
|
||||
<div id="text_module"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
20
app/assets/javascripts/app/views/text_module.jst.eco
Normal file
20
app/assets/javascripts/app/views/text_module.jst.eco
Normal file
|
@ -0,0 +1,20 @@
|
|||
<div class="well">
|
||||
<h3><%- @T( 'Text Modules' ) %></h3>
|
||||
<%- @T( 'Search' ) %>
|
||||
<br>
|
||||
<input type="text" name="" id="text-module-search" class="span2" value="<%= @search %>" autocomplete="off"/>
|
||||
<br>
|
||||
<div id="form-text-module"></div>
|
||||
<!--<button type="submit" class="btn" data-type="text_module_edit"><%- @T( 'Edit' ) %></button>-->
|
||||
<!--
|
||||
<button type="submit" class="btn" data-type="text_module_delete"><%- @T( 'Delete' ) %></button>
|
||||
<button type="submit" class="btn" data-type="text_module_select"><%- @T( 'Apply' ) %></button>
|
||||
-->
|
||||
<%- @T( 'Preview ') %>
|
||||
<br>
|
||||
<textarea id="text-module-preview-content" class="span2"></textarea>
|
||||
<hr>
|
||||
<label class="" for="text_module_name"><%- @T( 'Save as Text Module' ) %></label>
|
||||
<input type="text" name="text_module_name" id="text_module_name" class="span2" value="<%= @text_module.name %>"/>
|
||||
<button type="submit" class="btn" data-type="text_module_save"><%- @T( 'Save' ) %></button>
|
||||
</div>
|
148
app/controllers/text_modules_controller.rb
Normal file
148
app/controllers/text_modules_controller.rb
Normal file
|
@ -0,0 +1,148 @@
|
|||
class TextModulesController < ApplicationController
|
||||
before_filter :authentication_check
|
||||
|
||||
=begin
|
||||
|
||||
Format:
|
||||
JSON
|
||||
|
||||
Example:
|
||||
{
|
||||
"id":1,
|
||||
"name":"some text_module",
|
||||
"user_id": null,
|
||||
"keywords":"some keywords",
|
||||
"content":"some content",
|
||||
"active":true,
|
||||
"updated_at":"2012-09-14T17:51:53Z",
|
||||
"created_at":"2012-09-14T17:51:53Z",
|
||||
"updated_by_id":2.
|
||||
"created_by_id":2,
|
||||
}
|
||||
|
||||
=end
|
||||
|
||||
=begin
|
||||
|
||||
Resource:
|
||||
GET /api/text_modules.json
|
||||
|
||||
Response:
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "some_name1",
|
||||
...
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "some_name2",
|
||||
...
|
||||
}
|
||||
]
|
||||
|
||||
Test:
|
||||
curl http://localhost/api/text_modules.json -v -u #{login}:#{password}
|
||||
|
||||
=end
|
||||
|
||||
def index
|
||||
model_index_render(TextModule, params)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
Resource:
|
||||
GET /api/text_modules/#{id}.json
|
||||
|
||||
Response:
|
||||
{
|
||||
"id": 1,
|
||||
"name": "name_1",
|
||||
...
|
||||
}
|
||||
|
||||
Test:
|
||||
curl http://localhost/api/text_modules/#{id}.json -v -u #{login}:#{password}
|
||||
|
||||
=end
|
||||
|
||||
def show
|
||||
model_show_render(TextModule, params)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
Resource:
|
||||
POST /api/text_modules.json
|
||||
|
||||
Payload:
|
||||
{
|
||||
"name": "some name",
|
||||
"keywords":"some keywords",
|
||||
"content":"some content",
|
||||
"active":true,
|
||||
}
|
||||
|
||||
Response:
|
||||
{
|
||||
"id": 1,
|
||||
"name": "some_name",
|
||||
...
|
||||
}
|
||||
|
||||
Test:
|
||||
curl http://localhost/api/text_modules.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"name": "some_name","active": true, "note": "some note"}'
|
||||
|
||||
=end
|
||||
|
||||
def create
|
||||
model_create_render(TextModule, params)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
Resource:
|
||||
PUT /api/text_modules/{id}.json
|
||||
|
||||
Payload:
|
||||
{
|
||||
"name": "some name",
|
||||
"keywords":"some keywords",
|
||||
"content":"some content",
|
||||
"active":true,
|
||||
}
|
||||
|
||||
Response:
|
||||
{
|
||||
"id": 1,
|
||||
"name": "some_name",
|
||||
...
|
||||
}
|
||||
|
||||
Test:
|
||||
curl http://localhost/api/text_modules.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"name": "some_name","active": true, "note": "some note"}'
|
||||
|
||||
=end
|
||||
|
||||
def update
|
||||
model_update_render(TextModule, params)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
Resource:
|
||||
DELETE /api/text_modules/{id}.json
|
||||
|
||||
Response:
|
||||
{}
|
||||
|
||||
Test:
|
||||
curl http://localhost/api/text_modules.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X DELETE
|
||||
|
||||
=end
|
||||
|
||||
def destroy
|
||||
model_destory_render(TextModule, params)
|
||||
end
|
||||
end
|
4
app/models/text_module.rb
Normal file
4
app/models/text_module.rb
Normal file
|
@ -0,0 +1,4 @@
|
|||
class TextModule < ApplicationModel
|
||||
validates :name, :presence => true
|
||||
validates :content, :presence => true
|
||||
end
|
13
config/routes/text_module.rb
Normal file
13
config/routes/text_module.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
module ExtraRoutes
|
||||
def add(map)
|
||||
|
||||
# roles
|
||||
map.match '/api/text_modules', :to => 'text_modules#index', :via => :get
|
||||
map.match '/api/text_modules/:id', :to => 'text_modules#show', :via => :get
|
||||
map.match '/api/text_modules', :to => 'text_modules#create', :via => :post
|
||||
map.match '/api/text_modules/:id', :to => 'text_modules#update', :via => :put
|
||||
map.match '/api/text_modules/:id', :to => 'templates#destroy', :via => :delete
|
||||
|
||||
end
|
||||
module_function :add
|
||||
end
|
30
db/migrate/20121019140507_text_module_create.rb
Normal file
30
db/migrate/20121019140507_text_module_create.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
class TextModuleCreate < ActiveRecord::Migration
|
||||
def up
|
||||
create_table :text_modules do |t|
|
||||
t.references :user, :null => true
|
||||
t.column :name, :string, :limit => 250, :null => false
|
||||
t.column :keywords, :string, :limit => 500, :null => true
|
||||
t.column :content, :string, :limit => 5000, :null => false
|
||||
t.column :note, :string, :limit => 250, :null => true
|
||||
t.column :active, :boolean, :null => false, :default => true
|
||||
t.column :updated_by_id, :integer, :null => false
|
||||
t.column :created_by_id, :integer, :null => false
|
||||
t.timestamps
|
||||
end
|
||||
add_index :text_modules, [:user_id]
|
||||
add_index :text_modules, [:name]
|
||||
|
||||
create_table :text_modules_groups, :id => false do |t|
|
||||
t.integer :text_module_id
|
||||
t.integer :group_id
|
||||
end
|
||||
add_index :text_modules_groups, [:text_module_id]
|
||||
add_index :text_modules_groups, [:group_id]
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table :text_modules_groups
|
||||
drop_table :text_modules
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue