mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-14 07:00:01 -04:00
Achievement editor in place and looking mighty fine
This commit is contained in:
parent
c2d2f2a2b8
commit
1b2a251c58
6 changed files with 150 additions and 33 deletions
12
achievement_fixtures.js
Normal file
12
achievement_fixtures.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Fixtures
|
||||
|
||||
db.achievements.insert({
|
||||
query: '{"level.original": "52d97ecd32362bc86e004e87"}',
|
||||
index: true,
|
||||
slug: 'dungeon-arena-started',
|
||||
name: 'Dungeon Arena started',
|
||||
worth: 1,
|
||||
collection: 'level.session',
|
||||
description: 'Started playing Dungeon Arena.',
|
||||
userField: 'creator'
|
||||
});
|
|
@ -1,34 +1,5 @@
|
|||
c = require './../schemas'
|
||||
|
||||
module.exports =
|
||||
AchievementSchema =
|
||||
type: 'object'
|
||||
properties:
|
||||
name: c.shortString({title: 'Display Name'})
|
||||
query: { $ref: 'mongoFindQuery' } # TODO make this happen
|
||||
worth: { type: 'number' }
|
||||
model: { type: 'string' }
|
||||
description: { type: 'string' }
|
||||
userField: { type: 'string' }
|
||||
related: c.objectId
|
||||
proportionalTo:
|
||||
type: 'string'
|
||||
description: 'For repeatables only. Denotes the field a repeatable achievement needs for its calculations'
|
||||
required: ['name', 'query', 'worth', 'collection']
|
||||
|
||||
MongoFindQuerySchema =
|
||||
title: 'MongoDB Query'
|
||||
id: 'mongoFindQuery'
|
||||
type: 'object'
|
||||
patternProperties:
|
||||
'^[a-zA-Z0-9_\-\$]*$':
|
||||
type: [ 'string', 'object' ]
|
||||
oneOf: [
|
||||
{ $ref: 'mongoQueryOperator' }, # TODO make this happen
|
||||
{ type: 'string' }
|
||||
]
|
||||
additionalProperties: false
|
||||
|
||||
# TODO add these: http://docs.mongodb.org/manual/reference/operator/query/
|
||||
MongoQueryOperatorSchema =
|
||||
title: 'MongoDB Query operator'
|
||||
|
@ -42,4 +13,49 @@ MongoQueryOperatorSchema =
|
|||
'$lte': type: 'number'
|
||||
'$ne': type: [ 'number', 'string' ]
|
||||
'$nin': type: 'array'
|
||||
additionalProperties: true # TODO set to false when the schema's done
|
||||
additionalProperties: true # TODO set to false when the schema's done
|
||||
|
||||
MongoFindQuerySchema =
|
||||
title: 'MongoDB Query'
|
||||
id: 'mongoFindQuery'
|
||||
type: 'object'
|
||||
patternProperties:
|
||||
'^[-a-zA-Z0-9_]*$':
|
||||
oneOf: [
|
||||
#{ $ref: '#/definitions/' + MongoQueryOperatorSchema.id},
|
||||
{ type: 'string' }
|
||||
]
|
||||
properties:
|
||||
'levelID':
|
||||
oneOf: [
|
||||
{ type: 'string' }
|
||||
]
|
||||
additionalProperties: false
|
||||
definitions: {}
|
||||
|
||||
MongoFindQuerySchema.definitions[MongoQueryOperatorSchema.id] = MongoQueryOperatorSchema
|
||||
|
||||
AchievementSchema =
|
||||
type: 'object'
|
||||
properties:
|
||||
name: c.shortString({title: 'Display Name'})
|
||||
query:
|
||||
#type: 'object'
|
||||
$ref: '#/definitions/' + MongoFindQuerySchema.id
|
||||
worth: { type: 'number' }
|
||||
collection: { type: 'string' }
|
||||
description: { type: 'string' }
|
||||
userField: { type: 'string' }
|
||||
related: c.objectId
|
||||
proportionalTo:
|
||||
type: 'string'
|
||||
description: 'For repeatables only. Denotes the field a repeatable achievement needs for its calculations'
|
||||
definitions: {}
|
||||
|
||||
AchievementSchema.definitions[MongoFindQuerySchema.id] = MongoFindQuerySchema
|
||||
|
||||
c.extendNamedProperties AchievementSchema
|
||||
c.extendBasicProperties AchievementSchema, 'article'
|
||||
c.extendSearchableProperties AchievementSchema
|
||||
|
||||
module.exports = AchievementSchema
|
||||
|
|
|
@ -17,7 +17,7 @@ me.shortString = (ext) -> combine({type: 'string', maxLength: 100}, ext)
|
|||
me.pct = (ext) -> combine({type: 'number', maximum: 1.0, minimum: 0.0}, ext)
|
||||
me.date = (ext) -> combine({type: ['object', 'string'], format: 'date-time'}, ext)
|
||||
# should just be string (Mongo ID), but sometimes mongoose turns them into objects representing those, so we are lenient
|
||||
me.objectId = (ext) -> schema = combine({type: ['object', 'string'] }, ext)
|
||||
me.objectId = (ext) -> schema = combine(['object', 'string'], ext)
|
||||
me.url = (ext) -> combine({type: 'string', format: 'url', pattern: urlPattern}, ext)
|
||||
|
||||
PointSchema = me.object {title: "Point", description: "An {x, y} coordinate point.", format: "point2d", required: ["x", "y"]},
|
||||
|
@ -48,7 +48,7 @@ me.colorConfig = (props) ->
|
|||
# BASICS
|
||||
|
||||
basicProps = (linkFragment) ->
|
||||
_id: me.objectId(links: [{rel: 'self', href: "/db/#{linkFragment}/{($)}"}], format: 'hidden')
|
||||
_id: me.objectId(links: [{rel: 'self', href: "/db/#{linkFragment}/{($)}"}], format:"hidden")
|
||||
__v: { title: 'Mongoose Version', format: 'hidden' }
|
||||
|
||||
me.extendBasicProperties = (schema, linkFragment) ->
|
||||
|
|
25
app/templates/editor/achievement/edit.jade
Normal file
25
app/templates/editor/achievement/edit.jade
Normal file
|
@ -0,0 +1,25 @@
|
|||
extends /templates/base
|
||||
|
||||
block content
|
||||
div
|
||||
ol.breadcrumb
|
||||
li
|
||||
a(href="/editor", data-i18n="editor.main_title") CodeCombat Editors
|
||||
li
|
||||
a(href="/editor/achievement", data-i18n="editor.achievement_title") Achievement Editor
|
||||
li.active
|
||||
| #{achievement.attributes.name}
|
||||
|
||||
button(data-i18n="common.save", disabled=authorized === true ? undefined : "true").btn.btn-primary#save-button Save
|
||||
|
||||
h3(data-i18n="achievement.edit_achievement_title") Edit Achievement
|
||||
span
|
||||
|: "#{achievement.attributes.name}"
|
||||
|
||||
#achievement-treema
|
||||
|
||||
#achievement-view
|
||||
|
||||
hr
|
||||
|
||||
div#error-view
|
64
app/views/editor/achievement/edit.coffee
Normal file
64
app/views/editor/achievement/edit.coffee
Normal file
|
@ -0,0 +1,64 @@
|
|||
View = require 'views/kinds/RootView'
|
||||
ErrorView = require '../../error_view'
|
||||
template = require 'templates/editor/achievement/edit'
|
||||
Achievement = require 'models/Achievement'
|
||||
|
||||
module.exports = class AchievementEditView extends View
|
||||
id: "editor-achievement-edit-view"
|
||||
template: template
|
||||
startsLoading: true
|
||||
|
||||
events:
|
||||
'click #save-button': 'openSaveModal'
|
||||
|
||||
subscriptions:
|
||||
'save-achievement': 'saveAchievement'
|
||||
|
||||
constructor: (options, @achievementID) ->
|
||||
super options
|
||||
@achievement = new Achievement(_id: @achievementID)
|
||||
@achievement.saveBackups = true
|
||||
|
||||
@listenToOnce(@achievement, 'error',
|
||||
() =>
|
||||
@hideLoading()
|
||||
$(@$el).find('.main-content-area').children('*').not('#error-view').remove()
|
||||
|
||||
@insertSubView(new ErrorView())
|
||||
)
|
||||
|
||||
@achievement.fetch()
|
||||
@listenToOnce(@achievement, 'sync', @buildTreema)
|
||||
@pushChangesToPreview = _.throttle(@pushChangesToPreview, 500)
|
||||
|
||||
buildTreema: ->
|
||||
return if @treema? or (not @achievement.loaded)
|
||||
|
||||
@startsLoading = false
|
||||
@render()
|
||||
data = $.extend(true, {}, @achievement.attributes)
|
||||
options =
|
||||
data: data
|
||||
#filePath: "db/thang.type/#{@article.get('original')}"
|
||||
schema: Achievement.schema
|
||||
readOnly: me.get('anonymous')
|
||||
callbacks:
|
||||
change: @pushChangesToPreview
|
||||
@treema = @$el.find('#achievement-treema').treema(options)
|
||||
|
||||
@treema.build()
|
||||
|
||||
pushChangesToPreview: =>
|
||||
'TODO'
|
||||
|
||||
getRenderData: (context={}) ->
|
||||
context = super(context)
|
||||
context.achievement = @achievement
|
||||
context.authorized = me.isAdmin()
|
||||
context
|
||||
|
||||
openSaveModal: ->
|
||||
'TODO'
|
||||
|
||||
saveAchievement: (e) ->
|
||||
'TODO'
|
|
@ -6,7 +6,7 @@ module.exports = class AchievementSearchView extends SearchView
|
|||
model: require 'models/Achievement'
|
||||
modelURL: '/db/achievement'
|
||||
tableTemplate: require 'templates/editor/achievement/table'
|
||||
projection: ['name', 'description', 'collection']
|
||||
projection: ['name', 'description', 'collection', 'slug']
|
||||
|
||||
getRenderData: ->
|
||||
context = super()
|
||||
|
|
Loading…
Reference in a new issue