mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-26 14:03:28 -04:00
Migrates Artisan helpers to their own directory and begins implementation of level tasks view
This commit is contained in:
parent
abe9d5c267
commit
0436f18279
13 changed files with 265 additions and 0 deletions
app
core
styles/artisans
templates/artisans
views/artisans
|
@ -43,6 +43,12 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
'admin/pending-patches': go('admin/PendingPatchesView')
|
||||
'admin/codelogs': go('admin/CodeLogsView')
|
||||
|
||||
'artisans': go('artisans/ArtisansView')
|
||||
|
||||
'artisans/level-analytics': go('artisans/LevelAnalyticsView')
|
||||
'artisans/level-tasks': go('artisans/LevelTasksView')
|
||||
'artisans/thang-tasks': go('artisans/ThangTasksView')
|
||||
|
||||
'beta': go('HomeView')
|
||||
|
||||
'careers': => window.location.href = 'https://jobs.lever.co/codecombat'
|
||||
|
|
6
app/styles/artisans/artisansView.sass
Normal file
6
app/styles/artisans/artisansView.sass
Normal file
|
@ -0,0 +1,6 @@
|
|||
#artisans-view
|
||||
text-align: center
|
||||
a
|
||||
font-size: xx-large
|
||||
img
|
||||
border-radius: 8px
|
1
app/styles/artisans/levelAnalyticsView.sass
Normal file
1
app/styles/artisans/levelAnalyticsView.sass
Normal file
|
@ -0,0 +1 @@
|
|||
#level-analytics-view
|
12
app/styles/artisans/levelTasksView.sass
Normal file
12
app/styles/artisans/levelTasksView.sass
Normal file
|
@ -0,0 +1,12 @@
|
|||
#level-tasks-view
|
||||
#levelTable
|
||||
width: 100%
|
||||
|
||||
.tasksTable
|
||||
width: 100%
|
||||
|
||||
.tasks
|
||||
width: 87.5%
|
||||
|
||||
.taskOwner
|
||||
width: 12.5%
|
12
app/styles/artisans/thangTasksView.sass
Normal file
12
app/styles/artisans/thangTasksView.sass
Normal file
|
@ -0,0 +1,12 @@
|
|||
#thang-tasks-view
|
||||
#thangTable
|
||||
width: 100%
|
||||
|
||||
.tasksTable
|
||||
width: 100%
|
||||
|
||||
.tasks
|
||||
width: 87.5%
|
||||
|
||||
.taskOwner
|
||||
width: 12.5%
|
10
app/templates/artisans/artisansView.jade
Normal file
10
app/templates/artisans/artisansView.jade
Normal file
|
@ -0,0 +1,10 @@
|
|||
extends /templates/base
|
||||
|
||||
block content
|
||||
img(src='/images/pages/user/artisan.png')
|
||||
div
|
||||
a(href='artisans/thang-tasks')
|
||||
|Thang Tasks
|
||||
div
|
||||
a(href="artisans/level-tasks")
|
||||
|Level Tasks
|
4
app/templates/artisans/levelAnalyticsView.jade
Normal file
4
app/templates/artisans/levelAnalyticsView.jade
Normal file
|
@ -0,0 +1,4 @@
|
|||
extends /templates/base
|
||||
|
||||
block content
|
||||
table#levelTable
|
34
app/templates/artisans/levelTasksView.jade
Normal file
34
app/templates/artisans/levelTasksView.jade
Normal file
|
@ -0,0 +1,34 @@
|
|||
extends /templates/base
|
||||
|
||||
block content
|
||||
#level-tasks-view
|
||||
div
|
||||
a(href='./')
|
||||
| < Artisans Home
|
||||
input#nameSearch(placeholder='Filter: Level Name')
|
||||
br
|
||||
input#descSearch(placeholder='Filter: Task Description')
|
||||
hr
|
||||
if view.processedLevels
|
||||
table.table.table-striped#levelTable
|
||||
tr
|
||||
th Level Name
|
||||
th Task List
|
||||
for level in view.processedLevels
|
||||
if view.hasIncompleteTasks(level)
|
||||
+levelRow(level)
|
||||
else
|
||||
div ole?
|
||||
|
||||
|
||||
|
||||
mixin levelRow(level)
|
||||
tr
|
||||
td.taskOwner
|
||||
a(href= 'level/' + level.slug)= level.name
|
||||
td.tasks
|
||||
table.table-striped.table-hover.tasksTable
|
||||
for task in (level.tasks2 || [])
|
||||
if !task.complete
|
||||
tr
|
||||
td= task.name
|
32
app/templates/artisans/thangTasksView.jade
Normal file
32
app/templates/artisans/thangTasksView.jade
Normal file
|
@ -0,0 +1,32 @@
|
|||
extends /templates/base
|
||||
|
||||
block content
|
||||
#thang-tasks-view
|
||||
div
|
||||
a(href='./')
|
||||
| < Artisans Home
|
||||
input#nameSearch(placeholder='Filter: Thang Name')
|
||||
br
|
||||
input#descSearch(placeholder='Filter: Task Description')
|
||||
hr
|
||||
if view.processedThangs
|
||||
table.table.table-striped#thangTable
|
||||
tr
|
||||
th Thang Name
|
||||
th Task List
|
||||
for thang in view.processedThangs
|
||||
if view.hasIncompleteTasks(thang)
|
||||
+thangRow(thang)
|
||||
else
|
||||
span No view.processedThangs
|
||||
|
||||
mixin thangRow(thang)
|
||||
tr
|
||||
td.taskOwner
|
||||
a(href= 'thang/' + thang.get('slug'))= thang.get('name')
|
||||
td.tasks
|
||||
table.table-striped.table-hover.tasksTable
|
||||
for task in (thang.tasks || [])
|
||||
if !task.complete
|
||||
tr
|
||||
td= task.name
|
8
app/views/artisans/ArtisansView.coffee
Normal file
8
app/views/artisans/ArtisansView.coffee
Normal file
|
@ -0,0 +1,8 @@
|
|||
RootView = require 'views/core/RootView'
|
||||
template = require 'templates/artisans/artisansView'
|
||||
|
||||
module.exports = class ArtisansView extends RootView
|
||||
template: template
|
||||
id: 'artisans-view'
|
||||
constructor: (options) ->
|
||||
super options
|
35
app/views/artisans/LevelAnalyticsView.coffee
Normal file
35
app/views/artisans/LevelAnalyticsView.coffee
Normal file
|
@ -0,0 +1,35 @@
|
|||
RootView = require 'views/core/RootView'
|
||||
template = require 'templates/artisans/levelAnalyticsView'
|
||||
Level = require 'models/Level'
|
||||
Campaign = require 'models/Campaign'
|
||||
CocoCollection = require 'collections/CocoCollection'
|
||||
|
||||
module.exports = class LevelAnalyticsView extends RootView
|
||||
template: template
|
||||
id: 'level-analytics-view'
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@campaigns = new CocoCollection([],
|
||||
url: '/db/campaign?project=name,slug,tasks'
|
||||
model: Campaign
|
||||
)
|
||||
@campaigns.fetch()
|
||||
@listenTo(@campaigns, 'sync', @onCampaignsLoaded)
|
||||
@supermodel.loadCollection(@campaigns, 'campaigns')
|
||||
onCampaignsLoaded: ->
|
||||
@levels = []
|
||||
for campaign in @campaigns.models
|
||||
continue unless campaign.get('slug') is 'dungeon'
|
||||
levels = campaign.get('levels')
|
||||
for key, level of levels
|
||||
@levels.push level.slug
|
||||
@stats = new CocoCollection([],
|
||||
url: '/db/analytics_perday/-/level_completions?slug=dungeons-of-kithgard&startDay=20151022&endDay=20151104'
|
||||
model: {}
|
||||
)
|
||||
@stats.fetch()
|
||||
@listenTo(@stats, 'sync', @onStatsLoaded)
|
||||
@supermodel.loadCollection(@stats, 'stats')
|
||||
@renderSelectors '#levelTable'
|
||||
onStatsLoaded: ->
|
||||
console.log @stats
|
57
app/views/artisans/LevelTasksView.coffee
Normal file
57
app/views/artisans/LevelTasksView.coffee
Normal file
|
@ -0,0 +1,57 @@
|
|||
RootView = require 'views/core/RootView'
|
||||
template = require 'templates/artisans/levelTasksView'
|
||||
#ThangType = require 'models/ThangType'
|
||||
Level = require 'models/Level'
|
||||
Campaign = require 'models/Campaign'
|
||||
CocoCollection = require 'collections/CocoCollection'
|
||||
|
||||
module.exports = class LevelTasksView extends RootView
|
||||
template: template
|
||||
id: 'level-tasks-view'
|
||||
events:
|
||||
'input input': 'searchUpdate'
|
||||
'change input': 'searchUpdate'
|
||||
excludedCampaigns = [
|
||||
"picoctf"
|
||||
"auditions"
|
||||
]
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@campaigns = new CocoCollection([],
|
||||
url: '/db/campaign?project=name,slug,tasks'
|
||||
model: Campaign
|
||||
)
|
||||
@campaigns.fetch()
|
||||
@listenTo(@campaigns, 'sync', @onCampaignsLoaded)
|
||||
@supermodel.loadCollection(@campaigns, 'campaigns')
|
||||
|
||||
onCampaignsLoaded: ->
|
||||
@levels = {}
|
||||
sum = 0
|
||||
for campaign in @campaigns.models
|
||||
continue unless excludedCampaigns.indexOf(campaign.get 'slug') is -1
|
||||
levels = campaign.get('levels')
|
||||
sum += Object.keys(levels).length
|
||||
for key, level of levels
|
||||
continue unless ///#{$('#nameSearch')[0].value}///i.test level.name
|
||||
levelSlug = level.slug
|
||||
@levels[levelSlug] = level
|
||||
@processedLevels = @levels
|
||||
for key, level of @processedLevels
|
||||
level.tasks2 = _.filter level.tasks, (_elem) ->
|
||||
return ///#{$('#descSearch')[0].value}///i.test _elem.name
|
||||
@renderSelectors '#levelTable'
|
||||
|
||||
searchUpdate: ->
|
||||
if not @lastLoad? or (new Date()).getTime() - @lastLoad > 60 * 1000 * 1 # Update only after a minute from last update.
|
||||
@campaigns.fetch()
|
||||
@listenTo(@campaigns, 'sync', @onCampaignsLoaded)
|
||||
@supermodel.loadCollection(@campaigns, 'campaigns')
|
||||
@lastLoad = (new Date()).getTime()
|
||||
else
|
||||
@onCampaignsLoaded()
|
||||
|
||||
|
||||
# Jade helper
|
||||
hasIncompleteTasks: (level) ->
|
||||
return level.tasks2 and level.tasks2.filter((_elem) -> return not _elem.complete).length > 0
|
48
app/views/artisans/ThangTasksView.coffee
Normal file
48
app/views/artisans/ThangTasksView.coffee
Normal file
|
@ -0,0 +1,48 @@
|
|||
RootView = require 'views/core/RootView'
|
||||
template = require 'templates/artisans/thangTasksView'
|
||||
ThangType = require 'models/ThangType'
|
||||
CocoCollection = require 'collections/CocoCollection'
|
||||
|
||||
module.exports = class ThangTasksView extends RootView
|
||||
template: template
|
||||
id: 'thang-tasks-view'
|
||||
events:
|
||||
'input input': 'searchUpdate'
|
||||
'change input': 'searchUpdate'
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@thangs = new CocoCollection([],
|
||||
url: '/db/thang.type?project=name,tasks,slug'
|
||||
model: ThangType
|
||||
comparator: @sortThangs
|
||||
)
|
||||
@lastLoad = (new Date()).getTime()
|
||||
@listenTo(@thangs, 'sync', @onThangsLoaded)
|
||||
@supermodel.loadCollection(@thangs, 'thangs')
|
||||
|
||||
searchUpdate: ->
|
||||
if not @lastLoad? or (new Date()).getTime() - @lastLoad > 60 * 1000 * 1 # Update only after a minute from last update.
|
||||
@thangs.fetch()
|
||||
@listenTo(@thangs, 'sync', @onThangsLoaded)
|
||||
@supermodel.loadCollection(@thangs, 'thangs')
|
||||
@lastLoad = (new Date()).getTime()
|
||||
else
|
||||
@onThangsLoaded()
|
||||
|
||||
onThangsLoaded: ->
|
||||
@processedThangs = @thangs.filter (_elem) ->
|
||||
# Case-insensitive search of input vs name.
|
||||
return ///#{$('#nameSearch')[0].value}///i.test _elem.get('name')
|
||||
for thang in @processedThangs
|
||||
thang.tasks = _.filter thang.attributes.tasks, (_elem) ->
|
||||
# Similar case-insensitive search of input vs description (name).
|
||||
return ///#{$('#descSearch')[0].value}///i.test _elem.name
|
||||
@renderSelectors '#thangTable'
|
||||
|
||||
sortThangs: (a, b) ->
|
||||
a.get('name').localeCompare(b.get('name'))
|
||||
|
||||
# Jade helper
|
||||
hasIncompleteTasks: (thang) ->
|
||||
return thang.tasks and thang.tasks.filter((_elem) -> return not _elem.complete).length > 0
|
Loading…
Add table
Add a link
Reference in a new issue