From 7dff4fa402bc76ef0d353c383390147eb20b79d1 Mon Sep 17 00:00:00 2001 From: rolux Date: Sun, 6 Nov 2011 09:28:10 +0100 Subject: [PATCH] rename groups to filters --- pandora/0xdb.jsonc | 44 ++-- static/js/pandora/Query.js | 306 ---------------------------- static/js/pandora/UI.js | 10 +- static/js/pandora/URL.js | 4 +- static/js/pandora/browser.js | 20 +- static/js/pandora/contentPanel.js | 8 +- static/js/pandora/filter.js | 297 ++++++++++++++++++++++----- static/js/pandora/filterDialog.js | 4 +- static/js/pandora/filterForm.js | 61 ++++++ static/js/pandora/group.js | 252 ----------------------- static/js/pandora/mainPanel.js | 14 +- static/js/pandora/menu.js | 93 +++++---- static/js/pandora/navigationView.js | 4 +- static/js/pandora/rightPanel.js | 2 +- static/js/pandora/utils.js | 156 +++++++------- 15 files changed, 486 insertions(+), 789 deletions(-) delete mode 100644 static/js/pandora/Query.js create mode 100644 static/js/pandora/filterForm.js delete mode 100644 static/js/pandora/group.js diff --git a/pandora/0xdb.jsonc b/pandora/0xdb.jsonc index 715da10f..3b269e13 100644 --- a/pandora/0xdb.jsonc +++ b/pandora/0xdb.jsonc @@ -39,8 +39,8 @@ {"id": "lightness", "title": "Lightness", "type": "float"}, {"id": "volume", "title": "Volume", "type": "float"} ], - // fixme: either this, or group: true in itemKeys, but not both - "groups": [ + // fixme: either this, or filter: true in itemKeys, but not both + "filters": [ {"id": "director", "title": "Director", "type": "string"}, {"id": "country", "title": "Country", "type": "string"}, {"id": "year", "title": "Year", "type": "integer"}, @@ -65,9 +65,9 @@ columnRequired: If true, the column can't be removed columnWidth: Default column width in px find: If true, will appear as a find option + filter: if true, one can filter results by this key format: {type: "...", args: [...]}, for special formatting (Ox.formatType(args) will be called) - group: if true, one can group results by this key sort: special sort rule (title, person) sortOperator: sort operator (+, -), in case it differs from the default for the key's type (+ for strings, - for numbers) @@ -99,8 +99,8 @@ "autocomplete": true, "columnRequired": true, "columnWidth": 180, + "filter": true, "find": true, - "group": true, "sort": "person" }, { @@ -109,8 +109,8 @@ "type": ["string"], "autocomplete": true, "columnWidth": 120, - "find": true, - "group": true + "filter": true, + "find": true }, { "id": "year", @@ -118,8 +118,8 @@ "type": "year", // fixme: do we need this? "autocomplete": true, "columnWidth": 60, - "find": true, - "group": true + "filter": true, + "find": true }, { "id": "language", @@ -128,7 +128,7 @@ "autocomplete": true, "columnWidth": 120, "find": true, - "group": true + "filter": true }, { "id": "runtime", @@ -143,8 +143,8 @@ "type": ["string"], "autocomplete": true, "columnWidth": 180, + "filter": true, "find": true, - "group": true, "sort": "person" }, { @@ -153,8 +153,8 @@ "type": ["string"], "autocomplete": true, "columnWidth": 180, + "filter": true, "find": true, - "group": true, "sort": "person" }, { @@ -163,8 +163,8 @@ "type": ["string"], "autocomplete": true, "columnWidth": 180, + "filter": true, "find": true, - "group": true, "sort": "person" }, { @@ -173,8 +173,8 @@ "type": ["string"], "autocomplete": true, "columnWidth": 180, + "filter": true, "find": true, - "group": true, "sort": "person" }, { @@ -182,8 +182,8 @@ "title": "Actor", "type": ["string"], "autocomplete": true, + "filter": true, "find": true, - "group": true, "sort": "person" }, { @@ -214,16 +214,16 @@ "type": ["string"], "autocomplete": true, "columnWidth": 120, - "find": true, - "group": true + "filter": true, + "find": true }, { "id": "keyword", "title": "Keyword", "type": ["string"], "autocomplete": true, - "find": true, - "group": true + "filter": true, + "find": true }, { "id": "summary", @@ -589,15 +589,15 @@ "columnWidth": {} } }, - "find": {"conditions": [], "operator": "&"}, - "groups": [ + "filters": [ {"id": "director", "sort": [{"key": "items", "operator": "-"}]}, {"id": "country", "sort": [{"key": "items", "operator": "-"}]}, {"id": "year", "sort": [{"key": "name", "operator": "-"}]}, {"id": "language", "sort": [{"key": "items", "operator": "-"}]}, {"id": "genre", "sort": [{"key": "items", "operator": "-"}]} ], - "groupsSize": 176, + "filtersSize": 176, + "find": {"conditions": [], "operator": "&"}, "icons": "posters", "infoIconSize": 256, "item": "", @@ -616,8 +616,8 @@ "showAnnotations": true, "showBrowser": true, "showCalendarControls": true, // fixme: should be false + "showFilters": true, "showFlags": true, - "showGroups": true, "showHome": true, "showIconBrowser": false, "showInfo": true, diff --git a/static/js/pandora/Query.js b/static/js/pandora/Query.js deleted file mode 100644 index 1751ff3e..00000000 --- a/static/js/pandora/Query.js +++ /dev/null @@ -1,306 +0,0 @@ -// vim: et:ts=4:sw=4:sts=4:ft=javascript - -'use strict'; - -// FIXME: remove this - -pandora.Query = (function() { - - function constructFind(query) { - return /*encodeURI(*/query.conditions.map(function(condition) { - var ret; - if (condition.conditions) { - ret = '[' + constructFind(condition) + ']'; - } else { - ret = condition.value !== '' - ? condition.key + (condition.key ? ':' : '') - + constructValue(condition.value, condition.operator) - : null; - } - return ret; - }).join(query.operator == '&' ? ',' : '|')/*)*/; - } - - function constructValue(value, operator) { - value = encodeURIComponent(value); - operator = operator.replace('=', '^$'); - if (operator.indexOf('$') > -1) { - value = operator.substr(0, operator.length - 1) + value + '$'; - } else { - value = operator + value; - } - return value; - } - - function everyCondition(conditions, key, operator) { - // if every condition has the given key and operator - // (excluding conditions where all subconditions match) - // returns true, otherwise false - return Ox.every(conditions, function(condition) { - return condition.key == key && condition.operator == operator; - }); - } - - function getGroupsData(fullQuery) { - // a group is selected if exactly one condition in an & query - // or every condition in an | query - // has the group id as key and "=" as operator - return pandora.user.ui.groups.map(function(group) { - var index = -1, - key = group.id, - query = Ox.clone(fullQuery, true), - selected = []; - if (query.operator == '|') { - if (everyCondition(query.conditions, key, '=')) { - index = Ox.range(query.conditions.length); - selected = query.conditions.map(function(condition) { - return condition.value; - }); - } - } else { - index = oneCondition(query.conditions, key, '='); - if (index > -1) { - selected = query.conditions[index].conditions - ? query.conditions[index].conditions.map(function(condition) { - return condition.value; - }) - : [query.conditions[index].value]; - } - } - if (selected.length) { - if (Ox.isArray(index)) { - query = {conditions: [], operator: ''}; - } else { - query.conditions.splice(index, 1); - if (query.conditions.length == 1) { - if (query.conditions[0].conditions) { - // unwrap single remaining bracketed query - query = { - conditions: query.conditions[0].conditions, - operator: query.conditions[0].operator - } - } else { - query.operator = ''; - } - } - } - } - return { - index: index, - query: query, - selected: selected - }; - }); - } - - function parseFind(str) { - // takes a find query string, returns useful information about the application's state - // (selected lists, find input key/value (and index of the corresponding condition), query object) - var conditions, - index, indices, - ret = { - find: {index: -1, key: '', value: ''}, - groups: [], // {index, query, selected} - list: '', - query: {conditions: [], operator: '&'} - }, - subconditions = []; - if (str.length) { - // replace subconditions with placeholder, - // so we can later split by main operator - var counter = 0; - Ox.forEach(str, function(c, i) { - if (c == ']') { - counter--; - } - if (counter >= 1) { - subconditions[subconditions.length - 1] += c; - } - if (c == '[') { - (++counter == 1) && subconditions.push(''); - } - }); - subconditions.forEach(function(subcondition, i) { - str = str.replace(subcondition, i); - }); - if (str.indexOf(',') > -1) { - ret.query.operator = '&'; - } else if (str.indexOf('|') > -1) { - ret.query.operator = '|'; - } - ret.query.conditions = ( - ret.query.operator == '' ? [str] : str.split(ret.query.operator == '&' ? ',' : '|') - ).map(function(condition, i) { - var kv, ret; - if (condition[0] == '[') { - // re-insert subcondition - ret = parseFind(subconditions[parseInt(Ox.sub(condition, 1, -1))]).query; - } else { - kv = ((condition.indexOf(':') > -1 ? '' : ':') + condition).split(':'); - ret = Ox.extend({key: kv[0]}, parseValue(kv[1])); - } - return ret; - }); - // a list is selected if exactly one condition in an & query - // has "list" as key and "" as operator - if (ret.query.operator != '|') { - index = oneCondition(ret.query.conditions, 'list', ''); - if (index > -1 && !ret.query.conditions[index].conditions) { - ret.list = ret.query.conditions[index].value; - } - } - ret.groups = getGroupsData(ret.query); - // find is populated if exactly one condition in an & query - // has a findKey as key and "" as operator - // (and all other conditions are either list or groups) - // or if all conditions in an | query have the same group id as key - if (ret.query.operator == '|') { - ret.find = {index: -1, key: 'advanced', value: ''}; - Ox.map(pandora.user.ui.groups, function(key) { - if (everyCondition(ret.query.conditions, key, '=')) { - ret.find.key = ''; - return false; - } - }); - } else { - // number of conditions that are not list or groups - conditions = ret.query.conditions.length - - (ret.list != '') - - ret.groups.filter(function(group) { - return group.index > -1; - }).length; - // indices of non-advanced find queries - indices = Ox.map(pandora.site.findKeys, function(findKey) { - var key = findKey.id == 'all' ? '' : findKey.id, - index = oneCondition(ret.query.conditions, key, ''); - return index > -1 ? index : null; - }); - if (conditions > 0 || indices.length > 0) { - ret.find = ( - conditions == 1 && indices.length == 1 - && !ret.query.conditions[indices[0]].conditions - ) ? { - index: indices[0], - key: ret.query.conditions[indices[0]].key, - value: decodeURIComponent(ret.query.conditions[indices[0]].value) - } : {index: -1, key: 'advanced', value: ''} - } - } - } - return ret; - } - - function oneCondition(conditions, key, operator) { - // if exactly one condition has the given key and operator - // (including conditions where all subconditions match) - // returns the corresponding index, otherwise returns -1 - var indices = Ox.map(conditions, function(condition, i) { - return ( - condition.conditions - ? everyCondition(condition.conditions, key, operator) - : condition.key == key && condition.operator == operator - ) ? i : null; - }); - return indices.length == 1 ? indices[0] : -1; - } - - function parseValue(str) { - var value = { - value: decodeURI(str), - operator: '' - }; - if (value.value[0] == '!') { - value.operator = '!'; - value.value = value.value.substr(1); - } - if ('^<>'.indexOf(value.value[0]) > -1) { - value.operator += value.value[0]; - value.value = value.value.substr(1); - } - if (value.value.substr(-1) == '$') { - value.operator += '$'; - value.value = value.value.substr(0, value.value.length - 1); - } - value.operator = value.operator.replace('^$', '='); - return value; - } - - return { - - fromString: function(str) { - var query = Ox.unserialize(str), - data = parseFind(query.find || ''); - Ox.Log('', Ox.repeat('-', 120)); - Ox.Log('', 'STATE', data); - Ox.Log('', Ox.repeat('-', 120)); - pandora.UI.set({list: data.list}); - !pandora.user.ui.lists[data.list] && pandora.UI.set( - 'lists|' + data.list, pandora.site.user.ui.lists[''] - ); - pandora.user.ui.find = data.find; - pandora.user.ui.groupsData = data.groups; - pandora.user.ui.query = data.query; - if ('sort' in query) { - pandora.UI.set('lists|' + pandora.user.ui.list + '|sort', query.sort.split(',').map(function(v) { - var hasOperator = '+-'.indexOf(v[0]) > -1, - key = hasOperator ? v.substr(1) : v, - operator = hasOperator ? v[0]/*.replace('+', '')*/ : pandora.getSortOperator(key); - return { - key: key, - operator: operator - }; - })); - } - /* - if ('view' in query) { - pandora.UI.set(['lists', pandora.user.ui.list, 'listView'].join('|'), query.view); - } - */ - }, - - /* - toObject: function(groupId) { - //Ox.Log('', 'tO', pandora.user.ui.findQuery.conditions) - // the inner $.merge() creates a clone - var conditions = $.merge( - $.merge([], pandora.user.ui.listQuery.conditions), - pandora.user.ui.findQuery.conditions - ), - operator; - $.merge(conditions, pandora.user.queryGroups ? $.map(pandora.user.queryGroups, function(v, i) { - if (v.id != groupId && v.query.conditions.length) { - return v.query.conditions.length == 1 ? - v.query.conditions : v.query; - } - }) : []); - operator = conditions.length < 2 ? '' : ','; // fixme: should be & - //Ox.Log('', '>>', groupId, pandora.user.ui.find, conditions); - return { - conditions: conditions, - operator: operator - }; - }, - */ - - toString: function() { - //Ox.Log('', 'tS', pandora.user.ui.find) - if (!pandora.user.ui.item) { - var sort = pandora.user.ui.lists[pandora.user.ui.list].sort[0], - key = sort.key, - operator = sort.operator; - return pandora.user.ui.lists[pandora.user.ui.list].listView + '/?' + Ox.serialize({ - find: constructFind(pandora.user.ui.query), - sort: (operator == pandora.getSortOperator(key) ? '' : operator) + key - }); - } else { - return pandora.user.ui.item + '/' + pandora.user.ui.itemView; - } - }, - - updateGroups: function() { - pandora.user.ui.groupsData = getGroupsData(pandora.user.ui.query); - } - - }; - -})(); diff --git a/static/js/pandora/UI.js b/static/js/pandora/UI.js index f3f53a55..2fb51a3d 100644 --- a/static/js/pandora/UI.js +++ b/static/js/pandora/UI.js @@ -16,8 +16,8 @@ pandora.UI = (function() { that.reset = function() { pandora.user.ui = pandora.site.user.ui; - pandora.user.ui._list = pandora.getListsState(pandora.user.ui.find); - pandora.user.ui._groupsState = pandora.getGroupsState(pandora.user.ui.find); + pandora.user.ui._list = pandora.getListState(pandora.user.ui.find); + pandora.user.ui._filterState = pandora.getFilterState(pandora.user.ui.find); pandora.user.ui._findState = pandora.getFindState(pandora.user.ui.find); }; @@ -46,16 +46,16 @@ pandora.UI = (function() { Ox.Log('UI', 'SET', args) self.previousUI = Ox.clone(pandora.user.ui, true); - self.previousUI._list = pandora.getListsState(self.previousUI.find); + self.previousUI._list = pandora.getListState(self.previousUI.find); if ('find' in args) { // the challenge here is that find may change list, // and list may then change listSort and listView, // which we don't want to trigger, since find triggers // (values we put in add will be changed, but won't trigger) - list = pandora.getListsState(args.find); + list = pandora.getListState(args.find); pandora.user.ui._list = list; - pandora.user.ui._groupsState = pandora.getGroupsState(args.find); + pandora.user.ui._filterState = pandora.getFilterState(args.find); pandora.user.ui._findState = pandora.getFindState(args.find); if (pandora.$ui.appPanel) { // if we're not on page load, diff --git a/static/js/pandora/URL.js b/static/js/pandora/URL.js index 6f2ed3e2..b9955251 100644 --- a/static/js/pandora/URL.js +++ b/static/js/pandora/URL.js @@ -53,8 +53,8 @@ pandora.URL = (function() { function setState(state, callback) { - pandora.user.ui._list = pandora.getListsState(pandora.user.ui.find); - pandora.user.ui._groupsState = pandora.getGroupsState(pandora.user.ui.find); + pandora.user.ui._list = pandora.getListState(pandora.user.ui.find); + pandora.user.ui._filterState = pandora.getFilterState(pandora.user.ui.find); pandora.user.ui._findState = pandora.getFindState(pandora.user.ui.find); if (Ox.isEmpty(state)) { diff --git a/static/js/pandora/browser.js b/static/js/pandora/browser.js index de9628ec..415b7c93 100644 --- a/static/js/pandora/browser.js +++ b/static/js/pandora/browser.js @@ -3,20 +3,20 @@ pandora.ui.browser = function() { var that; if (!pandora.user.ui.item) { - pandora.user.ui.groupsSizes = pandora.getGroupsSizes(); - pandora.$ui.groups = pandora.ui.groups(); + pandora.user.ui.filterSizes = pandora.getFilterSizes(); + pandora.$ui.filters = pandora.ui.filters(); that = Ox.SplitPanel({ elements: [ { - element: pandora.$ui.groups[0], - size: pandora.user.ui.groupsSizes[0] + element: pandora.$ui.filters[0], + size: pandora.user.ui.filterSizes[0] }, { - element: pandora.$ui.groupsInnerPanel = pandora.ui.groupsInnerPanel() + element: pandora.$ui.filtersInnerPanel = pandora.ui.filtersInnerPanel() }, { - element: pandora.$ui.groups[4], - size: pandora.user.ui.groupsSizes[4] + element: pandora.$ui.filters[4], + size: pandora.user.ui.filterSizes[4] }, ], id: 'browser', @@ -24,7 +24,7 @@ pandora.ui.browser = function() { }) .bindEvent({ resize: function(data) { - pandora.$ui.groups.forEach(function(list) { + pandora.$ui.filters.forEach(function(list) { list.size(); }); if (pandora.user.ui.listView == 'map') { @@ -34,11 +34,11 @@ pandora.ui.browser = function() { } }, resizeend: function(data) { - pandora.UI.set({groupsSize: data.size}); + pandora.UI.set({filtersSize: data.size}); }, toggle: function(data) { data.collapsed && pandora.$ui.list.gainFocus(); - pandora.UI.set({showGroups: !data.collapsed}); + pandora.UI.set({showFilters: !data.collapsed}); if (pandora.user.ui.listView == 'map') { pandora.$ui.map.resizeMap(); } else if (pandora.user.ui.listView == 'calendar') { diff --git a/static/js/pandora/contentPanel.js b/static/js/pandora/contentPanel.js index 56a8f7bc..504dfee3 100644 --- a/static/js/pandora/contentPanel.js +++ b/static/js/pandora/contentPanel.js @@ -4,13 +4,13 @@ pandora.ui.contentPanel = function() { var that = Ox.SplitPanel({ elements: !pandora.user.ui.item ? [ { - collapsed: !pandora.user.ui.showGroups, + collapsed: !pandora.user.ui.showFilters, collapsible: true, element: pandora.$ui.browser = pandora.ui.browser(), resizable: true, resize: [96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], - size: pandora.user.ui.groupsSize, - tooltip: 'groups' + size: pandora.user.ui.filtersSize, + tooltip: 'filters' }, { element: pandora.$ui.list = pandora.ui.list() @@ -44,7 +44,7 @@ pandora.ui.contentPanel = function() { pandora_showbrowser: function(data) { data.value == that.options('elements')[0].collapsed && that.toggle(0); }, - pandora_showgroups: function(data) { + pandora_showfilters: function(data) { data.value == that.options('elements')[0].collapsed && that.toggle(0); } }); diff --git a/static/js/pandora/filter.js b/static/js/pandora/filter.js index d49751fa..95223dd6 100644 --- a/static/js/pandora/filter.js +++ b/static/js/pandora/filter.js @@ -1,61 +1,252 @@ // vim: et:ts=4:sw=4:sts=4:ft=javascript - 'use strict'; - -pandora.ui.filter = function(list) { - var that = Ox.Filter({ - findKeys: Ox.merge(Ox.map(pandora.site.itemKeys, function(key) { - return { - autocomplete: key.autocomplete, - autocompleteSortKey: key.autocompleteSortKey, - format: key.format, - id: key.id, - title: key.title, - type: key.type == 'layer' - ? Ox.getObjectById(pandora.site.layers, key.id).type - : key.type - }; - }), { - id: 'list', - title: 'List', - type: 'list' - }), - list: list ? null : { - sort: pandora.user.ui.listSort, - view: pandora.user.ui.listView - }, - query: list ? list.query : pandora.user.ui.find, - sortKeys: pandora.site.sortKeys, - viewKeys: pandora.site.listViews - }) - .css({padding: '16px'}) - .bindEvent({ - change: function(data) { - if (list) { - pandora.api.editList({ - id: list.id, - query: data.query - }, function(result) { - Ox.Request.clearCache(list.id); - pandora.$ui.list - .bindEventOnce({ - init: function(data) { - pandora.$ui.folderList[ - pandora.getListData().folder - ].value(list.id, 'items', data.items); - } - }) - .reloadList(); - pandora.$ui.groups.forEach(function($group) { - $group.reloadList(); - }); - }); - } else { - pandora.UI.set({find: data.query}); - //pandora.URL.replace(); +pandora.ui.filter = function(id) { + var i = Ox.getPositionById(pandora.user.ui.filters, id), + filter = Ox.getObjectById(pandora.site.filters, id), + panelWidth = pandora.$ui.document.width() - (pandora.user.ui.showSidebar * pandora.user.ui.sidebarSize) - 1, + title = Ox.getObjectById(pandora.site.filters, id).title, + //width = pandora.getFilterWidth(i, panelWidth), + that = Ox.TextList({ + columns: [ + { + align: 'left', + id: 'name', + format: function(value) { + return ['country', 'language'].indexOf(id) > -1 && pandora.user.ui.showFlags + ? $('
') + .append( + $('') + .attr({src: Ox[ + id == 'country' ? 'getImageByGeoname' : 'getImageByLanguage' + ]('icon', 16, value)}) + .css({ + float: 'left', + width: '14px', + height: '14px', + margin: '0 3px 0 -2px', + borderRadius: '4px' + }) + ) + .append( + $('
') + .addClass('flagname') + .css({ + float: 'left', + width: pandora.user.ui.filterSizes[i] - 64 - Ox.UI.SCROLLBAR_SIZE, + textOverflow: 'ellipsis', + overflowX: 'hidden' + }) + .html(value) + ) + : value + }, + operator: filter.type == 'string' ? '+' : '-', + title: title, + unique: true, + visible: true, + width: pandora.user.ui.filterSizes[i] - 40 - Ox.UI.SCROLLBAR_SIZE + }, + { + align: 'right', + id: 'items', + operator: '-', + title: '#', + visible: true, + width: 40 } + ], + columnsVisible: true, + id: 'filter_' + id, + items: function(data, callback) { + //if (pandora.user.ui.showFilters) { + delete data.keys; + return pandora.api.find(Ox.extend(data, { + group: id, + query: pandora.user.ui._filterState[i].find + }), callback); + //} else { + // callback({data: {items: data.keys ? [] : 0}}); + //} + }, + scrollbarVisible: true, + selected: pandora.user.ui._filterState[i].selected, + sort: [{ + key: pandora.user.ui.filters[i].sort[0].key, + operator: pandora.user.ui.filters[i].sort[0].operator + }] + }) + .bindEvent({ + paste: function(data) { + pandora.$ui.list.triggerEvent('paste', data); + }, + select: function(data) { + // fixme: cant index be an empty array, instead of -1? + // FIXME: this is still incorrect when deselecting a filter item + // makes a selected item in another filter disappear + var conditions = data.ids.map(function(value) { + return { + key: id, + value: value, + operator: '==' + }; + }), + index = pandora.user.ui._filterState[i].index, + find = Ox.clone(pandora.user.ui.find, true); + if (Ox.isArray(index)) { + // this filter had multiple selections and the | query + // was on the top level, i.e. not bracketed + find = { + conditions: conditions, + operator: conditions.length > 1 ? '|' : '&' + } + } else { + if (index == -1) { + // this filter had no selection, i.e. no query + index = find.conditions.length; + if (find.operator == '|') { + find = { + conditions: [find], + operator: '&' + }; + index = 1; + } else { + find.operator = '&'; + } + } + if (conditions.length == 0) { + // nothing selected + find.conditions.splice(index, 1); + if (find.conditions.length == 1) { + if (find.conditions[0].conditions) { + // unwrap single remaining bracketed query + find = { + conditions: find.conditions[0].conditions, + operator: '|' + }; + } else { + find.operator = '&'; + } + } + } else if (conditions.length == 1) { + // one item selected + find.conditions[index] = conditions[0]; + } else { + // multiple items selected + if (pandora.user.ui.find.conditions.length == 1) { + find = { + conditions: conditions, + operator: '|' + }; + } else { + find.conditions[index] = { + conditions: conditions, + operator: '|' + }; + } + } + } + pandora.UI.set('find', find); + }, + sort: function(data) { + Ox.Log('', 'SORT', data) + var filters = Ox.clone(pandora.user.ui.filters); + pandora.$ui.mainMenu.checkItem('sortMenu_sortfilters_sortfilter' + id + '_' + data.key); + pandora.$ui.mainMenu.checkItem('sortMenu_orderfilters_orderfilter' + id + '_' + (data.operator == '+' ? 'ascending' : 'descending')); + filters[i].sort = [{key: data.key, operator: data.operator}]; + pandora.UI.set({filters: filters}); } }); + Ox.Select({ + items: pandora.site.filters.map(function(filter) { + return { + checked: filter.id == id, + id: filter.id, + title: filter.title + } + }), + max: 1, + min: 1, + type: 'image' + }) + .bindEvent('change', function(data) { + var filters = Ox.clone(pandora.user.ui.filters), + find, + id_ = data.selected[0].id, + i_ = Ox.getPositionById(pandora.user.ui.filters, id_); + if (i_ == -1) { + // new filter was not part of old filter set + if (pandora.user.ui._filterState[i].selected.length) { + // if filter with selection gets replaced, update find + find = Ox.clone(pandora.user.ui.find, true); + find.conditions.splice(pandora.user.ui._filterState[i].index, 1); + } + filters[i] = makeFilter(id_); + pandora.UI.set(Ox.extend({ + filters: filters + }, find ? { + find: find + } : {})); + replaceFilter(i, id_); + // fixme: there is an obscure special case not yet covered: + // switching to a new filter may change find from advanced to not advanced + // if part of the existing query works as a filter selection in the new filter + } else { + // swap two existing filters + var filterData = Ox.clone(pandora.user.ui._filterState[i]); + pandora.user.ui._filterState[i] = pandora.user.ui._filterState[i_]; + pandora.user.ui._filterState[i_] = filterData; + filters[i] = makeFilter(id_, pandora.user.ui.filters[i_].sort); + filters[i_] = makeFilter(id, pandora.user.ui.filters[i].sort); + pandora.UI.set({filters: filters}); + replaceFilter(i, id_); + replaceFilter(i_, id); + } + function makeFilter(id, sort) { + // makes user.ui._filterState object from site.filters object + var filter = Ox.getObjectById(pandora.site.filters, id); + return { + id: filter.id, + sort: sort || [{key: filter.type == 'integer' ? 'name' : 'items', operator: '-'}] + }; + } + function replaceFilter(i, id, find) { + // if find is passed, selected items will be derived from it // FIXME: ??? + var isOuter = i % 4 == 0; + pandora.$ui[isOuter ? 'browser' : 'filtersInnerPanel'].replaceElement( + isOuter ? i / 2 : i - 1, + pandora.$ui.filters[i] = pandora.ui.filter(id) + ); + } + }) + .appendTo(that.$bar.$element); + return that; +}; + +pandora.ui.filters = function() { + var $filters = []; + pandora.user.ui.filters.forEach(function(filter, i) { + $filters[i] = pandora.ui.filter(filter.id); + }); + return $filters; +}; + +pandora.ui.filtersInnerPanel = function() { + var that = Ox.SplitPanel({ + elements: [ + { + element: pandora.$ui.filters[1], + size: pandora.user.ui.filterSizes[1] + }, + { + element: pandora.$ui.filters[2], + }, + { + element: pandora.$ui.filters[3], + size: pandora.user.ui.filterSizes[3] + } + ], + orientation: 'horizontal' + }); return that; }; diff --git a/static/js/pandora/filterDialog.js b/static/js/pandora/filterDialog.js index 7d9e6a75..a7794149 100644 --- a/static/js/pandora/filterDialog.js +++ b/static/js/pandora/filterDialog.js @@ -9,7 +9,7 @@ pandora.ui.filterDialog = function(list) { }) .bindEvent({ click: function() { - alert(JSON.stringify(pandora.$ui.filter.options('query'))); + alert(JSON.stringify(pandora.$ui.filterForm.options('query'))); } }), /* @@ -33,7 +33,7 @@ pandora.ui.filterDialog = function(list) { } }) ], - content: pandora.$ui.filter = pandora.ui.filter(list), + content: pandora.$ui.filterForm = pandora.ui.filterForm(list), maxWidth: 648 + Ox.UI.SCROLLBAR_SIZE, minHeight: 264, minWidth: 648 + Ox.UI.SCROLLBAR_SIZE, diff --git a/static/js/pandora/filterForm.js b/static/js/pandora/filterForm.js new file mode 100644 index 00000000..86d8c741 --- /dev/null +++ b/static/js/pandora/filterForm.js @@ -0,0 +1,61 @@ +// vim: et:ts=4:sw=4:sts=4:ft=javascript + +'use strict'; + +pandora.ui.filterForm = function(list) { + var that = Ox.Filter({ + findKeys: Ox.merge(Ox.map(pandora.site.itemKeys, function(key) { + return { + autocomplete: key.autocomplete, + autocompleteSortKey: key.autocompleteSortKey, + format: key.format, + id: key.id, + title: key.title, + type: key.type == 'layer' + ? Ox.getObjectById(pandora.site.layers, key.id).type + : key.type + }; + }), { + id: 'list', + title: 'List', + type: 'list' + }), + list: list ? null : { + sort: pandora.user.ui.listSort, + view: pandora.user.ui.listView + }, + query: list ? list.query : pandora.user.ui.find, + sortKeys: pandora.site.sortKeys, + viewKeys: pandora.site.listViews + }) + .css({padding: '16px'}) + .bindEvent({ + change: function(data) { + if (list) { + pandora.api.editList({ + id: list.id, + query: data.query + }, function(result) { + Ox.Request.clearCache(list.id); + pandora.$ui.list + .bindEventOnce({ + init: function(data) { + pandora.$ui.folderList[ + pandora.getListData().folder + ].value(list.id, 'items', data.items); + } + }) + .reloadList(); + pandora.$ui.filters.forEach(function($filter) { + $filter.reloadList(); + }); + }); + } else { + pandora.UI.set({find: data.query}); + //pandora.URL.replace(); + } + } + }); + return that; +}; + diff --git a/static/js/pandora/group.js b/static/js/pandora/group.js deleted file mode 100644 index ff800d80..00000000 --- a/static/js/pandora/group.js +++ /dev/null @@ -1,252 +0,0 @@ -// vim: et:ts=4:sw=4:sts=4:ft=javascript -'use strict'; -pandora.ui.group = function(id) { - var i = Ox.getPositionById(pandora.user.ui.groups, id), - group = Ox.getObjectById(pandora.site.groups, id), - panelWidth = pandora.$ui.document.width() - (pandora.user.ui.showSidebar * pandora.user.ui.sidebarSize) - 1, - title = Ox.getObjectById(pandora.site.groups, id).title, - //width = pandora.getGroupWidth(i, panelWidth), - that = Ox.TextList({ - columns: [ - { - align: 'left', - id: 'name', - format: function(value) { - return ['country', 'language'].indexOf(id) > -1 && pandora.user.ui.showFlags - ? $('
') - .append( - $('') - .attr({src: Ox[ - id == 'country' ? 'getImageByGeoname' : 'getImageByLanguage' - ]('icon', 16, value)}) - .css({ - float: 'left', - width: '14px', - height: '14px', - margin: '0 3px 0 -2px', - borderRadius: '4px' - }) - ) - .append( - $('
') - .addClass('flagname') - .css({ - float: 'left', - width: pandora.user.ui.groupsSizes[i] - 64 - Ox.UI.SCROLLBAR_SIZE, - textOverflow: 'ellipsis', - overflowX: 'hidden' - }) - .html(value) - ) - : value - }, - operator: group.type == 'string' ? '+' : '-', - title: title, - unique: true, - visible: true, - width: pandora.user.ui.groupsSizes[i] - 40 - Ox.UI.SCROLLBAR_SIZE - }, - { - align: 'right', - id: 'items', - operator: '-', - title: '#', - visible: true, - width: 40 - } - ], - columnsVisible: true, - id: 'group_' + id, - items: function(data, callback) { - //if (pandora.user.ui.showGroups) { - delete data.keys; - return pandora.api.find(Ox.extend(data, { - group: id, - query: pandora.user.ui._groupsState[i].find - }), callback); - //} else { - // callback({data: {items: data.keys ? [] : 0}}); - //} - }, - scrollbarVisible: true, - selected: pandora.user.ui._groupsState[i].selected, - sort: [{ - key: pandora.user.ui.groups[i].sort[0].key, - operator: pandora.user.ui.groups[i].sort[0].operator - }] - }) - .bindEvent({ - paste: function(data) { - pandora.$ui.list.triggerEvent('paste', data); - }, - select: function(data) { - // fixme: cant index be an empty array, instead of -1? - // FIXME: this is still incorrect when deselecting a group item - // makes a selected item in another group disappear - var conditions = data.ids.map(function(value) { - return { - key: id, - value: value, - operator: '==' - }; - }), - index = pandora.user.ui._groupsState[i].index, - find = Ox.clone(pandora.user.ui.find, true); - if (Ox.isArray(index)) { - // this group had multiple selections and the | query - // was on the top level, i.e. not bracketed - find = { - conditions: conditions, - operator: conditions.length > 1 ? '|' : '&' - } - } else { - if (index == -1) { - // this group had no selection, i.e. no query - index = find.conditions.length; - if (find.operator == '|') { - find = { - conditions: [find], - operator: '&' - }; - index = 1; - } else { - find.operator = '&'; - } - } - if (conditions.length == 0) { - // nothing selected - find.conditions.splice(index, 1); - if (find.conditions.length == 1) { - if (find.conditions[0].conditions) { - // unwrap single remaining bracketed query - find = { - conditions: find.conditions[0].conditions, - operator: '|' - }; - } else { - find.operator = '&'; - } - } - } else if (conditions.length == 1) { - // one item selected - find.conditions[index] = conditions[0]; - } else { - // multiple items selected - if (pandora.user.ui.find.conditions.length == 1) { - find = { - conditions: conditions, - operator: '|' - }; - } else { - find.conditions[index] = { - conditions: conditions, - operator: '|' - }; - } - } - } - pandora.UI.set('find', find); - }, - sort: function(data) { - Ox.Log('', 'SORT', data) - var groups = Ox.clone(pandora.user.ui.groups); - pandora.$ui.mainMenu.checkItem('sortMenu_sortgroups_sortgroup' + id + '_' + data.key); - pandora.$ui.mainMenu.checkItem('sortMenu_ordergroups_ordergroup' + id + '_' + (data.operator == '+' ? 'ascending' : 'descending')); - groups[i].sort = [{key: data.key, operator: data.operator}]; - pandora.UI.set({groups: groups}); - } - }); - Ox.Select({ - items: pandora.site.groups.map(function(group) { - return { - checked: group.id == id, - id: group.id, - title: group.title - } - }), - max: 1, - min: 1, - type: 'image' - }) - .bindEvent('change', function(data) { - var find, - groups = Ox.clone(pandora.user.ui.groups), - id_ = data.selected[0].id, - i_ = Ox.getPositionById(pandora.user.ui.groups, id_); - if (i_ == -1) { - // new group was not part of old group set - if (pandora.user.ui._groupsState[i].selected.length) { - // if group with selection gets replaced, update find - find = Ox.clone(pandora.user.ui.find, true); - find.conditions.splice(pandora.user.ui._groupsState[i].index, 1); - } - groups[i] = makeGroup(id_); - pandora.UI.set(Ox.extend({ - groups: groups - }, find ? { - find: find - } : {})); - replaceGroup(i, id_); - // fixme: there is an obscure special case not yet covered: - // switching to a new group may change find from advanced to not advanced - // if part of the existing query works as a group selection in the new group - } else { - // swap two existing groups - var groupsData = Ox.clone(pandora.user.ui._groupsState[i]); - pandora.user.ui._groupsState[i] = pandora.user.ui._groupsState[i_]; - pandora.user.ui._groupsState[i_] = groupsData; - groups[i] = makeGroup(id_, pandora.user.ui.groups[i_].sort); - groups[i_] = makeGroup(id, pandora.user.ui.groups[i].sort); - pandora.UI.set({groups: groups}); - replaceGroup(i, id_); - replaceGroup(i_, id); - } - function makeGroup(id, sort) { - // makes user.ui._groups object from site.groups object - var group = Ox.getObjectById(pandora.site.groups, id); - return { - id: group.id, - sort: sort || [{key: group.type == 'integer' ? 'name' : 'items', operator: '-'}] - }; - } - function replaceGroup(i, id, find) { - // if find is passed, selected items will be derived from it - var isOuter = i % 4 == 0; - pandora.$ui[isOuter ? 'browser' : 'groupsInnerPanel'].replaceElement( - isOuter ? i / 2 : i - 1, - pandora.$ui.groups[i] = pandora.ui.group(id) - ); - } - }) - .appendTo(that.$bar.$element); - return that; -}; - -pandora.ui.groups = function() { - var $groups = []; - pandora.user.ui.groups.forEach(function(group, i) { - $groups[i] = pandora.ui.group(group.id); - }); - return $groups; -}; - -pandora.ui.groupsInnerPanel = function() { - var that = Ox.SplitPanel({ - elements: [ - { - element: pandora.$ui.groups[1], - size: pandora.user.ui.groupsSizes[1] - }, - { - element: pandora.$ui.groups[2], - }, - { - element: pandora.$ui.groups[3], - size: pandora.user.ui.groupsSizes[3] - } - ], - orientation: 'horizontal' - }); - return that; -}; - diff --git a/static/js/pandora/mainPanel.js b/static/js/pandora/mainPanel.js index dee62f27..c50b292d 100644 --- a/static/js/pandora/mainPanel.js +++ b/static/js/pandora/mainPanel.js @@ -30,15 +30,15 @@ pandora.ui.mainPanel = function() { pandora.$ui.list.reloadList(); } // FIXME: why is this being handled _here_? - pandora.user.ui._groupsState.forEach(function(data, i) { - if (!Ox.isEqual(data.selected, previousUI._groupsState[i].selected)) { - pandora.$ui.groups[i].options({selected: data.selected}); + pandora.user.ui._filterState.forEach(function(data, i) { + if (!Ox.isEqual(data.selected, previousUI._filterState[i].selected)) { + pandora.$ui.filters[i].options({selected: data.selected}); } - if (!Ox.isEqual(data.find, previousUI._groupsState[i].find)) { - Ox.print(i, 'NOT EQUAL', data.find, previousUI._groupsState[i].find) - pandora.$ui.groups[i].reloadList(); + if (!Ox.isEqual(data.find, previousUI._filterState[i].find)) { + Ox.print(i, 'NOT EQUAL', data.find, previousUI._filterState[i].find) + pandora.$ui.filters[i].reloadList(); } else { - Ox.print(i, 'EQUAL', data.find, previousUI._groupsState[i].find) + Ox.print(i, 'EQUAL', data.find, previousUI._filterState[i].find) } }); } else { diff --git a/static/js/pandora/menu.js b/static/js/pandora/menu.js index 5ec4afb1..eb326a00 100644 --- a/static/js/pandora/menu.js +++ b/static/js/pandora/menu.js @@ -85,19 +85,19 @@ pandora.ui.mainMenu = function() { }) } ] }, {}, - { id: 'groups', title: 'Groups', items: [ - { group: 'groups', min: 5, max: 5, items: pandora.site.groups.map(function(group) { + { id: 'filters', title: 'Filters', items: [ + { group: 'filters', min: 5, max: 5, items: pandora.site.filters.map(function(filter) { return Ox.extend({ - checked: Ox.getPositionById(ui.groups, group.id) > -1 - }, group); + checked: Ox.getPositionById(ui.filters, filter.id) > -1 + }, filter); }) }, {}, - { id: 'resetgroups', title: 'Reset Groups' } + { id: 'resetfilters', title: 'Reset Filters' } ] }, {}, { id: 'showsidebar', title: (ui.showSidebar ? 'Hide' : 'Show') + ' Sidebar', keyboard: 'shift s' }, { id: 'showinfo', title: (ui.showInfo ? 'Hide' : 'Show') + ' Info', disabled: !ui.showSidebar, keyboard: 'shift i' }, - { id: 'showgroups', title: (ui.showGroups ? 'Hide' : 'Show') + ' Groups', disabled: !!ui.item, keyboard: 'shift g' }, + { id: 'showfilters', title: (ui.showFilters ? 'Hide' : 'Show') + ' Filters', disabled: !!ui.item, keyboard: 'shift f' }, { id: 'showbrowser', title: (ui.showBrowser ? 'Hide' : 'Show') + ' ' + pandora.site.itemName.singular + ' Browser', disabled: !ui.item, keyboard: 'shift b' }, { id: 'showannotations', title: (ui.showAnnotations ? 'Hide' : 'Show') + ' Annotations', disabled: !ui.item || ['timeline', 'video'].indexOf(ui.itemView) == -1, keyboard: 'shift a' }, { id: 'showtimeline', title: (ui.showTimeline ? 'Hide' : 'Show') + ' Timeline', disabled: !ui.item || ui.itemView != 'video', keyboard: 'shift t' }, @@ -159,17 +159,17 @@ pandora.ui.mainMenu = function() { pandora.$ui.findSelect.options({value: value}); } else if (data.id == 'itemview') { pandora.UI.set({itemView: value}); - } else if (Ox.startsWith(data.id, 'ordergroup')) { - var groups = Ox.clone(pandora.user.ui.groups), - id = data.id.replace('ordergroup', ''), - position = Ox.getPositionById(groups, id), - key = groups[position].sort[0].key, + } else if (Ox.startsWith(data.id, 'orderfilter')) { + var filters = Ox.clone(pandora.user.ui.filters), + id = data.id.replace('orderfilter', ''), + position = Ox.getPositionById(filters, id), + key = filters[position].sort[0].key, operator = value == 'ascending' ? '+' : '-'; - pandora.$ui.groups[position].options({ + pandora.$ui.filters[position].options({ sort: [{key: key, operator: operator}] }); - groups[position].sort[0].operator = operator; - pandora.UI.set({groups: groups}); + filters[position].sort[0].operator = operator; + pandora.UI.set({filters: filters}); } else if (data.id == 'ordermovies') { var key = pandora.user.ui.listSort[0].key, operator = value == 'ascending' ? '+' : '-'; @@ -179,19 +179,22 @@ pandora.ui.mainMenu = function() { pandora.UI.set('theme', value); } else if (data.id == 'showsiteposter') { pandora.UI.set('showSitePoster', data.checked) - } else if (Ox.startsWith(data.id, 'sortgroup')) { - var groups = Ox.clone(ui.groups), - id = data.id.replace('sortgroup', ''), - position = Ox.getPositionById(groups, id), - type = Ox.getObjectById(pandora.site.groups, id).type, + } else if (Ox.startsWith(data.id, 'sortfilter')) { + var filters = Ox.clone(ui.filters), + id = data.id.replace('sortfilter', ''), + position = Ox.getPositionById(filters, id), + type = Ox.getObjectById(pandora.site.filters, id).type, key = value, operator = key == 'name' && type == 'string' ? '+' : '-'; - pandora.$ui.mainMenu.checkItem('sortMenu_ordergroups_ordergroup' + id + '_' + (operator == '+' ? 'ascending' : 'descending')) - pandora.$ui.groups[position].options({ + pandora.$ui.mainMenu.checkItem( + 'sortMenu_orderfilters_orderfilter' + id + '_' + + (operator == '+' ? 'ascending' : 'descending') + ); + pandora.$ui.filters[position].options({ sort: [{key: key, operator: operator}] }); - groups[position].sort[0].key = key; - pandora.UI.set({groups: groups}); + filters[position].sort[0].key = key; + pandora.UI.set({filters: filters}); } else if (data.id == 'sortmovies') { pandora.UI.set({listSort: [{key: value, operator: ''}]}); } else if (data.id == 'viewicons') { @@ -236,8 +239,8 @@ pandora.ui.mainMenu = function() { pandora.UI.set({showSidebar: !ui.showSidebar}); } else if (data.id == 'showinfo') { pandora.UI.set({showInfo: !ui.showInfo}); - } else if (data.id == 'showgroups') { - pandora.UI.set({showGroups: !ui.showGroups}); + } else if (data.id == 'showfilters') { + pandora.UI.set({showFilters: !ui.showFilters}); } else if (data.id == 'showbrowser') { pandora.UI.set({showBrowser: !ui.showBrowser}); } else if (data.id == 'showannotations') { @@ -264,9 +267,9 @@ pandora.ui.mainMenu = function() { (pandora.$ui.usersDialog || ( pandora.$ui.usersDialog = pandora.ui.usersDialog()) ).open(); - } else if (data.id == 'resetgroups') { + } else if (data.id == 'resetfilters') { pandora.UI.set({ - groups: pandora.site.user.ui.groups + filters: pandora.site.user.ui.filters }); pandora.$ui.contentPanel.replaceElement(0, pandora.$ui.browser = pandora.ui.browser()); } else if (data.id == 'logs') { @@ -314,8 +317,8 @@ pandora.ui.mainMenu = function() { key_shift_b: function() { ui.item && pandora.UI.set({showBrowser: !ui.showBrowser}); }, - key_shift_g: function() { - !ui.item && pandora.UI.set({showGroups: !ui.showGroups}); + key_shift_f: function() { + !ui.item && pandora.UI.set({showFilters: !ui.showFilters}); }, key_shift_i: function() { ui.showSidebar && pandora.UI.set({showInfo: !ui.showInfo}); @@ -336,12 +339,12 @@ pandora.ui.mainMenu = function() { that[action]('deletelist'); that[ui.listSelection.length ? 'enableItem' : 'disableItem']('newlistfromselection'); }, - pandora_groups: function(data) { + pandora_filters: function(data) { that.replaceMenu('sortMenu', getSortMenu()); }, pandora_item: function(data) { if (!!data.value != !!data.previousValue) { - that[data.value ? 'disableItem' : 'enableItem']('showgroups'); + that[data.value ? 'disableItem' : 'enableItem']('showfilters'); that[data.value ? 'enableItem' : 'disableItem']('showbrowser'); that.replaceMenu('sortMenu', getSortMenu()); } @@ -376,8 +379,8 @@ pandora.ui.mainMenu = function() { pandora_showbrowser: function(data) { that.setItemTitle('showbrowser', (data.value ? 'Hide' : 'Show') + ' ' + pandora.site.itemName.singular + ' Browser'); }, - pandora_showgroups: function(data) { - that.setItemTitle('showgroups', (data.value ? 'Hide' : 'Show') + ' Groups'); + pandora_showfilters: function(data) { + that.setItemTitle('showfilters', (data.value ? 'Hide' : 'Show') + ' Filters'); }, pandora_showinfo: function(data) { that.setItemTitle('showinfo', (data.value ? 'Hide' : 'Show') + ' Info'); @@ -452,26 +455,26 @@ pandora.ui.mainMenu = function() { ] }, { id: 'advancedsort', title: 'Advanced Sort...', keyboard: 'shift control s' }, {}, - { id: 'sortgroups', title: 'Sort Groups', items: pandora.user.ui.groups.map(function(group) { + { id: 'sortfilters', title: 'Sort Filters', items: pandora.user.ui.filters.map(function(filter) { return { - id: 'sortgroup' + group.id, - title: 'Sort ' + Ox.getObjectById(pandora.site.groups, group.id).title + ' Group by', + id: 'sortfilter' + filter.id, + title: 'Sort ' + Ox.getObjectById(pandora.site.filters, filter.id).title + ' Filter by', items: [ - { group: 'sortgroup' + group.id, min: 1, max: 1, items: [ - { id: 'name', title: 'Name', checked: group.sort[0].key == 'name' }, - { id: 'items', title: 'Items', checked: group.sort[0].key == 'items' } + { group: 'sortfilter' + filter.id, min: 1, max: 1, items: [ + { id: 'name', title: 'Name', checked: filter.sort[0].key == 'name' }, + { id: 'items', title: 'Items', checked: filter.sort[0].key == 'items' } ] } ] } }) }, - { id: 'ordergroups', title: 'Order Groups', items: pandora.user.ui.groups.map(function(group) { + { id: 'orderfilters', title: 'Order Filters', items: pandora.user.ui.filters.map(function(filter) { return { - id: 'ordergroup' + group.id, - title: 'Order ' + Ox.getObjectById(pandora.site.groups, group.id).title + ' Group', + id: 'orderfilter' + filter.id, + title: 'Order ' + Ox.getObjectById(pandora.site.filters, filter.id).title + ' Filter', items: [ - { group: 'ordergroup' + group.id, min: 1, max: 1, items: [ - { id: 'ascending', title: 'Ascending', checked: group.sort[0].operator == '+' }, - { id: 'descending', title: 'Descending', checked: group.sort[0].operator == '-' } + { group: 'orderfilter' + filter.id, min: 1, max: 1, items: [ + { id: 'ascending', title: 'Ascending', checked: filter.sort[0].operator == '+' }, + { id: 'descending', title: 'Descending', checked: filter.sort[0].operator == '-' } ] } ] } diff --git a/static/js/pandora/navigationView.js b/static/js/pandora/navigationView.js index ef3a93e5..9e8248fd 100644 --- a/static/js/pandora/navigationView.js +++ b/static/js/pandora/navigationView.js @@ -107,7 +107,7 @@ pandora.ui.navigationView = function(type, videoRatio) { // clickable: pandora.site.capabilities.canClickMap[pandora.user.level], find: ui.mapFind, // 20 menu + 24 toolbar + 1 resizebar + 16 statusbar - height: window.innerHeight - ui.showGroups * ui.groupsSize - 61, + height: window.innerHeight - ui.showFilters * ui.filtersSize - 61, places: function(data, callback) { var itemsQuery; if (!ui.item) { @@ -162,7 +162,7 @@ pandora.ui.navigationView = function(type, videoRatio) { date: new Date(0), events: result.data.items, // 20 px menu, 24 px toolbar, 1px resizbar, 16px statusbar - height: window.innerHeight - ui.showGroups * ui.groupsSize - 61, + height: window.innerHeight - ui.showFilters * ui.filtersSize - 61, range: [-5000, 5000], showControls: ui.showCalendarControls, width: window.innerWidth - ui.showSidebar * ui.sidebarSize - listSize - 2, diff --git a/static/js/pandora/rightPanel.js b/static/js/pandora/rightPanel.js index 8c59ecc6..eee0a057 100644 --- a/static/js/pandora/rightPanel.js +++ b/static/js/pandora/rightPanel.js @@ -25,7 +25,7 @@ pandora.ui.rightPanel = function() { .bindEvent({ resize: function(data) { if (!pandora.user.ui.item) { - pandora.resizeGroups(); + pandora.resizeFilters(); pandora.$ui.list.size(); if (pandora.user.ui.listView == 'clips') { var clipsItems = pandora.getClipsItems(); diff --git a/static/js/pandora/utils.js b/static/js/pandora/utils.js index b1768de2..d0b4d8c2 100644 --- a/static/js/pandora/utils.js +++ b/static/js/pandora/utils.js @@ -458,6 +458,12 @@ pandora.getClipsQuery = function() { return clipsQuery; }; +pandora.getFilterSizes = function() { + return Ox.divideInt( + window.innerWidth - pandora.user.ui.showSidebar * pandora.user.ui.sidebarSize - 1, 5 + ); +}; + pandora.getFoldersHeight = function() { var height = 0; pandora.site.sectionFolders[pandora.user.ui.section].forEach(function(folder, i) { @@ -480,12 +486,6 @@ pandora.getFoldersWidth = function() { return width; }; -pandora.getGroupsSizes = function() { - return Ox.divideInt( - window.innerWidth - pandora.user.ui.showSidebar * pandora.user.ui.sidebarSize - 1, 5 - ) -}; - pandora.getInfoHeight = function(includeHidden) { // fixme: new, check if it can be used more var height = 0, isVideoPreview; @@ -700,8 +700,8 @@ pandora.isItemFind = function(find) { pandora.signin = function(data) { pandora.user = data.user; - pandora.user.ui._list = pandora.getListsState(pandora.user.ui.find); - pandora.user.ui._groupsState = pandora.getGroupsState(pandora.user.ui.find); + pandora.user.ui._list = pandora.getListState(pandora.user.ui.find); + pandora.user.ui._filterState = pandora.getFilterState(pandora.user.ui.find); pandora.user.ui._findState = pandora.getFindState(pandora.user.ui.find); Ox.Theme(pandora.user.ui.theme); pandora.UI.set({find: pandora.user.ui.find}); @@ -711,8 +711,8 @@ pandora.signin = function(data) { pandora.signout = function(data) { pandora.user = data.user; - pandora.user.ui._list = pandora.getListsState(pandora.user.ui.find); - pandora.user.ui._groupsState = pandora.getGroupsState(pandora.user.ui.find); + pandora.user.ui._list = pandora.getListState(pandora.user.ui.find); + pandora.user.ui._filterState = pandora.getFilterState(pandora.user.ui.find); pandora.user.ui._findState = pandora.getFindState(pandora.user.ui.find); Ox.Theme(pandora.site.user.ui.theme); pandora.UI.set({find: pandora.user.ui.find}); @@ -724,8 +724,8 @@ pandora.reloadList = function() { Ox.Log('', 'reloadList') var listData = pandora.getListData(); Ox.Request.clearCache(); // fixme: remove - pandora.$ui.groups.forEach(function($group) { - $group.reloadList(); + pandora.$ui.filters.forEach(function($filter) { + $filter.reloadList(); }); pandora.$ui.list .bindEvent({ @@ -746,18 +746,18 @@ pandora.reloadList = function() { .reloadList(); }; -pandora.resizeGroups = function(width) { - pandora.user.ui.groupsSizes = pandora.getGroupsSizes(); +pandora.resizeFilters = function(width) { + pandora.user.ui.filterSizes = pandora.getFilterSizes(); pandora.$ui.browser - .size(0, pandora.user.ui.groupsSizes[0]) - .size(2, pandora.user.ui.groupsSizes[4]); - pandora.$ui.groupsInnerPanel - .size(0, pandora.user.ui.groupsSizes[1]) - .size(2, pandora.user.ui.groupsSizes[3]); - pandora.$ui.groups.forEach(function($list, i) { - $list.resizeColumn('name', pandora.user.ui.groupsSizes[i] - 40 - Ox.UI.SCROLLBAR_SIZE); + .size(0, pandora.user.ui.filterSizes[0]) + .size(2, pandora.user.ui.filterSizes[4]); + pandora.$ui.filtersInnerPanel + .size(0, pandora.user.ui.filterSizes[1]) + .size(2, pandora.user.ui.filterSizes[3]); + pandora.$ui.filters.forEach(function($list, i) { + $list.resizeColumn('name', pandora.user.ui.filterSizes[i] - 40 - Ox.UI.SCROLLBAR_SIZE); if (pandora.user.ui.showFlags) { - $list.find('.flagname').css({width: pandora.user.ui.groupsSizes[i] - 64 - Ox.UI.SCROLLBAR_SIZE}) + $list.find('.flagname').css({width: pandora.user.ui.filterSizes[i] - 64 - Ox.UI.SCROLLBAR_SIZE}) } }); }; @@ -801,7 +801,7 @@ pandora.resizeWindow = function() { pandora.$ui.info.resizeInfo(); */ if (!pandora.user.ui.item) { - pandora.resizeGroups(pandora.$ui.rightPanel.width()); + pandora.resizeFilters(pandora.$ui.rightPanel.width()); if (pandora.user.ui.listView == 'clips') { var clipsItems = pandora.getClipsItems(); previousClipsItems = pandora.getClipsItems(pandora.$ui.list.options('width')); @@ -894,7 +894,7 @@ pandora.unloadWindow = function() { (function() { - // Note: getFindState has to run after getListsState and getGroupsState + // Note: getFindState has to run after getListState and getFilterState function everyCondition(conditions, key, operator) { // If every condition has the given key and operator @@ -919,58 +919,12 @@ pandora.unloadWindow = function() { return indices.length == 1 ? indices[0] : -1; } - pandora.getFindState = function(find) { - // The find element is populated if exactly one condition in an & query - // has a findKey as key and "=" as operator (and all other conditions - // are either list or groups), or if all conditions in an | query have - // the same group id as key and "==" as operator - Ox.Log('', 'getFindState', find) - // FIXME: this is still incorrect when you select a lot of group items - // and reload the page (will be advanced) - var conditions, indices, state = {index: -1, key: '*', value: ''}; - if (find.operator == '&') { - // number of conditions that are not list or groups - conditions = find.conditions.length - - !!pandora.user.ui._list - - pandora.user.ui._groupsState.filter(function(group) { - return group.index > -1; - }).length; - // indices of non-advanced find queries - indices = Ox.map(pandora.site.findKeys, function(findKey) { - var index = oneCondition(find.conditions, findKey.id, '='); - return index > -1 ? index : null; - }); - state = conditions == 1 && indices.length == 1 ? { - index: indices[0], - key: find.conditions[indices[0]].key, - value: decodeURIComponent(find.conditions[indices[0]].value) - } : { - index: -1, - key: conditions == 0 && indices.length == 0 ? '*' : 'advanced', - value: '' - }; - } else { - state = { - index: -1, - key: 'advanced', - value: '' - }; - Ox.forEach(pandora.user.ui.groups, function(key) { - if (everyCondition(find.conditions, key, '==')) { - state.key = '*'; - return false; - } - }); - } - return state; - } - - pandora.getGroupsState = function(find) { - // A group is selected if exactly one condition in an & query or every - // condition in an | query has the group id as key and "==" as operator - return pandora.user.ui.groups.map(function(group) { + pandora.getFilterState = function(find) { + // A filter is selected if exactly one condition in an & query or every + // condition in an | query has the filter id as key and "==" as operator + return pandora.user.ui.filters.map(function(filter) { // FIXME: cant index be an empty array, instead of -1? - var key = group.id, + var key = filter.id, state = {index: -1, find: Ox.clone(find, true), selected: []}; if (find.operator == '&') { // include conditions where all subconditions match @@ -992,10 +946,10 @@ pandora.unloadWindow = function() { } if (state.selected.length) { if (Ox.isArray(state.index)) { - // every condition in an | query matches this group + // every condition in an | query matches this filter state.find = {conditions: [], operator: ''}; } else { - // one condition in an & query matches this group + // one condition in an & query matches this filter state.find.conditions.splice(state.index, 1); if ( state.find.conditions.length == 1 @@ -1013,7 +967,53 @@ pandora.unloadWindow = function() { }); } - pandora.getListsState = function(find) { + pandora.getFindState = function(find) { + // The find element is populated if exactly one condition in an & query + // has a findKey as key and "=" as operator (and all other conditions + // are either list or filters), or if all conditions in an | query have + // the same filter id as key and "==" as operator + Ox.Log('', 'getFindState', find) + // FIXME: this is still incorrect when you select a lot of filter items + // and reload the page (will be advanced) + var conditions, indices, state = {index: -1, key: '*', value: ''}; + if (find.operator == '&') { + // number of conditions that are not list or filters + conditions = find.conditions.length + - !!pandora.user.ui._list + - pandora.user.ui._filterState.filter(function(filter) { + return filter.index > -1; + }).length; + // indices of non-advanced find queries + indices = Ox.map(pandora.site.findKeys, function(findKey) { + var index = oneCondition(find.conditions, findKey.id, '='); + return index > -1 ? index : null; + }); + state = conditions == 1 && indices.length == 1 ? { + index: indices[0], + key: find.conditions[indices[0]].key, + value: decodeURIComponent(find.conditions[indices[0]].value) + } : { + index: -1, + key: conditions == 0 && indices.length == 0 ? '*' : 'advanced', + value: '' + }; + } else { + state = { + index: -1, + key: 'advanced', + value: '' + }; + Ox.forEach(pandora.user.ui.filters, function(key) { + if (everyCondition(find.conditions, key, '==')) { + state.key = '*'; + return false; + } + }); + } + return state; + } + + pandora.getListState = function(find) { // A list is selected if exactly one condition in an & query has "list" // as key and "==" as operator var index, state = '';