Allow items to be grouped on mod detail pages
This commit is contained in:
@@ -21,3 +21,24 @@ All rights reserved.
|
|||||||
.error { background: $color-error; }
|
.error { background: $color-error; }
|
||||||
|
|
||||||
.error-new { background: $color-error-new; }
|
.error-new { background: $color-error-new; }
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-top: 3em;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-family: $font-family-header;
|
||||||
|
font-size: $font-size-large;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
background: white;
|
||||||
|
padding: 1em;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
position: relative; width: 33%;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,70 @@
|
|||||||
|
###
|
||||||
|
Crafting Guide - item_group_controller.coffee
|
||||||
|
|
||||||
|
Copyright (c) 2015 by Redwood Labs
|
||||||
|
All rights reserved.
|
||||||
|
###
|
||||||
|
|
||||||
|
BaseController = require './base_controller'
|
||||||
|
{Duration} = require '../constants'
|
||||||
|
{Event} = require '../constants'
|
||||||
|
Item = require '../models/item'
|
||||||
|
ItemController = require './item_controller'
|
||||||
|
|
||||||
|
########################################################################################################################
|
||||||
|
|
||||||
|
module.exports = class ItemGroupController extends BaseController
|
||||||
|
|
||||||
|
constructor: (options={})->
|
||||||
|
if not options.model? then throw new Error 'options.model is required'
|
||||||
|
if not options.modPack? then throw new Error 'options.modPack is required'
|
||||||
|
if not options.modVersion? then throw new Error 'options.modVersion is required'
|
||||||
|
options.templateName = 'item_group'
|
||||||
|
super options
|
||||||
|
|
||||||
|
@modVersion = options.modVersion
|
||||||
|
@_modPack = options.modPack
|
||||||
|
@_itemControllers = []
|
||||||
|
|
||||||
|
@modVersion.on Event.change, => @refresh()
|
||||||
|
|
||||||
|
# BaseController Overrides #####################################################################
|
||||||
|
|
||||||
|
onDidRender: ->
|
||||||
|
@$title = @$('h2')
|
||||||
|
@$items = @$('.panel')
|
||||||
|
super
|
||||||
|
|
||||||
|
refresh: ->
|
||||||
|
@$title.html if @model is Item.Group.Other then 'Items' else @model
|
||||||
|
@_refreshItems()
|
||||||
|
super
|
||||||
|
|
||||||
|
# Private Methods ##############################################################################
|
||||||
|
|
||||||
|
_createItemController: (item)->
|
||||||
|
controller = new ItemController model:item, modPack:@_modPack
|
||||||
|
controller.$el.hide()
|
||||||
|
controller.render()
|
||||||
|
|
||||||
|
@_itemControllers.push controller
|
||||||
|
@$items.append controller.$el
|
||||||
|
controller.$el.slideDown duration:Duration.fast
|
||||||
|
|
||||||
|
_refreshItems: ->
|
||||||
|
controllerIndex = 0
|
||||||
|
delay = 0
|
||||||
|
|
||||||
|
@modVersion.eachItemInGroup @model, (item)=>
|
||||||
|
controller = @_itemControllers[controllerIndex]
|
||||||
|
if not controller?
|
||||||
|
_.delay (=> @_createItemController item), delay
|
||||||
|
delay += @_delayStep
|
||||||
|
else
|
||||||
|
controller.model = item
|
||||||
|
controller.refresh()
|
||||||
|
controllerIndex += 1
|
||||||
|
|
||||||
|
while @_itemControllers.length > controllerIndex
|
||||||
|
controller = @_itemControllers.pop()
|
||||||
|
controller.$el.slideUp duration:Duration.fast, complete:-> @remove()
|
||||||
@@ -5,12 +5,12 @@ Copyright (c) 2015 by Redwood Labs
|
|||||||
All rights reserved.
|
All rights reserved.
|
||||||
###
|
###
|
||||||
|
|
||||||
BaseController = require './base_controller'
|
BaseController = require './base_controller'
|
||||||
{Duration} = require '../constants'
|
{Duration} = require '../constants'
|
||||||
Mod = require '../models/mod'
|
Mod = require '../models/mod'
|
||||||
ModPack = require '../models/mod_pack'
|
ModPack = require '../models/mod_pack'
|
||||||
ItemController = require './item_controller'
|
ItemGroupController = require './item_group_controller'
|
||||||
{Url} = require '../constants'
|
{Url} = require '../constants'
|
||||||
|
|
||||||
########################################################################################################################
|
########################################################################################################################
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ module.exports = class ModPageController extends BaseController
|
|||||||
|
|
||||||
@_delayStep = options.delayStep
|
@_delayStep = options.delayStep
|
||||||
@_effectiveModVersion = null
|
@_effectiveModVersion = null
|
||||||
@_itemControllers = []
|
@_groupControllers = []
|
||||||
@_modPack = options.modPack
|
@_modPack = options.modPack
|
||||||
|
|
||||||
Object.defineProperties this,
|
Object.defineProperties this,
|
||||||
@@ -48,7 +48,7 @@ module.exports = class ModPageController extends BaseController
|
|||||||
@$documentationLink = @$('.documentation')
|
@$documentationLink = @$('.documentation')
|
||||||
@$downloadLink = @$('.download')
|
@$downloadLink = @$('.download')
|
||||||
@$homePageLink = @$('.homePage')
|
@$homePageLink = @$('.homePage')
|
||||||
@$items = @$('.items .panel')
|
@$groupContainer = @$('.itemGroups')
|
||||||
@$titleImage = @$('.titleImage img')
|
@$titleImage = @$('.titleImage img')
|
||||||
@$versionSelector = @$('select.version')
|
@$versionSelector = @$('select.version')
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ module.exports = class ModPageController extends BaseController
|
|||||||
@_refreshLink @$documentationLink, @model.documentationUrl
|
@_refreshLink @$documentationLink, @model.documentationUrl
|
||||||
@_refreshLink @$downloadLink, @model.downloadUrl
|
@_refreshLink @$downloadLink, @model.downloadUrl
|
||||||
|
|
||||||
@_refreshItems()
|
@_refreshItemGroups()
|
||||||
@_refreshVersions()
|
@_refreshVersions()
|
||||||
super
|
super
|
||||||
|
|
||||||
@@ -75,15 +75,6 @@ module.exports = class ModPageController extends BaseController
|
|||||||
|
|
||||||
# Private Methods ##############################################################################
|
# Private Methods ##############################################################################
|
||||||
|
|
||||||
_createItemController: (item)->
|
|
||||||
controller = new ItemController model:item, modPack:@_modPack
|
|
||||||
controller.$el.hide()
|
|
||||||
controller.render()
|
|
||||||
|
|
||||||
@_itemControllers.push controller
|
|
||||||
@$items.append controller.$el
|
|
||||||
controller.$el.fadeIn duration:Duration.fast
|
|
||||||
|
|
||||||
_getEffectiveModVersion: ->
|
_getEffectiveModVersion: ->
|
||||||
return @_effectiveModVersion if @_effectiveModVersion?
|
return @_effectiveModVersion if @_effectiveModVersion?
|
||||||
return null unless @model?
|
return null unless @model?
|
||||||
@@ -94,6 +85,26 @@ module.exports = class ModPageController extends BaseController
|
|||||||
|
|
||||||
return modVersion
|
return modVersion
|
||||||
|
|
||||||
|
_refreshItemGroups: ->
|
||||||
|
groupIndex = 0
|
||||||
|
modVersion = @effectiveModVersion
|
||||||
|
modVersion.eachGroup (group)=>
|
||||||
|
controller = @_groupControllers[groupIndex]
|
||||||
|
if not controller?
|
||||||
|
controller = new ItemGroupController model:group, modVersion:modVersion, modPack:@_modPack
|
||||||
|
controller.render()
|
||||||
|
@$groupContainer.append controller.$el
|
||||||
|
@_groupControllers[groupIndex] = controller
|
||||||
|
else
|
||||||
|
controller.modVersion = modVersion
|
||||||
|
controller.model = group
|
||||||
|
controller.refresh()
|
||||||
|
groupIndex++
|
||||||
|
|
||||||
|
while @_groupControllers.length > groupIndex + 1
|
||||||
|
controller = @_groupControllers.pop()
|
||||||
|
controller.$el.slideUp duration:Duration.fast, -> @remove()
|
||||||
|
|
||||||
_refreshLink: ($link, url)->
|
_refreshLink: ($link, url)->
|
||||||
if url?
|
if url?
|
||||||
$link.fadeIn duration:Duration.fast
|
$link.fadeIn duration:Duration.fast
|
||||||
@@ -101,28 +112,6 @@ module.exports = class ModPageController extends BaseController
|
|||||||
else
|
else
|
||||||
$link.fadeOut duration:Duration.fast
|
$link.fadeOut duration:Duration.fast
|
||||||
|
|
||||||
_refreshItems: ->
|
|
||||||
controllerIndex = 0
|
|
||||||
delay = 0
|
|
||||||
|
|
||||||
effectiveModVersion = @effectiveModVersion
|
|
||||||
if effectiveModVersion?
|
|
||||||
@$items.show duration:Duration.fast
|
|
||||||
effectiveModVersion.eachItem (item)=>
|
|
||||||
controller = @_itemControllers[controllerIndex]
|
|
||||||
if not controller?
|
|
||||||
_.delay (=> @_createItemController item), delay
|
|
||||||
delay += @_delayStep
|
|
||||||
else
|
|
||||||
controller.model = item
|
|
||||||
controllerIndex += 1
|
|
||||||
else
|
|
||||||
@$items.hide duration:Duration.fast
|
|
||||||
|
|
||||||
while @_itemControllers.length > controllerIndex
|
|
||||||
controller = @_itemControllers.pop()
|
|
||||||
controller.$el.slideUp duration:Duration.fast, complete:-> @remove()
|
|
||||||
|
|
||||||
_refreshVersions: ->
|
_refreshVersions: ->
|
||||||
@$versionSelector.empty()
|
@$versionSelector.empty()
|
||||||
return unless @model?
|
return unless @model?
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ global.logger = new Logger
|
|||||||
switch window.location.hostname
|
switch window.location.hostname
|
||||||
when 'localhost'
|
when 'localhost'
|
||||||
global.env = 'development'
|
global.env = 'development'
|
||||||
logger.level = Logger.INFO
|
logger.level = Logger.DEBUG
|
||||||
when 'new.crafting-guide.com'
|
when 'new.crafting-guide.com'
|
||||||
global.env = 'staging'
|
global.env = 'staging'
|
||||||
logger.level = Logger.VERBOSE
|
logger.level = Logger.VERBOSE
|
||||||
|
|||||||
@@ -14,9 +14,12 @@ Recipe = require './recipe'
|
|||||||
|
|
||||||
module.exports = class Item extends BaseModel
|
module.exports = class Item extends BaseModel
|
||||||
|
|
||||||
|
@Group = Other:'Other'
|
||||||
|
|
||||||
constructor: (attributes={}, options={})->
|
constructor: (attributes={}, options={})->
|
||||||
if not attributes.name? then throw new Error 'attributes.name is required'
|
if not attributes.name? then throw new Error 'attributes.name is required'
|
||||||
|
|
||||||
|
attributes.group ?= Item.Group.Other
|
||||||
attributes.isGatherable ?= false
|
attributes.isGatherable ?= false
|
||||||
attributes.slug ?= _.slugify attributes.name
|
attributes.slug ?= _.slugify attributes.name
|
||||||
options.logEvents ?= false
|
options.logEvents ?= false
|
||||||
|
|||||||
@@ -21,16 +21,20 @@ module.exports = class ModVersion extends BaseModel
|
|||||||
if not attributes.version? then throw new Error 'attributes.version is required'
|
if not attributes.version? then throw new Error 'attributes.version is required'
|
||||||
super attributes, options
|
super attributes, options
|
||||||
|
|
||||||
@_items = {}
|
@_groups = {}
|
||||||
@_names = {}
|
@_items = {}
|
||||||
@_slugs = []
|
@_names = {}
|
||||||
|
@_slugs = []
|
||||||
|
|
||||||
# Public Methods ###############################################################################
|
# Public Methods ###############################################################################
|
||||||
|
|
||||||
addItem: (item)->
|
addItem: (item)->
|
||||||
if @_items[item.slug]? then throw new Error "duplicate item for #{item.name}"
|
if @_items[item.slug]? then throw new Error "duplicate item for #{item.name}"
|
||||||
|
|
||||||
@_items[item.slug] = item
|
@_items[item.slug] = item
|
||||||
|
@_groups[item.group] ?= {}
|
||||||
|
@_groups[item.group][item.slug] = item
|
||||||
|
|
||||||
item.modVersion = this
|
item.modVersion = this
|
||||||
@registerSlug item.slug, item.name
|
@registerSlug item.slug, item.name
|
||||||
return this
|
return this
|
||||||
@@ -44,6 +48,10 @@ module.exports = class ModVersion extends BaseModel
|
|||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
eachGroup: (callback)->
|
||||||
|
for groupName in _.keys(@_groups).sort()
|
||||||
|
callback groupName
|
||||||
|
|
||||||
eachItem: (callback)->
|
eachItem: (callback)->
|
||||||
for slug in @_slugs
|
for slug in @_slugs
|
||||||
item = @_items[slug]
|
item = @_items[slug]
|
||||||
@@ -51,6 +59,13 @@ module.exports = class ModVersion extends BaseModel
|
|||||||
callback @_items[slug], slug
|
callback @_items[slug], slug
|
||||||
return this
|
return this
|
||||||
|
|
||||||
|
eachItemInGroup: (group, callback)->
|
||||||
|
group = @_groups[group]
|
||||||
|
return unless group?
|
||||||
|
|
||||||
|
for slug in _.keys(group).sort()
|
||||||
|
callback group[slug]
|
||||||
|
|
||||||
eachName: (callback)->
|
eachName: (callback)->
|
||||||
for slug in @_slugs
|
for slug in @_slugs
|
||||||
callback @_names[slug], slug
|
callback @_names[slug], slug
|
||||||
|
|||||||
@@ -53,10 +53,14 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
|
|||||||
|
|
||||||
@_itemData.gatherable = (gatherable is 'yes')
|
@_itemData.gatherable = (gatherable is 'yes')
|
||||||
|
|
||||||
|
_command_group: (group)->
|
||||||
|
if group.length is 0 then throw new Error 'a group name cannot be empty'
|
||||||
|
@_rawData.group = group
|
||||||
|
|
||||||
_command_item: (name='')->
|
_command_item: (name='')->
|
||||||
if not name.length > 0 then throw new Error 'the item name cannot be empty'
|
if not name.length > 0 then throw new Error 'the item name cannot be empty'
|
||||||
|
|
||||||
@_itemData = name:name, line:@_lineNumber
|
@_itemData = name:name, line:@_lineNumber, group:@_rawData.group
|
||||||
@_rawData.items ?= []
|
@_rawData.items ?= []
|
||||||
@_rawData.items.push @_itemData
|
@_rawData.items.push @_itemData
|
||||||
|
|
||||||
@@ -118,7 +122,7 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
|
|||||||
itemData.gatherable ?= false
|
itemData.gatherable ?= false
|
||||||
itemData.recipes ?= []
|
itemData.recipes ?= []
|
||||||
|
|
||||||
item = new Item name:itemData.name, isGatherable:itemData.gatherable
|
item = new Item name:itemData.name, isGatherable:itemData.gatherable, group:itemData.group
|
||||||
modVersion.addItem item
|
modVersion.addItem item
|
||||||
|
|
||||||
for recipeData in itemData.recipes
|
for recipeData in itemData.recipes
|
||||||
@@ -186,9 +190,23 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
|
|||||||
builder
|
builder
|
||||||
.line 'schema: ', 1
|
.line 'schema: ', 1
|
||||||
.line()
|
.line()
|
||||||
.onlyIf itemList.length > 0, =>
|
|
||||||
builder.loop itemList, delimiter:'\n', onEach:(b, i)=> @_unparseItem(b, i)
|
modVersion.eachGroup (group)=>
|
||||||
.outdent()
|
@_unparseGroup builder, modVersion, group
|
||||||
|
|
||||||
|
_unparseGroup: (builder, modVersion, group)->
|
||||||
|
if group isnt Item.Group.Other
|
||||||
|
builder
|
||||||
|
.line 'group: ', group
|
||||||
|
.line()
|
||||||
|
.indent()
|
||||||
|
|
||||||
|
modVersion.eachItemInGroup group, (item)=>
|
||||||
|
@_unparseItem builder, item
|
||||||
|
builder.line()
|
||||||
|
|
||||||
|
if group isnt Item.Group.Other
|
||||||
|
builder.outdent()
|
||||||
|
|
||||||
_unparseItem: (builder, item)->
|
_unparseItem: (builder, item)->
|
||||||
recipes = []
|
recipes = []
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
//-
|
||||||
|
//- Crafting Guide - item_group.jade
|
||||||
|
//-
|
||||||
|
//- Copyright (c) 2015 by Redwood Labs
|
||||||
|
//- All rights reserved.
|
||||||
|
//-
|
||||||
|
|
||||||
|
.view__item_group.section
|
||||||
|
h2
|
||||||
|
.panel
|
||||||
@@ -18,6 +18,4 @@
|
|||||||
.byline: p
|
.byline: p
|
||||||
.description: p
|
.description: p
|
||||||
|
|
||||||
.section.items
|
.itemGroups
|
||||||
h2 Items
|
|
||||||
.panel
|
|
||||||
|
|||||||
@@ -16,7 +16,13 @@ modVersion = null
|
|||||||
|
|
||||||
describe 'mod_version.coffee', ->
|
describe 'mod_version.coffee', ->
|
||||||
|
|
||||||
beforeEach -> modVersion = new ModVersion modSlug:'test', version:'0.0'
|
beforeEach ->
|
||||||
|
modVersion = new ModVersion modSlug:'test', version:'0.0'
|
||||||
|
modVersion.addItem new Item name:'underscore', group:'punctuation'
|
||||||
|
modVersion.addItem new Item name:'bravo', group:'letter'
|
||||||
|
modVersion.addItem new Item name:'alpha', group:'letter'
|
||||||
|
modVersion.addItem new Item name:'one', group:'number'
|
||||||
|
modVersion.addItem new Item name:'two', group:'number'
|
||||||
|
|
||||||
describe 'constructor', ->
|
describe 'constructor', ->
|
||||||
|
|
||||||
@@ -40,6 +46,30 @@ describe 'mod_version.coffee', ->
|
|||||||
modVersion.addItem new Item name:'Wool'
|
modVersion.addItem new Item name:'Wool'
|
||||||
modVersion._items.wool.modVersion.should.equal modVersion
|
modVersion._items.wool.modVersion.should.equal modVersion
|
||||||
|
|
||||||
|
describe 'eachGroup', ->
|
||||||
|
|
||||||
|
it 'returns all the groups in order', ->
|
||||||
|
groupNames = []
|
||||||
|
modVersion.eachGroup (groupName)-> groupNames.push groupName
|
||||||
|
groupNames.should.eql ['letter', 'number', 'punctuation']
|
||||||
|
|
||||||
|
describe 'eachItemInGroup', ->
|
||||||
|
|
||||||
|
it 'returns immediately for unknown group', ->
|
||||||
|
slugs = []
|
||||||
|
modVersion.eachItemInGroup 'foobar', (item)-> slugs.push item.slug
|
||||||
|
slugs.should.eql []
|
||||||
|
|
||||||
|
it 'calls callback for exactly the items in a group in order', ->
|
||||||
|
slugs = []
|
||||||
|
modVersion.eachItemInGroup 'letter', (item)-> slugs.push item.slug
|
||||||
|
slugs.should.eql ['alpha', 'bravo']
|
||||||
|
|
||||||
|
slugs = []
|
||||||
|
modVersion.eachItemInGroup 'number', (item)-> slugs.push item.slug
|
||||||
|
slugs.should.eql ['one', 'two']
|
||||||
|
|
||||||
|
|
||||||
describe 'findItemByName', ->
|
describe 'findItemByName', ->
|
||||||
|
|
||||||
it 'locates items by slugified name', ->
|
it 'locates items by slugified name', ->
|
||||||
|
|||||||
Reference in New Issue
Block a user