diff --git a/app/assets/javascripts/admins/identity_authentications/index.js b/app/assets/javascripts/admins/identity_authentications/index.js index 2da644ec2..91ce5c7ec 100644 --- a/app/assets/javascripts/admins/identity_authentications/index.js +++ b/app/assets/javascripts/admins/identity_authentications/index.js @@ -1,6 +1,7 @@ $(document).on('turbolinks:load', function() { if ($('body.admins-identity-authentications-index-page').length > 0) { var $searchFrom = $('.identity-authentication-list-form'); + $searchFrom.find('select[name="status"]').val('pending'); $searchFrom.on('click', '.search-form-tab', function(){ var $link = $(this); @@ -12,6 +13,7 @@ $(document).on('turbolinks:load', function() { $searchFrom.find('.status-filter').show(); } else { $searchFrom.find('.status-filter').hide(); + $searchFrom.find('select[name="status"]').val('pending'); } }); } diff --git a/app/assets/javascripts/admins/professional_authentications/index.js b/app/assets/javascripts/admins/professional_authentications/index.js index 769a6b2fc..82a1da5af 100644 --- a/app/assets/javascripts/admins/professional_authentications/index.js +++ b/app/assets/javascripts/admins/professional_authentications/index.js @@ -1,6 +1,7 @@ $(document).on('turbolinks:load', function() { if ($('body.admins-professional-authentications-index-page').length > 0) { var $searchFrom = $('.professional-authentication-list-form'); + $searchFrom.find('select[name="status"]').val('pending'); $searchFrom.on('click', '.search-form-tab', function(){ var $link = $(this); @@ -12,6 +13,7 @@ $(document).on('turbolinks:load', function() { $searchFrom.find('.status-filter').show(); } else { $searchFrom.find('.status-filter').hide(); + $searchFrom.find('select[name="status"]').val('pending'); } }); } diff --git a/app/assets/javascripts/admins/shixun_authorizations/index.js b/app/assets/javascripts/admins/shixun_authorizations/index.js new file mode 100644 index 000000000..b98354c65 --- /dev/null +++ b/app/assets/javascripts/admins/shixun_authorizations/index.js @@ -0,0 +1,20 @@ +$(document).on('turbolinks:load', function() { + if ($('body.admins-shixun-authorizations-index-page').length > 0) { + var $searchFrom = $('.shixun-authorization-list-form'); + $searchFrom.find('select[name="status"]').val('pending'); + + $searchFrom.on('click', '.search-form-tab', function(){ + var $link = $(this); + + $searchFrom.find('input[name="keyword"]').val(''); + $searchFrom.find('select[name="status"]').val('processed'); + + if($link.data('value') === 'processed'){ + $searchFrom.find('.status-filter').show(); + } else { + $searchFrom.find('.status-filter').hide(); + $searchFrom.find('select[name="status"]').val('pending'); + } + }); + } +}) \ No newline at end of file diff --git a/app/assets/javascripts/admins/subject_authorizations/index.js b/app/assets/javascripts/admins/subject_authorizations/index.js new file mode 100644 index 000000000..bfba16fc1 --- /dev/null +++ b/app/assets/javascripts/admins/subject_authorizations/index.js @@ -0,0 +1,20 @@ +$(document).on('turbolinks:load', function() { + if ($('body.admins-subject-authorizations-index-page').length > 0) { + var $searchFrom = $('.subject-authorization-list-form'); + $searchFrom.find('select[name="status"]').val('pending'); + + $searchFrom.on('click', '.search-form-tab', function(){ + var $link = $(this); + + $searchFrom.find('input[name="keyword"]').val(''); + $searchFrom.find('select[name="status"]').val('processed'); + + if($link.data('value') === 'processed'){ + $searchFrom.find('.status-filter').show(); + } else { + $searchFrom.find('.status-filter').hide(); + $searchFrom.find('select[name="status"]').val('pending'); + } + }); + } +}) \ No newline at end of file diff --git a/app/assets/javascripts/bootstrap-notify.js b/app/assets/javascripts/bootstrap-notify.js old mode 100755 new mode 100644 diff --git a/app/assets/javascripts/bootstrap-notify.min.js b/app/assets/javascripts/bootstrap-notify.min.js old mode 100755 new mode 100644 diff --git a/app/assets/javascripts/i18n/select2-i18n.zh-CN.js b/app/assets/javascripts/i18n/select2-i18n.zh-CN.js old mode 100755 new mode 100644 diff --git a/app/assets/javascripts/jquery.cxselect.js b/app/assets/javascripts/jquery.cxselect.js old mode 100755 new mode 100644 index 9bd674664..aeb3c17dd --- a/app/assets/javascripts/jquery.cxselect.js +++ b/app/assets/javascripts/jquery.cxselect.js @@ -1,403 +1,403 @@ -/*! - * jQuery cxSelect - * @name jquery.cxselect.js - * @version 1.4.1 - * @date 2016-11-02 - * @author ciaoca - * @email ciaoca@gmail.com - * @site https://github.com/ciaoca/cxSelect - * @license Released under the MIT license - */ -(function(factory) { - if (typeof define === 'function' && define.amd) { - define(['jquery'], factory); - } else { - factory(window.jQuery || window.Zepto || window.$); - }; -}(function($) { - var cxSelect = function() { - var self = this; - var dom, settings, callback; - - // 分配参数 - for (var i = 0, l = arguments.length; i < l; i++) { - if (cxSelect.isJquery(arguments[i]) || cxSelect.isZepto(arguments[i])) { - dom = arguments[i]; - } else if (cxSelect.isElement(arguments[i])) { - dom = $(arguments[i]); - } else if (typeof arguments[i] === 'function') { - callback = arguments[i]; - } else if (typeof arguments[i] === 'object') { - settings = arguments[i]; - }; - }; - - var api = new cxSelect.init(dom, settings); - - if (typeof callback === 'function') { - callback(api); - }; - - return api; - }; - - cxSelect.isElement = function(o){ - if (o && (typeof HTMLElement === 'function' || typeof HTMLElement === 'object') && o instanceof HTMLElement) { - return true; - } else { - return (o && o.nodeType && o.nodeType === 1) ? true : false; - }; - }; - - cxSelect.isJquery = function(o){ - return (o && o.length && (typeof jQuery === 'function' || typeof jQuery === 'object') && o instanceof jQuery) ? true : false; - }; - - cxSelect.isZepto = function(o){ - return (o && o.length && (typeof Zepto === 'function' || typeof Zepto === 'object') && Zepto.zepto.isZ(o)) ? true : false; - }; - - cxSelect.getIndex = function(n, required) { - return required ? n : n - 1; - }; - - cxSelect.getData = function(data, space) { - if (typeof space === 'string' && space.length) { - space = space.split('.'); - for (var i = 0, l = space.length; i < l; i++) { - data = data[space[i]]; - }; - }; - return data; - }; - - cxSelect.init = function(dom, settings) { - var self = this; - - if (!cxSelect.isJquery(dom) && !cxSelect.isZepto(dom)) {return}; - - var theSelect = { - dom: { - box: dom - } - }; - - self.attach = cxSelect.attach.bind(theSelect); - self.detach = cxSelect.detach.bind(theSelect); - self.setOptions = cxSelect.setOptions.bind(theSelect); - self.clear = cxSelect.clear.bind(theSelect); - - theSelect.changeEvent = function() { - cxSelect.selectChange.call(theSelect, this.className); - }; - - theSelect.settings = $.extend({}, $.cxSelect.defaults, settings, { - url: theSelect.dom.box.data('url'), - emptyStyle: theSelect.dom.box.data('emptyStyle'), - required: theSelect.dom.box.data('required'), - firstTitle: theSelect.dom.box.data('firstTitle'), - firstValue: theSelect.dom.box.data('firstValue'), - jsonSpace: theSelect.dom.box.data('jsonSpace'), - jsonName: theSelect.dom.box.data('jsonName'), - jsonValue: theSelect.dom.box.data('jsonValue'), - jsonSub: theSelect.dom.box.data('jsonSub') - }); - - var _dataSelects = theSelect.dom.box.data('selects'); - - if (typeof _dataSelects === 'string' && _dataSelects.length) { - theSelect.settings.selects = _dataSelects.split(','); - }; - - self.setOptions(); - self.attach(); - - // 使用独立接口获取数据 - if (!theSelect.settings.url && !theSelect.settings.data) { - cxSelect.start.apply(theSelect); - - // 设置自定义数据 - } else if ($.isArray(theSelect.settings.data)) { - cxSelect.start.call(theSelect, theSelect.settings.data); - - // 设置 URL,通过 Ajax 获取数据 - } else if (typeof theSelect.settings.url === 'string' && theSelect.settings.url.length) { - $.getJSON(theSelect.settings.url, function(json) { - cxSelect.start.call(theSelect, json); - }); - }; - }; - - // 设置参数 - cxSelect.setOptions = function(opts) { - var self = this; - - if (opts) { - $.extend(self.settings, opts); - }; - - // 初次或重设选择器组 - if (!$.isArray(self.selectArray) || !self.selectArray.length || (opts && opts.selects)) { - self.selectArray = []; - - if ($.isArray(self.settings.selects) && self.settings.selects.length) { - var _tempSelect; - - for (var i = 0, l = self.settings.selects.length; i < l; i++) { - _tempSelect = self.dom.box.find('select.' + self.settings.selects[i]); - - if (!_tempSelect || !_tempSelect.length) {break}; - - self.selectArray.push(_tempSelect); - }; - }; - }; - - if (opts) { - if (!$.isArray(opts.data) && typeof opts.url === 'string' && opts.url.length) { - $.getJSON(self.settings.url, function(json) { - cxSelect.start.call(self, json); - }); - - } else { - cxSelect.start.call(self, opts.data); - }; - }; - }; - - // 绑定 - cxSelect.attach = function() { - var self = this; - - if (!self.attachStatus) { - self.dom.box.on('change', 'select', self.changeEvent); - }; - - if (typeof self.attachStatus === 'boolean') { - cxSelect.start.call(self); - }; - - self.attachStatus = true; - }; - - // 移除绑定 - cxSelect.detach = function() { - var self = this; - self.dom.box.off('change', 'select', self.changeEvent); - self.attachStatus = false; - }; - - // 清空选项 - cxSelect.clear = function(index) { - var self = this; - var _style = { - display: '', - visibility: '' - }; - - index = isNaN(index) ? 0 : index; - - // 清空后面的 select - for (var i = index, l = self.selectArray.length; i < l; i++) { - self.selectArray[i].empty().prop('disabled', true); - - if (self.settings.emptyStyle === 'none') { - _style.display = 'none'; - } else if (self.settings.emptyStyle === 'hidden') { - _style.visibility = 'hidden'; - }; - - self.selectArray[i].css(_style); - }; - }; - - cxSelect.start = function(data) { - var self = this; - - if ($.isArray(data)) { - self.settings.data = cxSelect.getData(data, self.settings.jsonSpace); - }; - - if (!self.selectArray.length) {return}; - - // 保存默认值 - for (var i = 0, l = self.selectArray.length; i < l; i++) { - if (typeof self.selectArray[i].attr('data-value') !== 'string' && self.selectArray[i][0].options.length) { - self.selectArray[i].attr('data-value', self.selectArray[i].val()); - }; - }; - - if (self.settings.data || (typeof self.selectArray[0].data('url') === 'string' && self.selectArray[0].data('url').length)) { - cxSelect.getOptionData.call(self, 0); - } else { - self.selectArray[0].prop('disabled', false).css({ - 'display': '', - 'visibility': '' - }); - }; - }; - - // 获取选项数据 - cxSelect.getOptionData = function(index) { - var self = this; - - if (typeof index !== 'number' || isNaN(index) || index < 0 || index >= self.selectArray.length) {return}; - - var _indexPrev = index - 1; - var _select = self.selectArray[index]; - var _selectData; - var _valueIndex; - var _dataUrl = _select.data('url'); - var _jsonSpace = typeof _select.data('jsonSpace') === 'undefined' ? self.settings.jsonSpace : _select.data('jsonSpace'); - var _query = {}; - var _queryName; - var _selectName; - var _selectValue; - - cxSelect.clear.call(self, index); - - // 使用独立接口 - if (typeof _dataUrl === 'string' && _dataUrl.length) { - if (index > 0) { - for (var i = 0, j = 1; i < index; i++, j++) { - _queryName = self.selectArray[j].data('queryName'); - _selectName = self.selectArray[i].attr('name'); - _selectValue = self.selectArray[i].val(); - - if (typeof _queryName === 'string' && _queryName.length) { - _query[_queryName] = _selectValue; - } else if (typeof _selectName === 'string' && _selectName.length) { - _query[_selectName] = _selectValue; - }; - }; - }; - - $.getJSON(_dataUrl, _query, function(json) { - _selectData = cxSelect.getData(json, _jsonSpace); - - cxSelect.buildOption.call(self, index, _selectData); - }); - - // 使用整合数据 - } else if (self.settings.data && typeof self.settings.data === 'object') { - _selectData = self.settings.data; - - for (var i = 0; i < index; i++) { - _valueIndex = cxSelect.getIndex(self.selectArray[i][0].selectedIndex, typeof self.selectArray[i].data('required') === 'boolean' ? self.selectArray[i].data('required') : self.settings.required); - - if (typeof _selectData[_valueIndex] === 'object' && $.isArray(_selectData[_valueIndex][self.settings.jsonSub]) && _selectData[_valueIndex][self.settings.jsonSub].length) { - _selectData = _selectData[_valueIndex][self.settings.jsonSub]; - } else { - _selectData = null; - break; - }; - }; - - cxSelect.buildOption.call(self, index, _selectData); - }; - }; - - // 构建选项列表 - cxSelect.buildOption = function(index, data) { - var self = this; - - var _select = self.selectArray[index]; - var _required = typeof _select.data('required') === 'boolean' ? _select.data('required') : self.settings.required; - var _firstTitle = typeof _select.data('firstTitle') === 'undefined' ? self.settings.firstTitle : _select.data('firstTitle'); - var _firstValue = typeof _select.data('firstValue') === 'undefined' ? self.settings.firstValue : _select.data('firstValue'); - var _jsonName = typeof _select.data('jsonName') === 'undefined' ? self.settings.jsonName : _select.data('jsonName'); - var _jsonValue = typeof _select.data('jsonValue') === 'undefined' ? self.settings.jsonValue : _select.data('jsonValue'); - - if (!$.isArray(data)) {return}; - - var _html = !_required ? '' : ''; - - // 区分标题、值的数据 - if (typeof _jsonName === 'string' && _jsonName.length) { - // 无值字段时使用标题作为值 - if (typeof _jsonValue !== 'string' || !_jsonValue.length) { - _jsonValue = _jsonName; - }; - - for (var i = 0, l = data.length; i < l; i++) { - _html += ''; - }; - - // 数组即为值的数据 - } else { - for (var i = 0, l = data.length; i < l; i++) { - _html += ''; - }; - }; - - _select.html(_html).prop('disabled', false).css({ - 'display': '', - 'visibility': '' - }); - - // 初次加载设置默认值 - if (typeof _select.attr('data-value') === 'string') { - _select.val(String(_select.attr('data-value'))).removeAttr('data-value'); - - if (_select[0].selectedIndex < 0) { - _select[0].options[0].selected = true; - }; - }; - - if (_required || _select[0].selectedIndex > 0) { - _select.trigger('change'); - }; - - }; - - // 改变选择时的处理 - cxSelect.selectChange = function(name) { - var self = this; - - if (typeof name !== 'string' || !name.length) {return}; - - var index; - - name = name.replace(/\s+/g, ','); - name = ',' + name + ','; - - // 获取当前 select 位置 - for (var i = 0, l = self.selectArray.length; i < l; i++) { - if (name.indexOf(',' + self.settings.selects[i] + ',') > -1) { - index = i; - break; - }; - }; - - if (typeof index === 'number' && index > -1) { - index += 1; - cxSelect.getOptionData.call(self, index); - }; - }; - - $.cxSelect = function() { - return cxSelect.apply(this, arguments); - }; - - // 默认值 - $.cxSelect.defaults = { - selects: [], // 下拉选框组 - url: null, // 列表数据文件路径(URL)或数组数据 - data: null, // 自定义数据 - emptyStyle: null, // 无数据状态显示方式 - required: false, // 是否为必选 - firstTitle: '请选择', // 第一个选项的标题 - firstValue: '', // 第一个选项的值 - jsonSpace: '', // 数据命名空间 - jsonName: 'n', // 数据标题字段名称 - jsonValue: '', // 数据值字段名称 - jsonSub: 's' // 子集数据字段名称 - }; - - $.fn.cxSelect = function(settings, callback) { - this.each(function(i) { - $.cxSelect(this, settings, callback); - }); - return this; - }; -})); +/*! + * jQuery cxSelect + * @name jquery.cxselect.js + * @version 1.4.1 + * @date 2016-11-02 + * @author ciaoca + * @email ciaoca@gmail.com + * @site https://github.com/ciaoca/cxSelect + * @license Released under the MIT license + */ +(function(factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else { + factory(window.jQuery || window.Zepto || window.$); + }; +}(function($) { + var cxSelect = function() { + var self = this; + var dom, settings, callback; + + // 分配参数 + for (var i = 0, l = arguments.length; i < l; i++) { + if (cxSelect.isJquery(arguments[i]) || cxSelect.isZepto(arguments[i])) { + dom = arguments[i]; + } else if (cxSelect.isElement(arguments[i])) { + dom = $(arguments[i]); + } else if (typeof arguments[i] === 'function') { + callback = arguments[i]; + } else if (typeof arguments[i] === 'object') { + settings = arguments[i]; + }; + }; + + var api = new cxSelect.init(dom, settings); + + if (typeof callback === 'function') { + callback(api); + }; + + return api; + }; + + cxSelect.isElement = function(o){ + if (o && (typeof HTMLElement === 'function' || typeof HTMLElement === 'object') && o instanceof HTMLElement) { + return true; + } else { + return (o && o.nodeType && o.nodeType === 1) ? true : false; + }; + }; + + cxSelect.isJquery = function(o){ + return (o && o.length && (typeof jQuery === 'function' || typeof jQuery === 'object') && o instanceof jQuery) ? true : false; + }; + + cxSelect.isZepto = function(o){ + return (o && o.length && (typeof Zepto === 'function' || typeof Zepto === 'object') && Zepto.zepto.isZ(o)) ? true : false; + }; + + cxSelect.getIndex = function(n, required) { + return required ? n : n - 1; + }; + + cxSelect.getData = function(data, space) { + if (typeof space === 'string' && space.length) { + space = space.split('.'); + for (var i = 0, l = space.length; i < l; i++) { + data = data[space[i]]; + }; + }; + return data; + }; + + cxSelect.init = function(dom, settings) { + var self = this; + + if (!cxSelect.isJquery(dom) && !cxSelect.isZepto(dom)) {return}; + + var theSelect = { + dom: { + box: dom + } + }; + + self.attach = cxSelect.attach.bind(theSelect); + self.detach = cxSelect.detach.bind(theSelect); + self.setOptions = cxSelect.setOptions.bind(theSelect); + self.clear = cxSelect.clear.bind(theSelect); + + theSelect.changeEvent = function() { + cxSelect.selectChange.call(theSelect, this.className); + }; + + theSelect.settings = $.extend({}, $.cxSelect.defaults, settings, { + url: theSelect.dom.box.data('url'), + emptyStyle: theSelect.dom.box.data('emptyStyle'), + required: theSelect.dom.box.data('required'), + firstTitle: theSelect.dom.box.data('firstTitle'), + firstValue: theSelect.dom.box.data('firstValue'), + jsonSpace: theSelect.dom.box.data('jsonSpace'), + jsonName: theSelect.dom.box.data('jsonName'), + jsonValue: theSelect.dom.box.data('jsonValue'), + jsonSub: theSelect.dom.box.data('jsonSub') + }); + + var _dataSelects = theSelect.dom.box.data('selects'); + + if (typeof _dataSelects === 'string' && _dataSelects.length) { + theSelect.settings.selects = _dataSelects.split(','); + }; + + self.setOptions(); + self.attach(); + + // 使用独立接口获取数据 + if (!theSelect.settings.url && !theSelect.settings.data) { + cxSelect.start.apply(theSelect); + + // 设置自定义数据 + } else if ($.isArray(theSelect.settings.data)) { + cxSelect.start.call(theSelect, theSelect.settings.data); + + // 设置 URL,通过 Ajax 获取数据 + } else if (typeof theSelect.settings.url === 'string' && theSelect.settings.url.length) { + $.getJSON(theSelect.settings.url, function(json) { + cxSelect.start.call(theSelect, json); + }); + }; + }; + + // 设置参数 + cxSelect.setOptions = function(opts) { + var self = this; + + if (opts) { + $.extend(self.settings, opts); + }; + + // 初次或重设选择器组 + if (!$.isArray(self.selectArray) || !self.selectArray.length || (opts && opts.selects)) { + self.selectArray = []; + + if ($.isArray(self.settings.selects) && self.settings.selects.length) { + var _tempSelect; + + for (var i = 0, l = self.settings.selects.length; i < l; i++) { + _tempSelect = self.dom.box.find('select.' + self.settings.selects[i]); + + if (!_tempSelect || !_tempSelect.length) {break}; + + self.selectArray.push(_tempSelect); + }; + }; + }; + + if (opts) { + if (!$.isArray(opts.data) && typeof opts.url === 'string' && opts.url.length) { + $.getJSON(self.settings.url, function(json) { + cxSelect.start.call(self, json); + }); + + } else { + cxSelect.start.call(self, opts.data); + }; + }; + }; + + // 绑定 + cxSelect.attach = function() { + var self = this; + + if (!self.attachStatus) { + self.dom.box.on('change', 'select', self.changeEvent); + }; + + if (typeof self.attachStatus === 'boolean') { + cxSelect.start.call(self); + }; + + self.attachStatus = true; + }; + + // 移除绑定 + cxSelect.detach = function() { + var self = this; + self.dom.box.off('change', 'select', self.changeEvent); + self.attachStatus = false; + }; + + // 清空选项 + cxSelect.clear = function(index) { + var self = this; + var _style = { + display: '', + visibility: '' + }; + + index = isNaN(index) ? 0 : index; + + // 清空后面的 select + for (var i = index, l = self.selectArray.length; i < l; i++) { + self.selectArray[i].empty().prop('disabled', true); + + if (self.settings.emptyStyle === 'none') { + _style.display = 'none'; + } else if (self.settings.emptyStyle === 'hidden') { + _style.visibility = 'hidden'; + }; + + self.selectArray[i].css(_style); + }; + }; + + cxSelect.start = function(data) { + var self = this; + + if ($.isArray(data)) { + self.settings.data = cxSelect.getData(data, self.settings.jsonSpace); + }; + + if (!self.selectArray.length) {return}; + + // 保存默认值 + for (var i = 0, l = self.selectArray.length; i < l; i++) { + if (typeof self.selectArray[i].attr('data-value') !== 'string' && self.selectArray[i][0].options.length) { + self.selectArray[i].attr('data-value', self.selectArray[i].val()); + }; + }; + + if (self.settings.data || (typeof self.selectArray[0].data('url') === 'string' && self.selectArray[0].data('url').length)) { + cxSelect.getOptionData.call(self, 0); + } else { + self.selectArray[0].prop('disabled', false).css({ + 'display': '', + 'visibility': '' + }); + }; + }; + + // 获取选项数据 + cxSelect.getOptionData = function(index) { + var self = this; + + if (typeof index !== 'number' || isNaN(index) || index < 0 || index >= self.selectArray.length) {return}; + + var _indexPrev = index - 1; + var _select = self.selectArray[index]; + var _selectData; + var _valueIndex; + var _dataUrl = _select.data('url'); + var _jsonSpace = typeof _select.data('jsonSpace') === 'undefined' ? self.settings.jsonSpace : _select.data('jsonSpace'); + var _query = {}; + var _queryName; + var _selectName; + var _selectValue; + + cxSelect.clear.call(self, index); + + // 使用独立接口 + if (typeof _dataUrl === 'string' && _dataUrl.length) { + if (index > 0) { + for (var i = 0, j = 1; i < index; i++, j++) { + _queryName = self.selectArray[j].data('queryName'); + _selectName = self.selectArray[i].attr('name'); + _selectValue = self.selectArray[i].val(); + + if (typeof _queryName === 'string' && _queryName.length) { + _query[_queryName] = _selectValue; + } else if (typeof _selectName === 'string' && _selectName.length) { + _query[_selectName] = _selectValue; + }; + }; + }; + + $.getJSON(_dataUrl, _query, function(json) { + _selectData = cxSelect.getData(json, _jsonSpace); + + cxSelect.buildOption.call(self, index, _selectData); + }); + + // 使用整合数据 + } else if (self.settings.data && typeof self.settings.data === 'object') { + _selectData = self.settings.data; + + for (var i = 0; i < index; i++) { + _valueIndex = cxSelect.getIndex(self.selectArray[i][0].selectedIndex, typeof self.selectArray[i].data('required') === 'boolean' ? self.selectArray[i].data('required') : self.settings.required); + + if (typeof _selectData[_valueIndex] === 'object' && $.isArray(_selectData[_valueIndex][self.settings.jsonSub]) && _selectData[_valueIndex][self.settings.jsonSub].length) { + _selectData = _selectData[_valueIndex][self.settings.jsonSub]; + } else { + _selectData = null; + break; + }; + }; + + cxSelect.buildOption.call(self, index, _selectData); + }; + }; + + // 构建选项列表 + cxSelect.buildOption = function(index, data) { + var self = this; + + var _select = self.selectArray[index]; + var _required = typeof _select.data('required') === 'boolean' ? _select.data('required') : self.settings.required; + var _firstTitle = typeof _select.data('firstTitle') === 'undefined' ? self.settings.firstTitle : _select.data('firstTitle'); + var _firstValue = typeof _select.data('firstValue') === 'undefined' ? self.settings.firstValue : _select.data('firstValue'); + var _jsonName = typeof _select.data('jsonName') === 'undefined' ? self.settings.jsonName : _select.data('jsonName'); + var _jsonValue = typeof _select.data('jsonValue') === 'undefined' ? self.settings.jsonValue : _select.data('jsonValue'); + + if (!$.isArray(data)) {return}; + + var _html = !_required ? '' : ''; + + // 区分标题、值的数据 + if (typeof _jsonName === 'string' && _jsonName.length) { + // 无值字段时使用标题作为值 + if (typeof _jsonValue !== 'string' || !_jsonValue.length) { + _jsonValue = _jsonName; + }; + + for (var i = 0, l = data.length; i < l; i++) { + _html += ''; + }; + + // 数组即为值的数据 + } else { + for (var i = 0, l = data.length; i < l; i++) { + _html += ''; + }; + }; + + _select.html(_html).prop('disabled', false).css({ + 'display': '', + 'visibility': '' + }); + + // 初次加载设置默认值 + if (typeof _select.attr('data-value') === 'string') { + _select.val(String(_select.attr('data-value'))).removeAttr('data-value'); + + if (_select[0].selectedIndex < 0) { + _select[0].options[0].selected = true; + }; + }; + + if (_required || _select[0].selectedIndex > 0) { + _select.trigger('change'); + }; + + }; + + // 改变选择时的处理 + cxSelect.selectChange = function(name) { + var self = this; + + if (typeof name !== 'string' || !name.length) {return}; + + var index; + + name = name.replace(/\s+/g, ','); + name = ',' + name + ','; + + // 获取当前 select 位置 + for (var i = 0, l = self.selectArray.length; i < l; i++) { + if (name.indexOf(',' + self.settings.selects[i] + ',') > -1) { + index = i; + break; + }; + }; + + if (typeof index === 'number' && index > -1) { + index += 1; + cxSelect.getOptionData.call(self, index); + }; + }; + + $.cxSelect = function() { + return cxSelect.apply(this, arguments); + }; + + // 默认值 + $.cxSelect.defaults = { + selects: [], // 下拉选框组 + url: null, // 列表数据文件路径(URL)或数组数据 + data: null, // 自定义数据 + emptyStyle: null, // 无数据状态显示方式 + required: false, // 是否为必选 + firstTitle: '请选择', // 第一个选项的标题 + firstValue: '', // 第一个选项的值 + jsonSpace: '', // 数据命名空间 + jsonName: 'n', // 数据标题字段名称 + jsonValue: '', // 数据值字段名称 + jsonSub: 's' // 子集数据字段名称 + }; + + $.fn.cxSelect = function(settings, callback) { + this.each(function(i) { + $.cxSelect(this, settings, callback); + }); + return this; + }; +})); diff --git a/app/assets/javascripts/jquery.cxselect.min.js b/app/assets/javascripts/jquery.cxselect.min.js old mode 100755 new mode 100644 index 54549a920..9aabba447 --- a/app/assets/javascripts/jquery.cxselect.min.js +++ b/app/assets/javascripts/jquery.cxselect.min.js @@ -1,11 +1,11 @@ -/*! - * jQuery cxSelect - * @name jquery.cxselect.js - * @version 1.4.1 - * @date 2016-11-02 - * @author ciaoca - * @email ciaoca@gmail.com - * @site https://github.com/ciaoca/cxSelect - * @license Released under the MIT license - */ +/*! + * jQuery cxSelect + * @name jquery.cxselect.js + * @version 1.4.1 + * @date 2016-11-02 + * @author ciaoca + * @email ciaoca@gmail.com + * @site https://github.com/ciaoca/cxSelect + * @license Released under the MIT license + */ !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a(window.jQuery||window.Zepto||window.$)}(function(a){var b=function(){var d,e,f,g,h,i;for(g=0,h=arguments.length;h>g;g++)b.isJquery(arguments[g])||b.isZepto(arguments[g])?d=arguments[g]:b.isElement(arguments[g])?d=a(arguments[g]):"function"==typeof arguments[g]?f=arguments[g]:"object"==typeof arguments[g]&&(e=arguments[g]);return i=new b.init(d,e),"function"==typeof f&&f(i),i};b.isElement=function(a){return a&&("function"==typeof HTMLElement||"object"==typeof HTMLElement)&&a instanceof HTMLElement?!0:a&&a.nodeType&&1===a.nodeType?!0:!1},b.isJquery=function(a){return a&&a.length&&("function"==typeof jQuery||"object"==typeof jQuery)&&a instanceof jQuery?!0:!1},b.isZepto=function(a){return a&&a.length&&("function"==typeof Zepto||"object"==typeof Zepto)&&Zepto.zepto.isZ(a)?!0:!1},b.getIndex=function(a,b){return b?a:a-1},b.getData=function(a,b){if("string"==typeof b&&b.length){b=b.split(".");for(var c=0,d=b.length;d>c;c++)a=a[b[c]]}return a},b.init=function(c,d){var f,g,e=this;(b.isJquery(c)||b.isZepto(c))&&(f={dom:{box:c}},e.attach=b.attach.bind(f),e.detach=b.detach.bind(f),e.setOptions=b.setOptions.bind(f),e.clear=b.clear.bind(f),f.changeEvent=function(){b.selectChange.call(f,this.className)},f.settings=a.extend({},a.cxSelect.defaults,d,{url:f.dom.box.data("url"),emptyStyle:f.dom.box.data("emptyStyle"),required:f.dom.box.data("required"),firstTitle:f.dom.box.data("firstTitle"),firstValue:f.dom.box.data("firstValue"),jsonSpace:f.dom.box.data("jsonSpace"),jsonName:f.dom.box.data("jsonName"),jsonValue:f.dom.box.data("jsonValue"),jsonSub:f.dom.box.data("jsonSub")}),g=f.dom.box.data("selects"),"string"==typeof g&&g.length&&(f.settings.selects=g.split(",")),e.setOptions(),e.attach(),f.settings.url||f.settings.data?a.isArray(f.settings.data)?b.start.call(f,f.settings.data):"string"==typeof f.settings.url&&f.settings.url.length&&a.getJSON(f.settings.url,function(a){b.start.call(f,a)}):b.start.apply(f))},b.setOptions=function(c){var e,f,g,d=this;if(c&&a.extend(d.settings,c),(!a.isArray(d.selectArray)||!d.selectArray.length||c&&c.selects)&&(d.selectArray=[],a.isArray(d.settings.selects)&&d.settings.selects.length))for(f=0,g=d.settings.selects.length;g>f&&(e=d.dom.box.find("select."+d.settings.selects[f]),e&&e.length);f++)d.selectArray.push(e);c&&(!a.isArray(c.data)&&"string"==typeof c.url&&c.url.length?a.getJSON(d.settings.url,function(a){b.start.call(d,a)}):b.start.call(d,c.data))},b.attach=function(){var a=this;a.attachStatus||a.dom.box.on("change","select",a.changeEvent),"boolean"==typeof a.attachStatus&&b.start.call(a),a.attachStatus=!0},b.detach=function(){var a=this;a.dom.box.off("change","select",a.changeEvent),a.attachStatus=!1},b.clear=function(a){var d,e,b=this,c={display:"",visibility:""};for(a=isNaN(a)?0:a,d=a,e=b.selectArray.length;e>d;d++)b.selectArray[d].empty().prop("disabled",!0),"none"===b.settings.emptyStyle?c.display="none":"hidden"===b.settings.emptyStyle&&(c.visibility="hidden"),b.selectArray[d].css(c)},b.start=function(c){var e,f,d=this;if(a.isArray(c)&&(d.settings.data=b.getData(c,d.settings.jsonSpace)),d.selectArray.length){for(e=0,f=d.selectArray.length;f>e;e++)"string"!=typeof d.selectArray[e].attr("data-value")&&d.selectArray[e][0].options.length&&d.selectArray[e].attr("data-value",d.selectArray[e].val());d.settings.data||"string"==typeof d.selectArray[0].data("url")&&d.selectArray[0].data("url").length?b.getOptionData.call(d,0):d.selectArray[0].prop("disabled",!1).css({display:"",visibility:""})}},b.getOptionData=function(c){var f,g,h,i,j,k,l,m,n,o,p,d=this;if(!("number"!=typeof c||isNaN(c)||0>c||c>=d.selectArray.length))if(f=d.selectArray[c],i=f.data("url"),j="undefined"==typeof f.data("jsonSpace")?d.settings.jsonSpace:f.data("jsonSpace"),k={},b.clear.call(d,c),"string"==typeof i&&i.length){if(c>0)for(o=0,p=1;c>o;o++,p++)l=d.selectArray[p].data("queryName"),m=d.selectArray[o].attr("name"),n=d.selectArray[o].val(),"string"==typeof l&&l.length?k[l]=n:"string"==typeof m&&m.length&&(k[m]=n);a.getJSON(i,k,function(a){g=b.getData(a,j),b.buildOption.call(d,c,g)})}else if(d.settings.data&&"object"==typeof d.settings.data){for(g=d.settings.data,o=0;c>o;o++){if(h=b.getIndex(d.selectArray[o][0].selectedIndex,"boolean"==typeof d.selectArray[o].data("required")?d.selectArray[o].data("required"):d.settings.required),"object"!=typeof g[h]||!a.isArray(g[h][d.settings.jsonSub])||!g[h][d.settings.jsonSub].length){g=null;break}g=g[h][d.settings.jsonSub]}b.buildOption.call(d,c,g)}},b.buildOption=function(b,c){var k,l,m,d=this,e=d.selectArray[b],f="boolean"==typeof e.data("required")?e.data("required"):d.settings.required,g="undefined"==typeof e.data("firstTitle")?d.settings.firstTitle:e.data("firstTitle"),h="undefined"==typeof e.data("firstValue")?d.settings.firstValue:e.data("firstValue"),i="undefined"==typeof e.data("jsonName")?d.settings.jsonName:e.data("jsonName"),j="undefined"==typeof e.data("jsonValue")?d.settings.jsonValue:e.data("jsonValue");if(a.isArray(c)){if(k=f?"":'","string"==typeof i&&i.length)for("string"==typeof j&&j.length||(j=i),l=0,m=c.length;m>l;l++)k+='";else for(l=0,m=c.length;m>l;l++)k+='";e.html(k).prop("disabled",!1).css({display:"",visibility:""}),"string"==typeof e.attr("data-value")&&(e.val(String(e.attr("data-value"))).removeAttr("data-value"),e[0].selectedIndex<0&&(e[0].options[0].selected=!0)),(f||e[0].selectedIndex>0)&&e.trigger("change")}},b.selectChange=function(a){var d,e,f,c=this;if("string"==typeof a&&a.length){for(a=a.replace(/\s+/g,","),a=","+a+",",e=0,f=c.selectArray.length;f>e;e++)if(a.indexOf(","+c.settings.selects[e]+",")>-1){d=e;break}"number"==typeof d&&d>-1&&(d+=1,b.getOptionData.call(c,d))}},a.cxSelect=function(){return b.apply(this,arguments)},a.cxSelect.defaults={selects:[],url:null,data:null,emptyStyle:null,required:!1,firstTitle:"请选择",firstValue:"",jsonSpace:"",jsonName:"n",jsonValue:"",jsonSub:"s"},a.fn.cxSelect=function(b,c){return this.each(function(){a.cxSelect(this,b,c)}),this}}); \ No newline at end of file diff --git a/app/assets/javascripts/jquery.validate.js b/app/assets/javascripts/jquery.validate.js index 70297bd5c..d025319db 100644 --- a/app/assets/javascripts/jquery.validate.js +++ b/app/assets/javascripts/jquery.validate.js @@ -1,21 +1,21 @@ -/*! - * jQuery Validation Plugin v1.19.1 - * - * https://jqueryvalidation.org/ - * - * Copyright (c) 2019 Jörn Zaefferer - * Released under the MIT license - */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - define( ["jquery"], factory ); - } else if (typeof module === "object" && module.exports) { - module.exports = factory( require( "jquery" ) ); - } else { - factory( jQuery ); - } -}(function( $ ) { - +/*! + * jQuery Validation Plugin v1.19.1 + * + * https://jqueryvalidation.org/ + * + * Copyright (c) 2019 Jörn Zaefferer + * Released under the MIT license + */ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + define( ["jquery"], factory ); + } else if (typeof module === "object" && module.exports) { + module.exports = factory( require( "jquery" ) ); + } else { + factory( jQuery ); + } +}(function( $ ) { + $.extend( $.fn, { // https://jqueryvalidation.org/validate/ @@ -1610,7 +1610,7 @@ $.extend( $.validator, { } } ); - + // Ajax mode: abort // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() @@ -1646,5 +1646,5 @@ if ( $.ajaxPrefilter ) { return ajax.apply( this, arguments ); }; } -return $; +return $; })); \ No newline at end of file diff --git a/app/assets/javascripts/select2.js b/app/assets/javascripts/select2.js old mode 100755 new mode 100644 diff --git a/app/assets/javascripts/select2.min.js b/app/assets/javascripts/select2.min.js old mode 100755 new mode 100644 diff --git a/app/assets/stylesheets/admins/daily-school-statistics.scss b/app/assets/stylesheets/admins/daily_school_statistics.scss similarity index 100% rename from app/assets/stylesheets/admins/daily-school-statistics.scss rename to app/assets/stylesheets/admins/daily_school_statistics.scss diff --git a/app/assets/stylesheets/admins/identity-authentications.scss b/app/assets/stylesheets/admins/identity_authentications.scss similarity index 100% rename from app/assets/stylesheets/admins/identity-authentications.scss rename to app/assets/stylesheets/admins/identity_authentications.scss diff --git a/app/assets/stylesheets/admins/professional-authentications.scss b/app/assets/stylesheets/admins/professional_authentications.scss similarity index 100% rename from app/assets/stylesheets/admins/professional-authentications.scss rename to app/assets/stylesheets/admins/professional_authentications.scss diff --git a/app/assets/stylesheets/admins/school-statistics.scss b/app/assets/stylesheets/admins/school_statistics.scss similarity index 100% rename from app/assets/stylesheets/admins/school-statistics.scss rename to app/assets/stylesheets/admins/school_statistics.scss diff --git a/app/assets/stylesheets/admins/shixun_authorizations.scss b/app/assets/stylesheets/admins/shixun_authorizations.scss new file mode 100644 index 000000000..05bcbc2bb --- /dev/null +++ b/app/assets/stylesheets/admins/shixun_authorizations.scss @@ -0,0 +1,9 @@ +.admins-shixun-authorizations-index-page { + .shixun-authorization-list-container { + span { + &.apply-status-1 { color: #28a745; } + &.apply-status-2 { color: #dc3545; } + &.apply-status-3 { color: #6c757d; } + } + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/admins/subject_authorizations.scss b/app/assets/stylesheets/admins/subject_authorizations.scss new file mode 100644 index 000000000..f16c30151 --- /dev/null +++ b/app/assets/stylesheets/admins/subject_authorizations.scss @@ -0,0 +1,9 @@ +.admins-subject-authorizations-index-page { + .subject-authorization-list-container { + span { + &.apply-status-1 { color: #28a745; } + &.apply-status-2 { color: #dc3545; } + &.apply-status-3 { color: #6c757d; } + } + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/select2-bootstrap4.min.scss b/app/assets/stylesheets/select2-bootstrap4.min.scss old mode 100755 new mode 100644 diff --git a/app/assets/stylesheets/select2.min.scss b/app/assets/stylesheets/select2.min.scss old mode 100755 new mode 100644 diff --git a/app/controllers/admins/shixun_authorizations_controller.rb b/app/controllers/admins/shixun_authorizations_controller.rb new file mode 100644 index 000000000..31bd5faf7 --- /dev/null +++ b/app/controllers/admins/shixun_authorizations_controller.rb @@ -0,0 +1,48 @@ +class Admins::ShixunAuthorizationsController < Admins::BaseController + def index + params[:status] ||= 'pending' + + applies = ApplyAction.where(container_type: 'ApplyShixun') + + status = + case params[:status] + when 'pending' then 0 + when 'processed' then [1, 2] + when 'agreed' then 1 + when 'refused' then 2 + else 0 + end + applies = applies.where(status: status) if status.present? + + # 关键字模糊查询 + keyword = params[:keyword].to_s.strip + if keyword.present? + applies = applies.joins('JOIN shixuns ON shixuns.id = apply_actions.container_id') + .where('shixuns.name LIKE :keyword', keyword: "%#{keyword}%") + end + + applies = applies.order(updated_at: :desc) + + @applies = paginate applies.includes(user: :user_extension) + + shixun_ids = @applies.map(&:container_id) + @shixun_map = Shixun.where(id: shixun_ids).each_with_object({}) { |s, h| h[s.id] = s } + end + + def agree + Admins::ShixunAuths::AgreeApplyService.call(current_apply, current_user) + render_success_js + end + + def refuse + Admins::ShixunAuths::RefuseApplyService.call(current_apply, current_user, params) + + render_success_js + end + + private + + def current_apply + @_current_apply ||= ApplyAction.where(container_type: 'ApplyShixun').find(params[:id]) + end +end \ No newline at end of file diff --git a/app/controllers/admins/subject_authorizations_controller.rb b/app/controllers/admins/subject_authorizations_controller.rb new file mode 100644 index 000000000..3d3733fa4 --- /dev/null +++ b/app/controllers/admins/subject_authorizations_controller.rb @@ -0,0 +1,49 @@ +class Admins::SubjectAuthorizationsController < Admins::BaseController + def index + params[:status] ||= 'pending' + + applies = ApplyAction.where(container_type: 'ApplySubject') + + status = + case params[:status] + when 'pending' then 0 + when 'processed' then [1, 2] + when 'agreed' then 1 + when 'refused' then 2 + else 0 + end + applies = applies.where(status: status) if status.present? + + # 关键字模糊查询 + keyword = params[:keyword].to_s.strip + if keyword.present? + applies = applies.joins('JOIN subjects ON subjects.id = apply_actions.container_id') + .where('subjects.name LIKE :keyword', keyword: "%#{keyword}%") + end + + applies = applies.order(updated_at: :desc) + + @applies = paginate applies.includes(user: :user_extension) + + subject_ids = @applies.map(&:container_id) + @subject_map = Subject.where(id: subject_ids).each_with_object({}) { |s, h| h[s.id] = s } + @challenge_count_map = Challenge.joins(shixun: :stage_shixuns).where(st: 0, stage_shixuns: { subject_id: subject_ids}).group('subject_id').count + end + + def agree + Admins::SubjectAuths::AgreeApplyService.call(current_apply, current_user) + render_success_js + end + + def refuse + Admins::SubjectAuths::RefuseApplyService.call(current_apply, current_user, params) + + render_success_js + end + + private + + def current_apply + @_current_apply ||= ApplyAction.where(container_type: 'ApplySubject').find(params[:id]) + end +end \ No newline at end of file diff --git a/app/controllers/challenges_controller.rb b/app/controllers/challenges_controller.rb index 9e87d3799..0f6532372 100644 --- a/app/controllers/challenges_controller.rb +++ b/app/controllers/challenges_controller.rb @@ -74,6 +74,7 @@ class ChallengesController < ApplicationController ChallengeTag.create(:name => tag, :challenge_choose_id => @challenge_choose.id, :challenge_id => @challenge.id) end end + @challenge.update_column(:score, @challenge.challenge_chooses.sum(:score)) end rescue Exception => e raise ActiveRecord::Rollback @@ -95,6 +96,7 @@ class ChallengesController < ApplicationController @challenge.update_column(:modify_time, Time.now) end @challenge_choose.update_attributes(chooce_params) + @challenge.update_column(:score, @challenge.challenge_chooses.sum(:score)) # 单选多选题的更新 category = @challenge_choose.standard_answer.length > 1 ? 2 : 1 @challenge_choose.update_column(:category, category) @@ -208,6 +210,9 @@ class ChallengesController < ApplicationController # 测试集的 @shixun.myshixuns.update_all(:system_tip => 0) end + if params[:challenge][:show_type].to_i == -1 + @challenge.update_attributes(picture_path: nil, web_route: nil, expect_picture_path: nil, original_picture_path: nil) + end # 关卡评测执行文件如果被修改,需要修改脚本内容 script = modify_shixun_script @shixun, @shixun.evaluate_script @shixun.shixun_info.update_column(:evaluate_script, script) diff --git a/app/controllers/concerns/admins/error_rescue_handler.rb b/app/controllers/concerns/admins/error_rescue_handler.rb index b1e29d5ce..ceb810f36 100644 --- a/app/controllers/concerns/admins/error_rescue_handler.rb +++ b/app/controllers/concerns/admins/error_rescue_handler.rb @@ -2,7 +2,7 @@ module Admins::ErrorRescueHandler extend ActiveSupport::Concern included do - rescue_from Exception, Educoder::TipException do |e| + rescue_from Exception do |e| raise e if Rails.env.development? Util.logger_error e diff --git a/app/controllers/concerns/admins/render_helper.rb b/app/controllers/concerns/admins/render_helper.rb index 3651f892b..0ccc16a09 100644 --- a/app/controllers/concerns/admins/render_helper.rb +++ b/app/controllers/concerns/admins/render_helper.rb @@ -28,7 +28,7 @@ module Admins::RenderHelper def internal_server_error respond_to do |format| format.html { render 'admins/shared/500' } - format.js { render_js_error(message) } + format.js { render_js_error('系统错误') } format.json { render status: 500, json: { message: '系统错误' } } end end diff --git a/app/controllers/games_controller.rb b/app/controllers/games_controller.rb index c7a598a43..0064914d3 100644 --- a/app/controllers/games_controller.rb +++ b/app/controllers/games_controller.rb @@ -13,8 +13,8 @@ class GamesController < ApplicationController def show uid_logger("--games show start") # 防止评测中途ajaxE被取消;3改成0是为了处理首次进入下一关的问题 - @game.update_attribute(:status, 0) if @game.status == 1 - @game.update_attributes(status: 0, open_time: Time.now) if @game.status == 3 + update_game_parameter(@game) + game_challenge = Challenge.base_attrs.find(@game.challenge_id) # 选择题类型的实训关卡总分 @@ -739,7 +739,7 @@ class GamesController < ApplicationController experience = 0 game_status = @game.status had_done = @game.had_done - game_challenge = Challenge.select([:id, :score, :position, :shixun_id, :web_route]).find(@game.challenge_id) + game_challenge = Challenge.select([:id, :score, :position, :shixun_id, :web_route, :show_type]).find(@game.challenge_id) if params[:resubmit].blank? # 非重新评测 if game_status == 2 # 通关 @@ -765,9 +765,10 @@ class GamesController < ApplicationController testset_detail max_query_index.to_i, game_challenge # 处理生成图片类型文件 - picture = (@game.picture_path.nil? ? 0 : @game.id) + picture = (game_challenge.show_type.to_i == -1 || @game.picture_path.nil?) ? 0 : @game.id # 针对web类型的实训 web_route = game_challenge.try(:web_route) + mirror_name = @shixun.mirror_name e_record = EvaluateRecord.where(:identifier => sec_key).first @@ -964,4 +965,13 @@ class GamesController < ApplicationController nil end end + + # 更新关卡状态和一些学习进度 + def update_game_parameter game + game.update_attribute(:status, 0) if game.status == 1 + game.update_attributes(status: 0, open_time: Time.now) if game.status == 3 + # 开启实训更新myshixuns的时间,方便跟踪用于的学习进度。 + game.myshixun.update_column(:updated_at, Time.now) + end + end diff --git a/app/controllers/subjects_controller.rb b/app/controllers/subjects_controller.rb index a62707536..5b926ee48 100644 --- a/app/controllers/subjects_controller.rb +++ b/app/controllers/subjects_controller.rb @@ -101,8 +101,9 @@ class SubjectsController < ApplicationController @tags = ChallengeTag.where(challenge_id: challenge_ids).pluck(:name).uniq # 用户获取的实训标签 # @user_tags = @subject.shixuns.map(&:user_tags_name).flatten.uniq - @user_tags = user_shixun_tags challenge_ids, @user.id - @my_subject_progress = @subject.my_subject_progress + + # 用户进展 + user_subject_progress(challenge_ids) end def new @@ -436,4 +437,33 @@ class SubjectsController < ApplicationController tip_exception("403", "") end end + + # 用户进展和获取的标签 + def user_subject_progress challenge_ids + pass_games = Game.select(:id, :cost_time, :challenge_id).where(status: 2, user_id: current_user.id, challenge_id: challenge_ids) if current_user.logged? + @all_score = Challenge.where(id: challenge_ids).sum(:score) + + # 如果没有通关的,没必要再继续统计了 + if pass_games.blank? + @my_score = 0 + @learned = 0 + @time = 0 + @user_tags = [] + else + pass_challenge_ids = pass_games.map(&:challenge_id) + subject_challenge_count = @subject.shixuns.sum(:challenges_count) + # 用户通关获得的标签 + @user_tags = ChallengeTag.where(challenge_id: pass_challenge_ids).pluck(:name) + # 用户学习进度 + @learned = + subject_challenge_count == 0 ? 0 : + ((pass_challenge_ids.size.to_f / subject_challenge_count).round(2) * 100).to_i + # 用户通关分数 + @my_score = Challenge.where(id: pass_challenge_ids).pluck(:score).sum + @time = pass_games.map(&:cost_time).sum + end + + + end + end diff --git a/app/models/apply_action.rb b/app/models/apply_action.rb index 2d31f394d..54bdaa396 100644 --- a/app/models/apply_action.rb +++ b/app/models/apply_action.rb @@ -1,8 +1,16 @@ # 申请消息 class ApplyAction < ApplicationRecord + belongs_to :user + has_many :tidings, :as => :container, :dependent => :destroy after_create :send_tiding + def status_text + I18n.t!("apply_action.status.#{status}") + rescue I18n::MissingTranslationData + nil + end + def send_tiding if container_type == 'TrialAuthorization' && status == 1 tidings.create(user_id: user_id, trigger_user_id: 0, status: 1, viewed: 0, tiding_type: 'System', diff --git a/app/models/challenge.rb b/app/models/challenge.rb index adb54fae9..8087fd6ab 100644 --- a/app/models/challenge.rb +++ b/app/models/challenge.rb @@ -40,16 +40,18 @@ class Challenge < ApplicationRecord ## 选择题总分 def choose_score - self.challenge_chooses.pluck(:score).sum + self.score + #self.challenge_chooses.pluck(:score).sum end # 关卡总分 def all_score - if self.st == 1 - self.choose_score - else - self.score - end + self.score + # if self.st == 1 + # self.choose_score + # else + # self.score + # end end # 开启挑战 diff --git a/app/models/game.rb b/app/models/game.rb index d81b794a5..d7c68dd5f 100644 --- a/app/models/game.rb +++ b/app/models/game.rb @@ -31,7 +31,7 @@ class Game < ApplicationRecord # 根据得分比例来算实际得分(试卷、实训作业) def real_score score - ((final_score < 0 ? 0 : final_score).to_f / challenge.all_score) * score + ((final_score < 0 ? 0 : final_score).to_f / challenge.score) * score end # 判断实训是否全部通关 diff --git a/app/models/shixun.rb b/app/models/shixun.rb index 81b444c0a..d61ba45b9 100644 --- a/app/models/shixun.rb +++ b/app/models/shixun.rb @@ -192,11 +192,7 @@ class Shixun < ApplicationRecord # 实训关卡的总分(由于大部分是实践题,因此没关联查choose表) # 提前加载问题:由于选择题比较少,所以几乎不会触发选择题的查询,所以没必要提前载入choose_score def all_score - sum = 0 - challenges.each do |challenge| - sum += challenge.st == 0 ? challenge.score : challenge.choose_score - end - sum + self.challenges.pluck(:score).sum end ### fork 数量 diff --git a/app/models/subject.rb b/app/models/subject.rb index 7b671cfb1..4b7f4dbcd 100644 --- a/app/models/subject.rb +++ b/app/models/subject.rb @@ -83,7 +83,7 @@ class Subject < ApplicationRecord def my_subject_progress my_challenge_count = Game.joins(:challenge).where(user_id: User.current.id, status: 2, challenges: {shixun_id: shixuns.published_closed}). - pluck(:challenge_id).uniq.size + pluck(:challenge_id).uniq.size count = self.subject_challenge_count == 0 ? 0 : ((my_challenge_count.to_f / self.subject_challenge_count).round(2) * 100).to_i end diff --git a/app/services/admins/shixun_auths/agree_apply_service.rb b/app/services/admins/shixun_auths/agree_apply_service.rb new file mode 100644 index 000000000..4734e03bb --- /dev/null +++ b/app/services/admins/shixun_auths/agree_apply_service.rb @@ -0,0 +1,43 @@ +class Admins::ShixunAuths::AgreeApplyService < ApplicationService + attr_reader :apply, :user, :shixun + + def initialize(apply, user) + @apply = apply + @user = user + @shixun = Shixun.find(apply.container_id) + end + + def call + ActiveRecord::Base.transaction do + apply.update!(status: 1, dealer_id: user.id) + shixun.update!(status: 2, publish_time: Time.now) + + # 奖励金币、经验 + reward_grade_and_experience! + + deal_tiding! + end + end + + private + + def reward_grade_and_experience! + score = shixun.all_score + shixun_creator = shixun.user + + RewardGradeService.call(shixun_creator, container_id: shixun.id, container_type: 'shixunPublish', score: score) + + Experience.create!(user_id: shixun_creator.id, container_id: shixun.id, container_type: 'shixunPublish', score: score) + shixun_creator.update_column(:experience, shixun_creator.experience.to_i + score) + end + + def deal_tiding! + apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1) + + Tiding.create!(user_id: apply.user_id, trigger_user_id: 0, + container_id: apply.id, container_type: 'ApplyAction', + parent_container_id: apply.container_id, parent_container_type: apply.container_type, + belong_container_id: apply.container_id, belong_container_type: 'Shixun', + status: 1, tiding_type: 'System') + end +end \ No newline at end of file diff --git a/app/services/admins/shixun_auths/refuse_apply_service.rb b/app/services/admins/shixun_auths/refuse_apply_service.rb new file mode 100644 index 000000000..49416a2b0 --- /dev/null +++ b/app/services/admins/shixun_auths/refuse_apply_service.rb @@ -0,0 +1,35 @@ +class Admins::ShixunAuths::RefuseApplyService < ApplicationService + attr_reader :apply, :user, :shixun, :params + + def initialize(apply, user, params) + @apply = apply + @user = user + @shixun = Shixun.find(apply.container_id) + @params = params + end + + def call + ActiveRecord::Base.transaction do + shixun.update!(status: 0) + apply.update!(status: 2, reason: reason, dealer_id: user.id) + + deal_tiding! + end + end + + private + + def reason + params[:reason].to_s.strip + end + + def deal_tiding! + apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1) + + Tiding.create!(user_id: apply.user_id, trigger_user_id: 0, + container_id: apply.id, container_type: 'ApplyAction', + parent_container_id: apply.container_id, parent_container_type: apply.container_type, + belong_container_id: apply.container_id, belong_container_type: 'Shixun', + status: 2, tiding_type: 'System') + end +end \ No newline at end of file diff --git a/app/services/admins/subject_auths/agree_apply_service.rb b/app/services/admins/subject_auths/agree_apply_service.rb new file mode 100644 index 000000000..465e3e903 --- /dev/null +++ b/app/services/admins/subject_auths/agree_apply_service.rb @@ -0,0 +1,30 @@ +class Admins::SubjectAuths::AgreeApplyService < ApplicationService + attr_reader :apply, :user, :subject + + def initialize(apply, user) + @apply = apply + @user = user + @subject = Subject.find(apply.container_id) + end + + def call + ActiveRecord::Base.transaction do + apply.update!(status: 1, dealer_id: user.id) + subject.update!(status: 2, publish_time: Time.now) + + deal_tiding! + end + end + + private + + def deal_tiding! + apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1) + + Tiding.create!(user_id: apply.user_id, trigger_user_id: 0, + container_id: apply.id, container_type: 'ApplyAction', + parent_container_id: apply.container_id, parent_container_type: apply.container_type, + belong_container_id: apply.container_id, belong_container_type: 'Subject', + status: 1, tiding_type: 'System') + end +end \ No newline at end of file diff --git a/app/services/admins/subject_auths/refuse_apply_service.rb b/app/services/admins/subject_auths/refuse_apply_service.rb new file mode 100644 index 000000000..f51d55185 --- /dev/null +++ b/app/services/admins/subject_auths/refuse_apply_service.rb @@ -0,0 +1,35 @@ +class Admins::SubjectAuths::RefuseApplyService < ApplicationService + attr_reader :apply, :user, :subject, :params + + def initialize(apply, user, params) + @apply = apply + @user = user + @subject = Subject.find(apply.container_id) + @params = params + end + + def call + ActiveRecord::Base.transaction do + subject.update!(status: 0) + apply.update!(status: 2, reason: reason, dealer_id: user.id) + + deal_tiding! + end + end + + private + + def reason + params[:reason].to_s.strip + end + + def deal_tiding! + apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1) + + Tiding.create!(user_id: apply.user_id, trigger_user_id: 0, + container_id: apply.id, container_type: 'ApplyAction', + parent_container_id: apply.container_id, parent_container_type: apply.container_type, + belong_container_id: apply.container_id, belong_container_type: 'Subject', + status: 2, tiding_type: 'System') + end +end \ No newline at end of file diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb index 2be899ebd..ab30e8bd3 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -41,6 +41,8 @@ <%= sidebar_item_group('#apply-review-submenu', '审核', icon: 'gavel') do %>
  • <%= sidebar_item(admins_identity_authentications_path, '实名认证', icon: 'id-card-o', controller: 'admins-identity_authentications') %>
  • <%= sidebar_item(admins_professional_authentications_path, '职业认证', icon: 'drivers-license', controller: 'admins-professional_authentications') %>
  • +
  • <%= sidebar_item(admins_shixun_authorizations_path, '实训发布', icon: 'object-ungroup', controller: 'admins-shixun_authorizations') %>
  • +
  • <%= sidebar_item(admins_subject_authorizations_path, '实践课程发布', icon: 'object-group', controller: 'admins-subject_authorizations') %>
  • <% end %> diff --git a/app/views/admins/shared/error.js.erb b/app/views/admins/shared/error.js.erb index ebb78aec6..261796d0b 100644 --- a/app/views/admins/shared/error.js.erb +++ b/app/views/admins/shared/error.js.erb @@ -4,4 +4,7 @@ setTimeout(function() { if ($('.admin-alert-container button.close').length > 0) { $('.admin-alert-container button.close').trigger('click'); } -}, 2000) \ No newline at end of file +}, 5000) +$(".admin-body-container").animate({ + scrollTop: 0 +}, 200); \ No newline at end of file diff --git a/app/views/admins/shixun_authorizations/index.html.erb b/app/views/admins/shixun_authorizations/index.html.erb new file mode 100644 index 000000000..743f2e1b2 --- /dev/null +++ b/app/views/admins/shixun_authorizations/index.html.erb @@ -0,0 +1,32 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('实训发布') %> +<% end %> + +
    + + + <%= form_tag(admins_shixun_authorizations_path(unsafe_params), method: :get, class: 'form-inline search-form justify-content-end mt-3', remote: true) do %> +
    + + <% status_options = [['全部', 'processed'], ['已同意', 'agreed'], ['已拒绝', 'refused']] %> + <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> +
    + <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '实训名称检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %> + <% end %> +
    + +
    + <%= render(partial: 'admins/shixun_authorizations/shared/list', locals: { applies: @applies, shixun_map: @shixun_map }) %> +
    + +<%= render(partial: 'admins/shared/admin_common_refuse_modal') %> \ No newline at end of file diff --git a/app/views/admins/shixun_authorizations/index.js.erb b/app/views/admins/shixun_authorizations/index.js.erb new file mode 100644 index 000000000..caa8bb389 --- /dev/null +++ b/app/views/admins/shixun_authorizations/index.js.erb @@ -0,0 +1 @@ +$('.shixun-authorization-list-container').html("<%= j( render partial: 'admins/shixun_authorizations/shared/list', locals: { applies: @applies, shixun_map: @shixun_map } ) %>"); \ No newline at end of file diff --git a/app/views/admins/shixun_authorizations/shared/_list.html.erb b/app/views/admins/shixun_authorizations/shared/_list.html.erb new file mode 100644 index 000000000..ce3b4ca43 --- /dev/null +++ b/app/views/admins/shixun_authorizations/shared/_list.html.erb @@ -0,0 +1,60 @@ +<% is_processed = params[:status].to_s != 'pending' %> + + + + + + + + + + <% if is_processed %> + + + <% else %> + + <% end %> + + + + <% if applies.present? %> + <% applies.each do |apply| %> + <% user = apply.user %> + <% shixun = shixun_map[apply.container_id] %> + + + + + + + + <% if is_processed %> + + + <% else %> + + <% end %> + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
    头像创建者实训名称任务数时间拒绝原因状态操作
    + <%= link_to "/users/#{user.login}", class: 'shixun-authorization-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %> + + <% end %> + <%= user.real_name %> + <%= link_to "/shixuns/#{shixun.identifier}", target: '_blank' do %> + <%= overflow_hidden_span shixun.name, width: 300 %> + <% end %> + <%= shixun.challenges_count %><%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %><%= overflow_hidden_span apply.reason, width: 140 %><%= apply.status_text %> + <%= agree_link '同意', agree_admins_shixun_authorization_path(apply, element: ".shixun-authorization-#{apply.id}"), 'data-confirm': '确认审核通过?' %> + <%= javascript_void_link('拒绝', class: 'action refuse-action', + data: { + toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id, + url: refuse_admins_shixun_authorization_path(apply, element: ".shixun-authorization-#{apply.id}") + }) %> +
    + +<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %> \ No newline at end of file diff --git a/app/views/admins/subject_authorizations/index.html.erb b/app/views/admins/subject_authorizations/index.html.erb new file mode 100644 index 000000000..3d5539663 --- /dev/null +++ b/app/views/admins/subject_authorizations/index.html.erb @@ -0,0 +1,33 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('实践课程发布') %> +<% end %> + +
    + + + <%= form_tag(admins_subject_authorizations_path(unsafe_params), method: :get, class: 'form-inline search-form justify-content-end mt-3', remote: true) do %> +
    + + <% status_options = [['全部', 'processed'], ['已同意', 'agreed'], ['已拒绝', 'refused']] %> + <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> +
    + <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '实训课程名称检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %> + <% end %> +
    + +
    + <%= render(partial: 'admins/subject_authorizations/shared/list', + locals: { applies: @applies, subject_map: @subject_map, challenge_count_map: @challenge_count_map }) %> +
    + +<%= render(partial: 'admins/shared/admin_common_refuse_modal') %> \ No newline at end of file diff --git a/app/views/admins/subject_authorizations/index.js.erb b/app/views/admins/subject_authorizations/index.js.erb new file mode 100644 index 000000000..a21809041 --- /dev/null +++ b/app/views/admins/subject_authorizations/index.js.erb @@ -0,0 +1 @@ +$('.subject-authorization-list-container').html("<%= j( render partial: 'admins/subject_authorizations/shared/list', locals: { applies: @applies, subject_map: @subject_map, challenge_count_map: @challenge_count_map } ) %>"); \ No newline at end of file diff --git a/app/views/admins/subject_authorizations/shared/_list.html.erb b/app/views/admins/subject_authorizations/shared/_list.html.erb new file mode 100644 index 000000000..7b8da800d --- /dev/null +++ b/app/views/admins/subject_authorizations/shared/_list.html.erb @@ -0,0 +1,64 @@ +<% is_processed = params[:status].to_s != 'pending' %> + + + + + + + + + + + + <% if is_processed %> + + + <% else %> + + <% end %> + + + + <% if applies.present? %> + <% applies.each do |apply| %> + <% user = apply.user %> + <% subject = subject_map[apply.container_id] %> + + + + + + + + + + <% if is_processed %> + + + <% else %> + + <% end %> + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
    头像创建者实践课程名称阶段数实训数关卡数时间拒绝原因状态操作
    + <%= link_to "/users/#{user.login}", class: 'subject-authorization-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %> + + <% end %> + <%= user.real_name %> + <%= link_to "/paths/#{subject.id}", target: '_blank' do %> + <%= overflow_hidden_span subject.name, width: 300 %> + <% end %> + <%= subject.stages_count %><%= subject.shixuns_count %><%= challenge_count_map.fetch(subject.id, 0) %><%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %><%= overflow_hidden_span apply.reason, width: 140 %><%= apply.status_text %> + <%= agree_link '同意', agree_admins_subject_authorization_path(apply, element: ".subject-authorization-#{apply.id}"), 'data-confirm': '确认审核通过?' %> + <%= javascript_void_link('拒绝', class: 'action refuse-action', + data: { + toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id, + url: refuse_admins_subject_authorization_path(apply, element: ".subject-authorization-#{apply.id}") + }) %> +
    + +<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %> \ No newline at end of file diff --git a/app/views/challenges/index.json.jbuilder b/app/views/challenges/index.json.jbuilder index a542b8119..37ce94305 100644 --- a/app/views/challenges/index.json.jbuilder +++ b/app/views/challenges/index.json.jbuilder @@ -13,7 +13,7 @@ if @challenges.present? json.position challenge.position json.st challenge.st json.name challenge.subject - json.score challenge.all_score + json.score challenge.score json.passed_count challenge.user_passed_count json.playing_count challenge.playing_count json.name_url shixun_challenge_path(challenge, shixun_identifier: @shixun.identifier) diff --git a/app/views/exercise_questions/_exercise_questions.json.jbuilder b/app/views/exercise_questions/_exercise_questions.json.jbuilder index bbdf45440..ca8ea7e6b 100644 --- a/app/views/exercise_questions/_exercise_questions.json.jbuilder +++ b/app/views/exercise_questions/_exercise_questions.json.jbuilder @@ -20,10 +20,20 @@ if question.question_type <= 2 #当为选择题或判断题时,只显示选 #TODO: 旧版本来一个题只有一个标准答案的,新版又做成了一个题有多个标准答案(exercise_choice_id存放的是标准答案的位置..) standard_answer_b = standard_answers_array.join("").include?(a.choice_position.to_s) user_answer_b = user_answer.include?(a.id) + choice_text = a.choice_text + if question.question_type == 2 + if choice_text == "对" + choice_text = "正确" + end + if choice_text == "错" + choice_text = "错误" + end + end json.c_position (index+1) if ex_choice_random_boolean #当选项随机时,选项位置以此为准,否则不出现 json.choice_id a.id # json.choice_text (edit_type.present? || question.question_type == 2) ? a.choice_text : "#{(index+65).chr}.#{a.choice_text}" - json.choice_text a.choice_text + + json.choice_text choice_text json.choice_position a.choice_position if exercise_type == 1 || exercise_type == 4 #1为教师编辑/预览 试卷或问题,2为空白试卷,即标准答案和用户答案都不显示,3为用户开始答题的显示,4为老师评阅试卷或学生在截止后查看试卷 json.standard_boolean standard_answer_b @@ -36,6 +46,14 @@ if question.question_type <= 2 #当为选择题或判断题时,只显示选 if exercise_type == 1 || exercise_type == 4 #1为老师,4为试卷截止且答案公开的情况 json.standard_answer standard_answers_array + if question.question_type == 2 #返回答案的文字 + standard_text = standard_answers_array.first.to_i == 1 ? "正确" : "错误" + else + array_text_answer = [] + standard_answers_array.each{|a| array_text_answer.push((a+64).chr)} + standard_text = array_text_answer.join("") + end + json.standard_answer_show standard_text end if exercise_type == 3 || exercise_type == 4 json.user_answer user_answer diff --git a/app/views/subjects/right_banner.json.jbuilder b/app/views/subjects/right_banner.json.jbuilder index 9ca42c5bc..a289ad0a9 100644 --- a/app/views/subjects/right_banner.json.jbuilder +++ b/app/views/subjects/right_banner.json.jbuilder @@ -14,8 +14,8 @@ end # 我的进展 json.progress do - json.my_score @subject.my_subject_score - json.all_score @subject.all_score - json.learned @subject.my_subject_progress - json.time @subject.my_consume_time + json.my_score @my_score + json.all_score @all_score + json.learned @learned + json.time @time end \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb index 0b31f5828..f0b3f1775 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -55,6 +55,8 @@ Rails.application.configure do # Suppress logger output for asset requests. config.assets.quiet = true + # config.assets.prefix = '/dev-assets' + # Raises error for missing translations # config.action_view.raise_on_missing_translations = true diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 5298b4ab6..922969938 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -11,4 +11,4 @@ Rails.application.config.assets.paths << Rails.root.join('node_modules') # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in the app/assets # folder are already added. -Rails.application.config.assets.precompile += %w( admin.js admin.scss ) +Rails.application.config.assets.precompile += %w( admin.js admin.css ) diff --git a/config/locales/apply_actions/zh-CN.yml b/config/locales/apply_actions/zh-CN.yml new file mode 100644 index 000000000..933ef6223 --- /dev/null +++ b/config/locales/apply_actions/zh-CN.yml @@ -0,0 +1,7 @@ +zh-CN: + apply_action: + status: + '0': '待处理' + '1': '已同意' + '2': '已拒绝' + '3': '已撤销' \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 4fc660a45..7e2cf72f3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -774,6 +774,18 @@ Rails.application.routes.draw do post :refuse end end + resources :shixun_authorizations, only: [:index] do + member do + post :agree + post :refuse + end + end + resources :subject_authorizations, only: [:index] do + member do + post :agree + post :refuse + end + end end #git 认证回调 diff --git a/db/migrate/20190827055814_modify_challnege_score_for_choose.rb b/db/migrate/20190827055814_modify_challnege_score_for_choose.rb new file mode 100644 index 000000000..7b96877e3 --- /dev/null +++ b/db/migrate/20190827055814_modify_challnege_score_for_choose.rb @@ -0,0 +1,10 @@ +class ModifyChallnegeScoreForChoose < ActiveRecord::Migration[5.2] + def change + challenges = Challenge.where(st: 1) + challenges.find_each do |c| + puts(c.id) + score = c.challenge_chooses.sum(:score) + c.update_column(:score, score) + end + end +end diff --git a/public/assets/.sprockets-manifest-1c370772f16743f825981ab0e5c94237.json b/public/assets/.sprockets-manifest-1c370772f16743f825981ab0e5c94237.json new file mode 100644 index 000000000..5f5a55fd7 --- /dev/null +++ b/public/assets/.sprockets-manifest-1c370772f16743f825981ab0e5c94237.json @@ -0,0 +1 @@ +{"files":{"admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js":{"logical_path":"admin.js","mtime":"2019-08-26T15:21:11+08:00","size":907839,"digest":"6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d","integrity":"sha256-ZXXxOZlT+xk1wDenuL0oxK/we3C+2bQfr2iZqJr0tX0="},"admin-8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5.css":{"logical_path":"admin.css","mtime":"2019-08-26T15:21:47+08:00","size":655571,"digest":"8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5","integrity":"sha256-iisDy4oFXcY/RUQ7MEyudzgjMb66VbFXCz08iqQkQtU="},"font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot":{"logical_path":"font-awesome/fontawesome-webfont.eot","mtime":"2019-08-14T17:22:43+08:00","size":165742,"digest":"7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979","integrity":"sha256-e/yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk="},"font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2":{"logical_path":"font-awesome/fontawesome-webfont.woff2","mtime":"2019-08-14T17:22:43+08:00","size":77160,"digest":"2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe","integrity":"sha256-Kt78vAQefRj88tQXh53FoJmXqmTWdbejxLbOM9oT8/4="},"font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff":{"logical_path":"font-awesome/fontawesome-webfont.woff","mtime":"2019-08-14T17:22:43+08:00","size":98024,"digest":"ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07","integrity":"sha256-ugxZ3rVFD1y0Gz+TYJ7i0NmVQVh33foiPoqKdTNHTwc="},"font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf":{"logical_path":"font-awesome/fontawesome-webfont.ttf","mtime":"2019-08-14T17:22:43+08:00","size":165548,"digest":"aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8","integrity":"sha256-qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg="},"font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg":{"logical_path":"font-awesome/fontawesome-webfont.svg","mtime":"2019-08-14T17:22:43+08:00","size":444379,"digest":"ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4","integrity":"sha256-rWFXkmwWIrpOHQPUePFUE2hSS/xG9R5C/g2UX37zI+Q="},"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png":{"logical_path":"logo.png","mtime":"2019-08-21T15:10:12+08:00","size":2816,"digest":"7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423","integrity":"sha256-f/ESVocJv5f5iY/ockm3qPIA/x9I1TfYWvhyFfGHBCM="},"application-a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533.js":{"logical_path":"application.js","mtime":"2019-08-26T15:21:11+08:00","size":1042232,"digest":"a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533","integrity":"sha256-o6TzVJ1oZwVyuwdwDIWprBHlNu3HP+9udIlyO/U15TM="},"application-a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46.css":{"logical_path":"application.css","mtime":"2019-08-26T15:21:47+08:00","size":1182859,"digest":"a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46","integrity":"sha256-p1CLiOtqaaWzAWAr3cFHRc7AmFPqfZHG+uhWuW54j0Y="}},"assets":{"admin.js":"admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js","admin.css":"admin-8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5.css","font-awesome/fontawesome-webfont.eot":"font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot","font-awesome/fontawesome-webfont.woff2":"font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2","font-awesome/fontawesome-webfont.woff":"font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff","font-awesome/fontawesome-webfont.ttf":"font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf","font-awesome/fontawesome-webfont.svg":"font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg","logo.png":"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png","application.js":"application-a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533.js","application.css":"application-a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46.css"}} \ No newline at end of file diff --git a/public/assets/admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js b/public/assets/admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js new file mode 100644 index 000000000..2ff813ff4 --- /dev/null +++ b/public/assets/admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js @@ -0,0 +1,28296 @@ +/* +Unobtrusive JavaScript +https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts +Released under the MIT license + */ + + +(function() { + var context = this; + + (function() { + (function() { + this.Rails = { + linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]', + buttonClickSelector: { + selector: 'button[data-remote]:not([form]), button[data-confirm]:not([form])', + exclude: 'form button' + }, + inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]', + formSubmitSelector: 'form', + formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])', + formDisableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled', + formEnableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled', + fileInputSelector: 'input[name][type=file]:not([disabled])', + linkDisableSelector: 'a[data-disable-with], a[data-disable]', + buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]' + }; + + }).call(this); + }).call(context); + + var Rails = context.Rails; + + (function() { + (function() { + var cspNonce; + + cspNonce = Rails.cspNonce = function() { + var meta; + meta = document.querySelector('meta[name=csp-nonce]'); + return meta && meta.content; + }; + + }).call(this); + (function() { + var expando, m; + + m = Element.prototype.matches || Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector; + + Rails.matches = function(element, selector) { + if (selector.exclude != null) { + return m.call(element, selector.selector) && !m.call(element, selector.exclude); + } else { + return m.call(element, selector); + } + }; + + expando = '_ujsData'; + + Rails.getData = function(element, key) { + var ref; + return (ref = element[expando]) != null ? ref[key] : void 0; + }; + + Rails.setData = function(element, key, value) { + if (element[expando] == null) { + element[expando] = {}; + } + return element[expando][key] = value; + }; + + Rails.$ = function(selector) { + return Array.prototype.slice.call(document.querySelectorAll(selector)); + }; + + }).call(this); + (function() { + var $, csrfParam, csrfToken; + + $ = Rails.$; + + csrfToken = Rails.csrfToken = function() { + var meta; + meta = document.querySelector('meta[name=csrf-token]'); + return meta && meta.content; + }; + + csrfParam = Rails.csrfParam = function() { + var meta; + meta = document.querySelector('meta[name=csrf-param]'); + return meta && meta.content; + }; + + Rails.CSRFProtection = function(xhr) { + var token; + token = csrfToken(); + if (token != null) { + return xhr.setRequestHeader('X-CSRF-Token', token); + } + }; + + Rails.refreshCSRFTokens = function() { + var param, token; + token = csrfToken(); + param = csrfParam(); + if ((token != null) && (param != null)) { + return $('form input[name="' + param + '"]').forEach(function(input) { + return input.value = token; + }); + } + }; + + }).call(this); + (function() { + var CustomEvent, fire, matches, preventDefault; + + matches = Rails.matches; + + CustomEvent = window.CustomEvent; + + if (typeof CustomEvent !== 'function') { + CustomEvent = function(event, params) { + var evt; + evt = document.createEvent('CustomEvent'); + evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); + return evt; + }; + CustomEvent.prototype = window.Event.prototype; + preventDefault = CustomEvent.prototype.preventDefault; + CustomEvent.prototype.preventDefault = function() { + var result; + result = preventDefault.call(this); + if (this.cancelable && !this.defaultPrevented) { + Object.defineProperty(this, 'defaultPrevented', { + get: function() { + return true; + } + }); + } + return result; + }; + } + + fire = Rails.fire = function(obj, name, data) { + var event; + event = new CustomEvent(name, { + bubbles: true, + cancelable: true, + detail: data + }); + obj.dispatchEvent(event); + return !event.defaultPrevented; + }; + + Rails.stopEverything = function(e) { + fire(e.target, 'ujs:everythingStopped'); + e.preventDefault(); + e.stopPropagation(); + return e.stopImmediatePropagation(); + }; + + Rails.delegate = function(element, selector, eventType, handler) { + return element.addEventListener(eventType, function(e) { + var target; + target = e.target; + while (!(!(target instanceof Element) || matches(target, selector))) { + target = target.parentNode; + } + if (target instanceof Element && handler.call(target, e) === false) { + e.preventDefault(); + return e.stopPropagation(); + } + }); + }; + + }).call(this); + (function() { + var AcceptHeaders, CSRFProtection, createXHR, cspNonce, fire, prepareOptions, processResponse; + + cspNonce = Rails.cspNonce, CSRFProtection = Rails.CSRFProtection, fire = Rails.fire; + + AcceptHeaders = { + '*': '*/*', + text: 'text/plain', + html: 'text/html', + xml: 'application/xml, text/xml', + json: 'application/json, text/javascript', + script: 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript' + }; + + Rails.ajax = function(options) { + var xhr; + options = prepareOptions(options); + xhr = createXHR(options, function() { + var ref, response; + response = processResponse((ref = xhr.response) != null ? ref : xhr.responseText, xhr.getResponseHeader('Content-Type')); + if (Math.floor(xhr.status / 100) === 2) { + if (typeof options.success === "function") { + options.success(response, xhr.statusText, xhr); + } + } else { + if (typeof options.error === "function") { + options.error(response, xhr.statusText, xhr); + } + } + return typeof options.complete === "function" ? options.complete(xhr, xhr.statusText) : void 0; + }); + if ((options.beforeSend != null) && !options.beforeSend(xhr, options)) { + return false; + } + if (xhr.readyState === XMLHttpRequest.OPENED) { + return xhr.send(options.data); + } + }; + + prepareOptions = function(options) { + options.url = options.url || location.href; + options.type = options.type.toUpperCase(); + if (options.type === 'GET' && options.data) { + if (options.url.indexOf('?') < 0) { + options.url += '?' + options.data; + } else { + options.url += '&' + options.data; + } + } + if (AcceptHeaders[options.dataType] == null) { + options.dataType = '*'; + } + options.accept = AcceptHeaders[options.dataType]; + if (options.dataType !== '*') { + options.accept += ', */*; q=0.01'; + } + return options; + }; + + createXHR = function(options, done) { + var xhr; + xhr = new XMLHttpRequest(); + xhr.open(options.type, options.url, true); + xhr.setRequestHeader('Accept', options.accept); + if (typeof options.data === 'string') { + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); + } + if (!options.crossDomain) { + xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + } + CSRFProtection(xhr); + xhr.withCredentials = !!options.withCredentials; + xhr.onreadystatechange = function() { + if (xhr.readyState === XMLHttpRequest.DONE) { + return done(xhr); + } + }; + return xhr; + }; + + processResponse = function(response, type) { + var parser, script; + if (typeof response === 'string' && typeof type === 'string') { + if (type.match(/\bjson\b/)) { + try { + response = JSON.parse(response); + } catch (error) {} + } else if (type.match(/\b(?:java|ecma)script\b/)) { + script = document.createElement('script'); + script.setAttribute('nonce', cspNonce()); + script.text = response; + document.head.appendChild(script).parentNode.removeChild(script); + } else if (type.match(/\b(xml|html|svg)\b/)) { + parser = new DOMParser(); + type = type.replace(/;.+/, ''); + try { + response = parser.parseFromString(response, type); + } catch (error) {} + } + } + return response; + }; + + Rails.href = function(element) { + return element.href; + }; + + Rails.isCrossDomain = function(url) { + var e, originAnchor, urlAnchor; + originAnchor = document.createElement('a'); + originAnchor.href = location.href; + urlAnchor = document.createElement('a'); + try { + urlAnchor.href = url; + return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) || (originAnchor.protocol + '//' + originAnchor.host === urlAnchor.protocol + '//' + urlAnchor.host)); + } catch (error) { + e = error; + return true; + } + }; + + }).call(this); + (function() { + var matches, toArray; + + matches = Rails.matches; + + toArray = function(e) { + return Array.prototype.slice.call(e); + }; + + Rails.serializeElement = function(element, additionalParam) { + var inputs, params; + inputs = [element]; + if (matches(element, 'form')) { + inputs = toArray(element.elements); + } + params = []; + inputs.forEach(function(input) { + if (!input.name || input.disabled) { + return; + } + if (matches(input, 'select')) { + return toArray(input.options).forEach(function(option) { + if (option.selected) { + return params.push({ + name: input.name, + value: option.value + }); + } + }); + } else if (input.checked || ['radio', 'checkbox', 'submit'].indexOf(input.type) === -1) { + return params.push({ + name: input.name, + value: input.value + }); + } + }); + if (additionalParam) { + params.push(additionalParam); + } + return params.map(function(param) { + if (param.name != null) { + return (encodeURIComponent(param.name)) + "=" + (encodeURIComponent(param.value)); + } else { + return param; + } + }).join('&'); + }; + + Rails.formElements = function(form, selector) { + if (matches(form, 'form')) { + return toArray(form.elements).filter(function(el) { + return matches(el, selector); + }); + } else { + return toArray(form.querySelectorAll(selector)); + } + }; + + }).call(this); + (function() { + var allowAction, fire, stopEverything; + + fire = Rails.fire, stopEverything = Rails.stopEverything; + + Rails.handleConfirm = function(e) { + if (!allowAction(this)) { + return stopEverything(e); + } + }; + + allowAction = function(element) { + var answer, callback, message; + message = element.getAttribute('data-confirm'); + if (!message) { + return true; + } + answer = false; + if (fire(element, 'confirm')) { + try { + answer = confirm(message); + } catch (error) {} + callback = fire(element, 'confirm:complete', [answer]); + } + return answer && callback; + }; + + }).call(this); + (function() { + var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, matches, setData, stopEverything; + + matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, stopEverything = Rails.stopEverything, formElements = Rails.formElements; + + Rails.handleDisabledElement = function(e) { + var element; + element = this; + if (element.disabled) { + return stopEverything(e); + } + }; + + Rails.enableElement = function(e) { + var element; + element = e instanceof Event ? e.target : e; + if (matches(element, Rails.linkDisableSelector)) { + return enableLinkElement(element); + } else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formEnableSelector)) { + return enableFormElement(element); + } else if (matches(element, Rails.formSubmitSelector)) { + return enableFormElements(element); + } + }; + + Rails.disableElement = function(e) { + var element; + element = e instanceof Event ? e.target : e; + if (matches(element, Rails.linkDisableSelector)) { + return disableLinkElement(element); + } else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formDisableSelector)) { + return disableFormElement(element); + } else if (matches(element, Rails.formSubmitSelector)) { + return disableFormElements(element); + } + }; + + disableLinkElement = function(element) { + var replacement; + replacement = element.getAttribute('data-disable-with'); + if (replacement != null) { + setData(element, 'ujs:enable-with', element.innerHTML); + element.innerHTML = replacement; + } + element.addEventListener('click', stopEverything); + return setData(element, 'ujs:disabled', true); + }; + + enableLinkElement = function(element) { + var originalText; + originalText = getData(element, 'ujs:enable-with'); + if (originalText != null) { + element.innerHTML = originalText; + setData(element, 'ujs:enable-with', null); + } + element.removeEventListener('click', stopEverything); + return setData(element, 'ujs:disabled', null); + }; + + disableFormElements = function(form) { + return formElements(form, Rails.formDisableSelector).forEach(disableFormElement); + }; + + disableFormElement = function(element) { + var replacement; + replacement = element.getAttribute('data-disable-with'); + if (replacement != null) { + if (matches(element, 'button')) { + setData(element, 'ujs:enable-with', element.innerHTML); + element.innerHTML = replacement; + } else { + setData(element, 'ujs:enable-with', element.value); + element.value = replacement; + } + } + element.disabled = true; + return setData(element, 'ujs:disabled', true); + }; + + enableFormElements = function(form) { + return formElements(form, Rails.formEnableSelector).forEach(enableFormElement); + }; + + enableFormElement = function(element) { + var originalText; + originalText = getData(element, 'ujs:enable-with'); + if (originalText != null) { + if (matches(element, 'button')) { + element.innerHTML = originalText; + } else { + element.value = originalText; + } + setData(element, 'ujs:enable-with', null); + } + element.disabled = false; + return setData(element, 'ujs:disabled', null); + }; + + }).call(this); + (function() { + var stopEverything; + + stopEverything = Rails.stopEverything; + + Rails.handleMethod = function(e) { + var csrfParam, csrfToken, form, formContent, href, link, method; + link = this; + method = link.getAttribute('data-method'); + if (!method) { + return; + } + href = Rails.href(link); + csrfToken = Rails.csrfToken(); + csrfParam = Rails.csrfParam(); + form = document.createElement('form'); + formContent = ""; + if ((csrfParam != null) && (csrfToken != null) && !Rails.isCrossDomain(href)) { + formContent += ""; + } + formContent += ''; + form.method = 'post'; + form.action = href; + form.target = link.target; + form.innerHTML = formContent; + form.style.display = 'none'; + document.body.appendChild(form); + form.querySelector('[type="submit"]').click(); + return stopEverything(e); + }; + + }).call(this); + (function() { + var ajax, fire, getData, isCrossDomain, isRemote, matches, serializeElement, setData, stopEverything, + slice = [].slice; + + matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, fire = Rails.fire, stopEverything = Rails.stopEverything, ajax = Rails.ajax, isCrossDomain = Rails.isCrossDomain, serializeElement = Rails.serializeElement; + + isRemote = function(element) { + var value; + value = element.getAttribute('data-remote'); + return (value != null) && value !== 'false'; + }; + + Rails.handleRemote = function(e) { + var button, data, dataType, element, method, url, withCredentials; + element = this; + if (!isRemote(element)) { + return true; + } + if (!fire(element, 'ajax:before')) { + fire(element, 'ajax:stopped'); + return false; + } + withCredentials = element.getAttribute('data-with-credentials'); + dataType = element.getAttribute('data-type') || 'script'; + if (matches(element, Rails.formSubmitSelector)) { + button = getData(element, 'ujs:submit-button'); + method = getData(element, 'ujs:submit-button-formmethod') || element.method; + url = getData(element, 'ujs:submit-button-formaction') || element.getAttribute('action') || location.href; + if (method.toUpperCase() === 'GET') { + url = url.replace(/\?.*$/, ''); + } + if (element.enctype === 'multipart/form-data') { + data = new FormData(element); + if (button != null) { + data.append(button.name, button.value); + } + } else { + data = serializeElement(element, button); + } + setData(element, 'ujs:submit-button', null); + setData(element, 'ujs:submit-button-formmethod', null); + setData(element, 'ujs:submit-button-formaction', null); + } else if (matches(element, Rails.buttonClickSelector) || matches(element, Rails.inputChangeSelector)) { + method = element.getAttribute('data-method'); + url = element.getAttribute('data-url'); + data = serializeElement(element, element.getAttribute('data-params')); + } else { + method = element.getAttribute('data-method'); + url = Rails.href(element); + data = element.getAttribute('data-params'); + } + ajax({ + type: method || 'GET', + url: url, + data: data, + dataType: dataType, + beforeSend: function(xhr, options) { + if (fire(element, 'ajax:beforeSend', [xhr, options])) { + return fire(element, 'ajax:send', [xhr]); + } else { + fire(element, 'ajax:stopped'); + return false; + } + }, + success: function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return fire(element, 'ajax:success', args); + }, + error: function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return fire(element, 'ajax:error', args); + }, + complete: function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return fire(element, 'ajax:complete', args); + }, + crossDomain: isCrossDomain(url), + withCredentials: (withCredentials != null) && withCredentials !== 'false' + }); + return stopEverything(e); + }; + + Rails.formSubmitButtonClick = function(e) { + var button, form; + button = this; + form = button.form; + if (!form) { + return; + } + if (button.name) { + setData(form, 'ujs:submit-button', { + name: button.name, + value: button.value + }); + } + setData(form, 'ujs:formnovalidate-button', button.formNoValidate); + setData(form, 'ujs:submit-button-formaction', button.getAttribute('formaction')); + return setData(form, 'ujs:submit-button-formmethod', button.getAttribute('formmethod')); + }; + + Rails.handleMetaClick = function(e) { + var data, link, metaClick, method; + link = this; + method = (link.getAttribute('data-method') || 'GET').toUpperCase(); + data = link.getAttribute('data-params'); + metaClick = e.metaKey || e.ctrlKey; + if (metaClick && method === 'GET' && !data) { + return e.stopImmediatePropagation(); + } + }; + + }).call(this); + (function() { + var $, CSRFProtection, delegate, disableElement, enableElement, fire, formSubmitButtonClick, getData, handleConfirm, handleDisabledElement, handleMetaClick, handleMethod, handleRemote, refreshCSRFTokens; + + fire = Rails.fire, delegate = Rails.delegate, getData = Rails.getData, $ = Rails.$, refreshCSRFTokens = Rails.refreshCSRFTokens, CSRFProtection = Rails.CSRFProtection, enableElement = Rails.enableElement, disableElement = Rails.disableElement, handleDisabledElement = Rails.handleDisabledElement, handleConfirm = Rails.handleConfirm, handleRemote = Rails.handleRemote, formSubmitButtonClick = Rails.formSubmitButtonClick, handleMetaClick = Rails.handleMetaClick, handleMethod = Rails.handleMethod; + + if ((typeof jQuery !== "undefined" && jQuery !== null) && (jQuery.ajax != null) && !jQuery.rails) { + jQuery.rails = Rails; + jQuery.ajaxPrefilter(function(options, originalOptions, xhr) { + if (!options.crossDomain) { + return CSRFProtection(xhr); + } + }); + } + + Rails.start = function() { + if (window._rails_loaded) { + throw new Error('rails-ujs has already been loaded!'); + } + window.addEventListener('pageshow', function() { + $(Rails.formEnableSelector).forEach(function(el) { + if (getData(el, 'ujs:disabled')) { + return enableElement(el); + } + }); + return $(Rails.linkDisableSelector).forEach(function(el) { + if (getData(el, 'ujs:disabled')) { + return enableElement(el); + } + }); + }); + delegate(document, Rails.linkDisableSelector, 'ajax:complete', enableElement); + delegate(document, Rails.linkDisableSelector, 'ajax:stopped', enableElement); + delegate(document, Rails.buttonDisableSelector, 'ajax:complete', enableElement); + delegate(document, Rails.buttonDisableSelector, 'ajax:stopped', enableElement); + delegate(document, Rails.linkClickSelector, 'click', handleDisabledElement); + delegate(document, Rails.linkClickSelector, 'click', handleConfirm); + delegate(document, Rails.linkClickSelector, 'click', handleMetaClick); + delegate(document, Rails.linkClickSelector, 'click', disableElement); + delegate(document, Rails.linkClickSelector, 'click', handleRemote); + delegate(document, Rails.linkClickSelector, 'click', handleMethod); + delegate(document, Rails.buttonClickSelector, 'click', handleDisabledElement); + delegate(document, Rails.buttonClickSelector, 'click', handleConfirm); + delegate(document, Rails.buttonClickSelector, 'click', disableElement); + delegate(document, Rails.buttonClickSelector, 'click', handleRemote); + delegate(document, Rails.inputChangeSelector, 'change', handleDisabledElement); + delegate(document, Rails.inputChangeSelector, 'change', handleConfirm); + delegate(document, Rails.inputChangeSelector, 'change', handleRemote); + delegate(document, Rails.formSubmitSelector, 'submit', handleDisabledElement); + delegate(document, Rails.formSubmitSelector, 'submit', handleConfirm); + delegate(document, Rails.formSubmitSelector, 'submit', handleRemote); + delegate(document, Rails.formSubmitSelector, 'submit', function(e) { + return setTimeout((function() { + return disableElement(e); + }), 13); + }); + delegate(document, Rails.formSubmitSelector, 'ajax:send', disableElement); + delegate(document, Rails.formSubmitSelector, 'ajax:complete', enableElement); + delegate(document, Rails.formInputClickSelector, 'click', handleDisabledElement); + delegate(document, Rails.formInputClickSelector, 'click', handleConfirm); + delegate(document, Rails.formInputClickSelector, 'click', formSubmitButtonClick); + document.addEventListener('DOMContentLoaded', refreshCSRFTokens); + return window._rails_loaded = true; + }; + + if (window.Rails === Rails && fire(document, 'rails:attachBindings')) { + Rails.start(); + } + + }).call(this); + }).call(this); + + if (typeof module === "object" && module.exports) { + module.exports = Rails; + } else if (typeof define === "function" && define.amd) { + define(Rails); + } +}).call(this); +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ActiveStorage=e():t.ActiveStorage=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var i=r[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var r={};return e.m=t,e.c=r,e.d=function(t,r,n){e.o(t,r)||Object.defineProperty(t,r,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(r,"a",r),r},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=2)}([function(t,e,r){"use strict";function n(t){var e=a(document.head,'meta[name="'+t+'"]');if(e)return e.getAttribute("content")}function i(t,e){return"string"==typeof t&&(e=t,t=document),o(t.querySelectorAll(e))}function a(t,e){return"string"==typeof t&&(e=t,t=document),t.querySelector(e)}function u(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},n=t.disabled,i=r.bubbles,a=r.cancelable,u=r.detail,o=document.createEvent("Event");o.initEvent(e,i||!0,a||!0),o.detail=u||{};try{t.disabled=!1,t.dispatchEvent(o)}finally{t.disabled=n}return o}function o(t){return Array.isArray(t)?t:Array.from?Array.from(t):[].slice.call(t)}e.d=n,e.c=i,e.b=a,e.a=u,e.e=o},function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(t&&"function"==typeof t[e]){for(var r=arguments.length,n=Array(r>2?r-2:0),i=2;i1&&void 0!==arguments[1]?arguments[1]:{};return Object(a.a)(this.form,"direct-uploads:"+t,{detail:e})}}]),t}()},function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.d(e,"a",function(){return o});var i=r(1),a=r(0),u=function(){function t(t,e){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:{};return e.file=this.file,e.id=this.directUpload.id,Object(a.a)(this.input,"direct-upload:"+t,{detail:e})}},{key:"dispatchError",value:function(t){this.dispatch("error",{error:t}).defaultPrevented||alert(t)}},{key:"directUploadWillCreateBlobWithXHR",value:function(t){this.dispatch("before-blob-request",{xhr:t})}},{key:"directUploadWillStoreFileWithXHR",value:function(t){var e=this;this.dispatch("before-storage-request",{xhr:t}),t.upload.addEventListener("progress",function(t){return e.uploadRequestDidProgress(t)})}},{key:"url",get:function(){return this.input.getAttribute("data-direct-upload-url")}}]),t}()},function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.d(e,"a",function(){return s});var i=r(7),a=r.n(i),u=function(){function t(t,e){for(var r=0;r>>25)+n|0,a+=(r&n|~r&i)+e[1]-389564586|0,a=(a<<12|a>>>20)+r|0,i+=(a&r|~a&n)+e[2]+606105819|0,i=(i<<17|i>>>15)+a|0,n+=(i&a|~i&r)+e[3]-1044525330|0,n=(n<<22|n>>>10)+i|0,r+=(n&i|~n&a)+e[4]-176418897|0,r=(r<<7|r>>>25)+n|0,a+=(r&n|~r&i)+e[5]+1200080426|0,a=(a<<12|a>>>20)+r|0,i+=(a&r|~a&n)+e[6]-1473231341|0,i=(i<<17|i>>>15)+a|0,n+=(i&a|~i&r)+e[7]-45705983|0,n=(n<<22|n>>>10)+i|0,r+=(n&i|~n&a)+e[8]+1770035416|0,r=(r<<7|r>>>25)+n|0,a+=(r&n|~r&i)+e[9]-1958414417|0,a=(a<<12|a>>>20)+r|0,i+=(a&r|~a&n)+e[10]-42063|0,i=(i<<17|i>>>15)+a|0,n+=(i&a|~i&r)+e[11]-1990404162|0,n=(n<<22|n>>>10)+i|0,r+=(n&i|~n&a)+e[12]+1804603682|0,r=(r<<7|r>>>25)+n|0,a+=(r&n|~r&i)+e[13]-40341101|0,a=(a<<12|a>>>20)+r|0,i+=(a&r|~a&n)+e[14]-1502002290|0,i=(i<<17|i>>>15)+a|0,n+=(i&a|~i&r)+e[15]+1236535329|0,n=(n<<22|n>>>10)+i|0,r+=(n&a|i&~a)+e[1]-165796510|0,r=(r<<5|r>>>27)+n|0,a+=(r&i|n&~i)+e[6]-1069501632|0,a=(a<<9|a>>>23)+r|0,i+=(a&n|r&~n)+e[11]+643717713|0,i=(i<<14|i>>>18)+a|0,n+=(i&r|a&~r)+e[0]-373897302|0,n=(n<<20|n>>>12)+i|0,r+=(n&a|i&~a)+e[5]-701558691|0,r=(r<<5|r>>>27)+n|0,a+=(r&i|n&~i)+e[10]+38016083|0,a=(a<<9|a>>>23)+r|0,i+=(a&n|r&~n)+e[15]-660478335|0,i=(i<<14|i>>>18)+a|0,n+=(i&r|a&~r)+e[4]-405537848|0,n=(n<<20|n>>>12)+i|0,r+=(n&a|i&~a)+e[9]+568446438|0,r=(r<<5|r>>>27)+n|0,a+=(r&i|n&~i)+e[14]-1019803690|0,a=(a<<9|a>>>23)+r|0,i+=(a&n|r&~n)+e[3]-187363961|0,i=(i<<14|i>>>18)+a|0,n+=(i&r|a&~r)+e[8]+1163531501|0,n=(n<<20|n>>>12)+i|0,r+=(n&a|i&~a)+e[13]-1444681467|0,r=(r<<5|r>>>27)+n|0,a+=(r&i|n&~i)+e[2]-51403784|0,a=(a<<9|a>>>23)+r|0,i+=(a&n|r&~n)+e[7]+1735328473|0,i=(i<<14|i>>>18)+a|0,n+=(i&r|a&~r)+e[12]-1926607734|0,n=(n<<20|n>>>12)+i|0,r+=(n^i^a)+e[5]-378558|0,r=(r<<4|r>>>28)+n|0,a+=(r^n^i)+e[8]-2022574463|0,a=(a<<11|a>>>21)+r|0,i+=(a^r^n)+e[11]+1839030562|0,i=(i<<16|i>>>16)+a|0,n+=(i^a^r)+e[14]-35309556|0,n=(n<<23|n>>>9)+i|0,r+=(n^i^a)+e[1]-1530992060|0,r=(r<<4|r>>>28)+n|0,a+=(r^n^i)+e[4]+1272893353|0,a=(a<<11|a>>>21)+r|0,i+=(a^r^n)+e[7]-155497632|0,i=(i<<16|i>>>16)+a|0,n+=(i^a^r)+e[10]-1094730640|0,n=(n<<23|n>>>9)+i|0,r+=(n^i^a)+e[13]+681279174|0,r=(r<<4|r>>>28)+n|0,a+=(r^n^i)+e[0]-358537222|0,a=(a<<11|a>>>21)+r|0,i+=(a^r^n)+e[3]-722521979|0,i=(i<<16|i>>>16)+a|0,n+=(i^a^r)+e[6]+76029189|0,n=(n<<23|n>>>9)+i|0,r+=(n^i^a)+e[9]-640364487|0,r=(r<<4|r>>>28)+n|0,a+=(r^n^i)+e[12]-421815835|0,a=(a<<11|a>>>21)+r|0,i+=(a^r^n)+e[15]+530742520|0,i=(i<<16|i>>>16)+a|0,n+=(i^a^r)+e[2]-995338651|0,n=(n<<23|n>>>9)+i|0,r+=(i^(n|~a))+e[0]-198630844|0,r=(r<<6|r>>>26)+n|0,a+=(n^(r|~i))+e[7]+1126891415|0,a=(a<<10|a>>>22)+r|0,i+=(r^(a|~n))+e[14]-1416354905|0,i=(i<<15|i>>>17)+a|0,n+=(a^(i|~r))+e[5]-57434055|0,n=(n<<21|n>>>11)+i|0,r+=(i^(n|~a))+e[12]+1700485571|0,r=(r<<6|r>>>26)+n|0,a+=(n^(r|~i))+e[3]-1894986606|0,a=(a<<10|a>>>22)+r|0,i+=(r^(a|~n))+e[10]-1051523|0,i=(i<<15|i>>>17)+a|0,n+=(a^(i|~r))+e[1]-2054922799|0,n=(n<<21|n>>>11)+i|0,r+=(i^(n|~a))+e[8]+1873313359|0,r=(r<<6|r>>>26)+n|0,a+=(n^(r|~i))+e[15]-30611744|0,a=(a<<10|a>>>22)+r|0,i+=(r^(a|~n))+e[6]-1560198380|0,i=(i<<15|i>>>17)+a|0,n+=(a^(i|~r))+e[13]+1309151649|0,n=(n<<21|n>>>11)+i|0,r+=(i^(n|~a))+e[4]-145523070|0,r=(r<<6|r>>>26)+n|0,a+=(n^(r|~i))+e[11]-1120210379|0,a=(a<<10|a>>>22)+r|0,i+=(r^(a|~n))+e[2]+718787259|0,i=(i<<15|i>>>17)+a|0,n+=(a^(i|~r))+e[9]-343485551|0,n=(n<<21|n>>>11)+i|0,t[0]=r+t[0]|0,t[1]=n+t[1]|0,t[2]=i+t[2]|0,t[3]=a+t[3]|0}function r(t){var e,r=[];for(e=0;e<64;e+=4)r[e>>2]=t.charCodeAt(e)+(t.charCodeAt(e+1)<<8)+(t.charCodeAt(e+2)<<16)+(t.charCodeAt(e+3)<<24);return r}function n(t){var e,r=[];for(e=0;e<64;e+=4)r[e>>2]=t[e]+(t[e+1]<<8)+(t[e+2]<<16)+(t[e+3]<<24);return r}function i(t){var n,i,a,u,o,s,f=t.length,c=[1732584193,-271733879,-1732584194,271733878];for(n=64;n<=f;n+=64)e(c,r(t.substring(n-64,n)));for(t=t.substring(n-64),i=t.length,a=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],n=0;n>2]|=t.charCodeAt(n)<<(n%4<<3);if(a[n>>2]|=128<<(n%4<<3),n>55)for(e(c,a),n=0;n<16;n+=1)a[n]=0;return u=8*f,u=u.toString(16).match(/(.*?)(.{0,8})$/),o=parseInt(u[2],16),s=parseInt(u[1],16)||0,a[14]=o,a[15]=s,e(c,a),c}function a(t){var r,i,a,u,o,s,f=t.length,c=[1732584193,-271733879,-1732584194,271733878];for(r=64;r<=f;r+=64)e(c,n(t.subarray(r-64,r)));for(t=r-64>2]|=t[r]<<(r%4<<3);if(a[r>>2]|=128<<(r%4<<3),r>55)for(e(c,a),r=0;r<16;r+=1)a[r]=0;return u=8*f,u=u.toString(16).match(/(.*?)(.{0,8})$/),o=parseInt(u[2],16),s=parseInt(u[1],16)||0,a[14]=o,a[15]=s,e(c,a),c}function u(t){var e,r="";for(e=0;e<4;e+=1)r+=p[t>>8*e+4&15]+p[t>>8*e&15];return r}function o(t){var e;for(e=0;e>16)+(e>>16)+(r>>16)<<16|65535&r},"undefined"==typeof ArrayBuffer||ArrayBuffer.prototype.slice||function(){function e(t,e){return t=0|t||0,t<0?Math.max(t+e,0):Math.min(t,e)}ArrayBuffer.prototype.slice=function(r,n){var i,a,u,o,s=this.byteLength,f=e(r,s),c=s;return n!==t&&(c=e(n,s)),f>c?new ArrayBuffer(0):(i=c-f,a=new ArrayBuffer(i),u=new Uint8Array(a),o=new Uint8Array(this,f,i),u.set(o),a)}}(),d.prototype.append=function(t){return this.appendBinary(s(t)),this},d.prototype.appendBinary=function(t){this._buff+=t,this._length+=t.length;var n,i=this._buff.length;for(n=64;n<=i;n+=64)e(this._hash,r(this._buff.substring(n-64,n)));return this._buff=this._buff.substring(n-64),this},d.prototype.end=function(t){var e,r,n=this._buff,i=n.length,a=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(e=0;e>2]|=n.charCodeAt(e)<<(e%4<<3);return this._finish(a,i),r=o(this._hash),t&&(r=l(r)),this.reset(),r},d.prototype.reset=function(){return this._buff="",this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},d.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash}},d.prototype.setState=function(t){return this._buff=t.buff,this._length=t.length,this._hash=t.hash,this},d.prototype.destroy=function(){delete this._hash,delete this._buff,delete this._length},d.prototype._finish=function(t,r){var n,i,a,u=r;if(t[u>>2]|=128<<(u%4<<3),u>55)for(e(this._hash,t),u=0;u<16;u+=1)t[u]=0;n=8*this._length,n=n.toString(16).match(/(.*?)(.{0,8})$/),i=parseInt(n[2],16),a=parseInt(n[1],16)||0,t[14]=i,t[15]=a,e(this._hash,t)},d.hash=function(t,e){return d.hashBinary(s(t),e)},d.hashBinary=function(t,e){var r=i(t),n=o(r);return e?l(n):n},d.ArrayBuffer=function(){this.reset()},d.ArrayBuffer.prototype.append=function(t){var r,i=h(this._buff.buffer,t,!0),a=i.length;for(this._length+=t.byteLength,r=64;r<=a;r+=64)e(this._hash,n(i.subarray(r-64,r)));return this._buff=r-64>2]|=n[e]<<(e%4<<3);return this._finish(a,i),r=o(this._hash),t&&(r=l(r)),this.reset(),r},d.ArrayBuffer.prototype.reset=function(){return this._buff=new Uint8Array(0),this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},d.ArrayBuffer.prototype.getState=function(){var t=d.prototype.getState.call(this);return t.buff=c(t.buff),t},d.ArrayBuffer.prototype.setState=function(t){return t.buff=f(t.buff,!0),d.prototype.setState.call(this,t)},d.ArrayBuffer.prototype.destroy=d.prototype.destroy,d.ArrayBuffer.prototype._finish=d.prototype._finish,d.ArrayBuffer.hash=function(t,e){var r=a(new Uint8Array(t)),n=o(r);return e?l(n):n},d})},function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.d(e,"a",function(){return u});var i=r(0),a=function(){function t(t,e){for(var r=0;r=200&&this.status<300){var e=this.response,r=e.direct_upload;delete e.direct_upload,this.attributes=e,this.directUploadData=r,this.callback(null,this.toJSON())}else this.requestDidError(t)}},{key:"requestDidError",value:function(t){this.callback('Error creating Blob for "'+this.file.name+'". Status: '+this.status)}},{key:"toJSON",value:function(){var t={};for(var e in this.attributes)t[e]=this.attributes[e];return t}},{key:"status",get:function(){return this.xhr.status}},{key:"response",get:function(){var t=this.xhr,e=t.responseType,r=t.response;return"json"==e?r:JSON.parse(r)}}]),t}()},function(t,e,r){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}r.d(e,"a",function(){return a});var i=function(){function t(t,e){for(var r=0;r=200&&r<300?this.callback(null,n):this.requestDidError(t)}},{key:"requestDidError",value:function(t){this.callback('Error storing "'+this.file.name+'". Status: '+this.xhr.status)}}]),t}()}])}); +/* +Turbolinks 5.2.0 +Copyright © 2018 Basecamp, LLC + */ + +(function(){var t=this;(function(){(function(){this.Turbolinks={supported:function(){return null!=window.history.pushState&&null!=window.requestAnimationFrame&&null!=window.addEventListener}(),visit:function(t,r){return e.controller.visit(t,r)},clearCache:function(){return e.controller.clearCache()},setProgressBarDelay:function(t){return e.controller.setProgressBarDelay(t)}}}).call(this)}).call(t);var e=t.Turbolinks;(function(){(function(){var t,r,n,o=[].slice;e.copyObject=function(t){var e,r,n;r={};for(e in t)n=t[e],r[e]=n;return r},e.closest=function(e,r){return t.call(e,r)},t=function(){var t,e;return t=document.documentElement,null!=(e=t.closest)?e:function(t){var e;for(e=this;e;){if(e.nodeType===Node.ELEMENT_NODE&&r.call(e,t))return e;e=e.parentNode}}}(),e.defer=function(t){return setTimeout(t,1)},e.throttle=function(t){var e;return e=null,function(){var r;return r=1<=arguments.length?o.call(arguments,0):[],null!=e?e:e=requestAnimationFrame(function(n){return function(){return e=null,t.apply(n,r)}}(this))}},e.dispatch=function(t,e){var r,o,i,s,a,u;return a=null!=e?e:{},u=a.target,r=a.cancelable,o=a.data,i=document.createEvent("Events"),i.initEvent(t,!0,r===!0),i.data=null!=o?o:{},i.cancelable&&!n&&(s=i.preventDefault,i.preventDefault=function(){return this.defaultPrevented||Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}}),s.call(this)}),(null!=u?u:document).dispatchEvent(i),i},n=function(){var t;return t=document.createEvent("Events"),t.initEvent("test",!0,!0),t.preventDefault(),t.defaultPrevented}(),e.match=function(t,e){return r.call(t,e)},r=function(){var t,e,r,n;return t=document.documentElement,null!=(e=null!=(r=null!=(n=t.matchesSelector)?n:t.webkitMatchesSelector)?r:t.msMatchesSelector)?e:t.mozMatchesSelector}(),e.uuid=function(){var t,e,r;for(r="",t=e=1;36>=e;t=++e)r+=9===t||14===t||19===t||24===t?"-":15===t?"4":20===t?(Math.floor(4*Math.random())+8).toString(16):Math.floor(15*Math.random()).toString(16);return r}}).call(this),function(){e.Location=function(){function t(t){var e,r;null==t&&(t=""),r=document.createElement("a"),r.href=t.toString(),this.absoluteURL=r.href,e=r.hash.length,2>e?this.requestURL=this.absoluteURL:(this.requestURL=this.absoluteURL.slice(0,-e),this.anchor=r.hash.slice(1))}var e,r,n,o;return t.wrap=function(t){return t instanceof this?t:new this(t)},t.prototype.getOrigin=function(){return this.absoluteURL.split("/",3).join("/")},t.prototype.getPath=function(){var t,e;return null!=(t=null!=(e=this.requestURL.match(/\/\/[^\/]*(\/[^?;]*)/))?e[1]:void 0)?t:"/"},t.prototype.getPathComponents=function(){return this.getPath().split("/").slice(1)},t.prototype.getLastPathComponent=function(){return this.getPathComponents().slice(-1)[0]},t.prototype.getExtension=function(){var t,e;return null!=(t=null!=(e=this.getLastPathComponent().match(/\.[^.]*$/))?e[0]:void 0)?t:""},t.prototype.isHTML=function(){return this.getExtension().match(/^(?:|\.(?:htm|html|xhtml))$/)},t.prototype.isPrefixedBy=function(t){var e;return e=r(t),this.isEqualTo(t)||o(this.absoluteURL,e)},t.prototype.isEqualTo=function(t){return this.absoluteURL===(null!=t?t.absoluteURL:void 0)},t.prototype.toCacheKey=function(){return this.requestURL},t.prototype.toJSON=function(){return this.absoluteURL},t.prototype.toString=function(){return this.absoluteURL},t.prototype.valueOf=function(){return this.absoluteURL},r=function(t){return e(t.getOrigin()+t.getPath())},e=function(t){return n(t,"/")?t:t+"/"},o=function(t,e){return t.slice(0,e.length)===e},n=function(t,e){return t.slice(-e.length)===e},t}()}.call(this),function(){var t=function(t,e){return function(){return t.apply(e,arguments)}};e.HttpRequest=function(){function r(r,n,o){this.delegate=r,this.requestCanceled=t(this.requestCanceled,this),this.requestTimedOut=t(this.requestTimedOut,this),this.requestFailed=t(this.requestFailed,this),this.requestLoaded=t(this.requestLoaded,this),this.requestProgressed=t(this.requestProgressed,this),this.url=e.Location.wrap(n).requestURL,this.referrer=e.Location.wrap(o).absoluteURL,this.createXHR()}return r.NETWORK_FAILURE=0,r.TIMEOUT_FAILURE=-1,r.timeout=60,r.prototype.send=function(){var t;return this.xhr&&!this.sent?(this.notifyApplicationBeforeRequestStart(),this.setProgress(0),this.xhr.send(),this.sent=!0,"function"==typeof(t=this.delegate).requestStarted?t.requestStarted():void 0):void 0},r.prototype.cancel=function(){return this.xhr&&this.sent?this.xhr.abort():void 0},r.prototype.requestProgressed=function(t){return t.lengthComputable?this.setProgress(t.loaded/t.total):void 0},r.prototype.requestLoaded=function(){return this.endRequest(function(t){return function(){var e;return 200<=(e=t.xhr.status)&&300>e?t.delegate.requestCompletedWithResponse(t.xhr.responseText,t.xhr.getResponseHeader("Turbolinks-Location")):(t.failed=!0,t.delegate.requestFailedWithStatusCode(t.xhr.status,t.xhr.responseText))}}(this))},r.prototype.requestFailed=function(){return this.endRequest(function(t){return function(){return t.failed=!0,t.delegate.requestFailedWithStatusCode(t.constructor.NETWORK_FAILURE)}}(this))},r.prototype.requestTimedOut=function(){return this.endRequest(function(t){return function(){return t.failed=!0,t.delegate.requestFailedWithStatusCode(t.constructor.TIMEOUT_FAILURE)}}(this))},r.prototype.requestCanceled=function(){return this.endRequest()},r.prototype.notifyApplicationBeforeRequestStart=function(){return e.dispatch("turbolinks:request-start",{data:{url:this.url,xhr:this.xhr}})},r.prototype.notifyApplicationAfterRequestEnd=function(){return e.dispatch("turbolinks:request-end",{data:{url:this.url,xhr:this.xhr}})},r.prototype.createXHR=function(){return this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url,!0),this.xhr.timeout=1e3*this.constructor.timeout,this.xhr.setRequestHeader("Accept","text/html, application/xhtml+xml"),this.xhr.setRequestHeader("Turbolinks-Referrer",this.referrer),this.xhr.onprogress=this.requestProgressed,this.xhr.onload=this.requestLoaded,this.xhr.onerror=this.requestFailed,this.xhr.ontimeout=this.requestTimedOut,this.xhr.onabort=this.requestCanceled},r.prototype.endRequest=function(t){return this.xhr?(this.notifyApplicationAfterRequestEnd(),null!=t&&t.call(this),this.destroy()):void 0},r.prototype.setProgress=function(t){var e;return this.progress=t,"function"==typeof(e=this.delegate).requestProgressed?e.requestProgressed(this.progress):void 0},r.prototype.destroy=function(){var t;return this.setProgress(1),"function"==typeof(t=this.delegate).requestFinished&&t.requestFinished(),this.delegate=null,this.xhr=null},r}()}.call(this),function(){var t=function(t,e){return function(){return t.apply(e,arguments)}};e.ProgressBar=function(){function e(){this.trickle=t(this.trickle,this),this.stylesheetElement=this.createStylesheetElement(),this.progressElement=this.createProgressElement()}var r;return r=300,e.defaultCSS=".turbolinks-progress-bar {\n position: fixed;\n display: block;\n top: 0;\n left: 0;\n height: 3px;\n background: #0076ff;\n z-index: 9999;\n transition: width "+r+"ms ease-out, opacity "+r/2+"ms "+r/2+"ms ease-in;\n transform: translate3d(0, 0, 0);\n}",e.prototype.show=function(){return this.visible?void 0:(this.visible=!0,this.installStylesheetElement(),this.installProgressElement(),this.startTrickling())},e.prototype.hide=function(){return this.visible&&!this.hiding?(this.hiding=!0,this.fadeProgressElement(function(t){return function(){return t.uninstallProgressElement(),t.stopTrickling(),t.visible=!1,t.hiding=!1}}(this))):void 0},e.prototype.setValue=function(t){return this.value=t,this.refresh()},e.prototype.installStylesheetElement=function(){return document.head.insertBefore(this.stylesheetElement,document.head.firstChild)},e.prototype.installProgressElement=function(){return this.progressElement.style.width=0,this.progressElement.style.opacity=1,document.documentElement.insertBefore(this.progressElement,document.body),this.refresh()},e.prototype.fadeProgressElement=function(t){return this.progressElement.style.opacity=0,setTimeout(t,1.5*r)},e.prototype.uninstallProgressElement=function(){return this.progressElement.parentNode?document.documentElement.removeChild(this.progressElement):void 0},e.prototype.startTrickling=function(){return null!=this.trickleInterval?this.trickleInterval:this.trickleInterval=setInterval(this.trickle,r)},e.prototype.stopTrickling=function(){return clearInterval(this.trickleInterval),this.trickleInterval=null},e.prototype.trickle=function(){return this.setValue(this.value+Math.random()/100)},e.prototype.refresh=function(){return requestAnimationFrame(function(t){return function(){return t.progressElement.style.width=10+90*t.value+"%"}}(this))},e.prototype.createStylesheetElement=function(){var t;return t=document.createElement("style"),t.type="text/css",t.textContent=this.constructor.defaultCSS,t},e.prototype.createProgressElement=function(){var t;return t=document.createElement("div"),t.className="turbolinks-progress-bar",t},e}()}.call(this),function(){var t=function(t,e){return function(){return t.apply(e,arguments)}};e.BrowserAdapter=function(){function r(r){this.controller=r,this.showProgressBar=t(this.showProgressBar,this),this.progressBar=new e.ProgressBar}var n,o,i;return i=e.HttpRequest,n=i.NETWORK_FAILURE,o=i.TIMEOUT_FAILURE,r.prototype.visitProposedToLocationWithAction=function(t,e){return this.controller.startVisitToLocationWithAction(t,e)},r.prototype.visitStarted=function(t){return t.issueRequest(),t.changeHistory(),t.loadCachedSnapshot()},r.prototype.visitRequestStarted=function(t){return this.progressBar.setValue(0),t.hasCachedSnapshot()||"restore"!==t.action?this.showProgressBarAfterDelay():this.showProgressBar()},r.prototype.visitRequestProgressed=function(t){return this.progressBar.setValue(t.progress)},r.prototype.visitRequestCompleted=function(t){return t.loadResponse()},r.prototype.visitRequestFailedWithStatusCode=function(t,e){switch(e){case n:case o:return this.reload();default:return t.loadResponse()}},r.prototype.visitRequestFinished=function(t){return this.hideProgressBar()},r.prototype.visitCompleted=function(t){return t.followRedirect()},r.prototype.pageInvalidated=function(){return this.reload()},r.prototype.showProgressBarAfterDelay=function(){return this.progressBarTimeout=setTimeout(this.showProgressBar,this.controller.progressBarDelay)},r.prototype.showProgressBar=function(){return this.progressBar.show()},r.prototype.hideProgressBar=function(){return this.progressBar.hide(),clearTimeout(this.progressBarTimeout)},r.prototype.reload=function(){return window.location.reload()},r}()}.call(this),function(){var t=function(t,e){return function(){return t.apply(e,arguments)}};e.History=function(){function r(e){this.delegate=e,this.onPageLoad=t(this.onPageLoad,this),this.onPopState=t(this.onPopState,this)}return r.prototype.start=function(){return this.started?void 0:(addEventListener("popstate",this.onPopState,!1),addEventListener("load",this.onPageLoad,!1),this.started=!0)},r.prototype.stop=function(){return this.started?(removeEventListener("popstate",this.onPopState,!1),removeEventListener("load",this.onPageLoad,!1),this.started=!1):void 0},r.prototype.push=function(t,r){return t=e.Location.wrap(t),this.update("push",t,r)},r.prototype.replace=function(t,r){return t=e.Location.wrap(t),this.update("replace",t,r)},r.prototype.onPopState=function(t){var r,n,o,i;return this.shouldHandlePopState()&&(i=null!=(n=t.state)?n.turbolinks:void 0)?(r=e.Location.wrap(window.location),o=i.restorationIdentifier,this.delegate.historyPoppedToLocationWithRestorationIdentifier(r,o)):void 0},r.prototype.onPageLoad=function(t){return e.defer(function(t){return function(){return t.pageLoaded=!0}}(this))},r.prototype.shouldHandlePopState=function(){return this.pageIsLoaded()},r.prototype.pageIsLoaded=function(){return this.pageLoaded||"complete"===document.readyState},r.prototype.update=function(t,e,r){var n;return n={turbolinks:{restorationIdentifier:r}},history[t+"State"](n,null,e)},r}()}.call(this),function(){e.HeadDetails=function(){function t(t){var e,r,n,s,a,u;for(this.elements={},n=0,a=t.length;a>n;n++)u=t[n],u.nodeType===Node.ELEMENT_NODE&&(s=u.outerHTML,r=null!=(e=this.elements)[s]?e[s]:e[s]={type:i(u),tracked:o(u),elements:[]},r.elements.push(u))}var e,r,n,o,i;return t.fromHeadElement=function(t){var e;return new this(null!=(e=null!=t?t.childNodes:void 0)?e:[])},t.prototype.hasElementWithKey=function(t){return t in this.elements},t.prototype.getTrackedElementSignature=function(){var t,e;return function(){var r,n;r=this.elements,n=[];for(t in r)e=r[t].tracked,e&&n.push(t);return n}.call(this).join("")},t.prototype.getScriptElementsNotInDetails=function(t){return this.getElementsMatchingTypeNotInDetails("script",t)},t.prototype.getStylesheetElementsNotInDetails=function(t){return this.getElementsMatchingTypeNotInDetails("stylesheet",t)},t.prototype.getElementsMatchingTypeNotInDetails=function(t,e){var r,n,o,i,s,a;o=this.elements,s=[];for(n in o)i=o[n],a=i.type,r=i.elements,a!==t||e.hasElementWithKey(n)||s.push(r[0]);return s},t.prototype.getProvisionalElements=function(){var t,e,r,n,o,i,s;r=[],n=this.elements;for(e in n)o=n[e],s=o.type,i=o.tracked,t=o.elements,null!=s||i?t.length>1&&r.push.apply(r,t.slice(1)):r.push.apply(r,t);return r},t.prototype.getMetaValue=function(t){var e;return null!=(e=this.findMetaElementByName(t))?e.getAttribute("content"):void 0},t.prototype.findMetaElementByName=function(t){var r,n,o,i;r=void 0,i=this.elements;for(o in i)n=i[o].elements,e(n[0],t)&&(r=n[0]);return r},i=function(t){return r(t)?"script":n(t)?"stylesheet":void 0},o=function(t){return"reload"===t.getAttribute("data-turbolinks-track")},r=function(t){var e;return e=t.tagName.toLowerCase(),"script"===e},n=function(t){var e;return e=t.tagName.toLowerCase(),"style"===e||"link"===e&&"stylesheet"===t.getAttribute("rel")},e=function(t,e){var r;return r=t.tagName.toLowerCase(),"meta"===r&&t.getAttribute("name")===e},t}()}.call(this),function(){e.Snapshot=function(){function t(t,e){this.headDetails=t,this.bodyElement=e}return t.wrap=function(t){return t instanceof this?t:"string"==typeof t?this.fromHTMLString(t):this.fromHTMLElement(t)},t.fromHTMLString=function(t){var e;return e=document.createElement("html"),e.innerHTML=t,this.fromHTMLElement(e)},t.fromHTMLElement=function(t){var r,n,o,i;return o=t.querySelector("head"),r=null!=(i=t.querySelector("body"))?i:document.createElement("body"),n=e.HeadDetails.fromHeadElement(o),new this(n,r)},t.prototype.clone=function(){return new this.constructor(this.headDetails,this.bodyElement.cloneNode(!0))},t.prototype.getRootLocation=function(){var t,r;return r=null!=(t=this.getSetting("root"))?t:"/",new e.Location(r)},t.prototype.getCacheControlValue=function(){return this.getSetting("cache-control")},t.prototype.getElementForAnchor=function(t){try{return this.bodyElement.querySelector("[id='"+t+"'], a[name='"+t+"']")}catch(e){}},t.prototype.getPermanentElements=function(){return this.bodyElement.querySelectorAll("[id][data-turbolinks-permanent]")},t.prototype.getPermanentElementById=function(t){return this.bodyElement.querySelector("#"+t+"[data-turbolinks-permanent]")},t.prototype.getPermanentElementsPresentInSnapshot=function(t){var e,r,n,o,i;for(o=this.getPermanentElements(),i=[],r=0,n=o.length;n>r;r++)e=o[r],t.getPermanentElementById(e.id)&&i.push(e);return i},t.prototype.findFirstAutofocusableElement=function(){return this.bodyElement.querySelector("[autofocus]")},t.prototype.hasAnchor=function(t){return null!=this.getElementForAnchor(t)},t.prototype.isPreviewable=function(){return"no-preview"!==this.getCacheControlValue()},t.prototype.isCacheable=function(){return"no-cache"!==this.getCacheControlValue()},t.prototype.isVisitable=function(){return"reload"!==this.getSetting("visit-control")},t.prototype.getSetting=function(t){return this.headDetails.getMetaValue("turbolinks-"+t)},t}()}.call(this),function(){var t=[].slice;e.Renderer=function(){function e(){}var r;return e.render=function(){var e,r,n,o;return n=arguments[0],r=arguments[1],e=3<=arguments.length?t.call(arguments,2):[],o=function(t,e,r){r.prototype=t.prototype;var n=new r,o=t.apply(n,e);return Object(o)===o?o:n}(this,e,function(){}),o.delegate=n,o.render(r),o},e.prototype.renderView=function(t){return this.delegate.viewWillRender(this.newBody),t(),this.delegate.viewRendered(this.newBody)},e.prototype.invalidateView=function(){return this.delegate.viewInvalidated()},e.prototype.createScriptElement=function(t){var e;return"false"===t.getAttribute("data-turbolinks-eval")?t:(e=document.createElement("script"),e.textContent=t.textContent,e.async=!1,r(e,t),e)},r=function(t,e){var r,n,o,i,s,a,u;for(i=e.attributes,a=[],r=0,n=i.length;n>r;r++)s=i[r],o=s.name,u=s.value,a.push(t.setAttribute(o,u));return a},e}()}.call(this),function(){var t,r,n=function(t,e){function r(){this.constructor=t}for(var n in e)o.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},o={}.hasOwnProperty;e.SnapshotRenderer=function(e){function o(t,e,r){this.currentSnapshot=t,this.newSnapshot=e,this.isPreview=r,this.currentHeadDetails=this.currentSnapshot.headDetails,this.newHeadDetails=this.newSnapshot.headDetails,this.currentBody=this.currentSnapshot.bodyElement,this.newBody=this.newSnapshot.bodyElement}return n(o,e),o.prototype.render=function(t){return this.shouldRender()?(this.mergeHead(),this.renderView(function(e){return function(){return e.replaceBody(),e.isPreview||e.focusFirstAutofocusableElement(),t()}}(this))):this.invalidateView()},o.prototype.mergeHead=function(){return this.copyNewHeadStylesheetElements(),this.copyNewHeadScriptElements(),this.removeCurrentHeadProvisionalElements(),this.copyNewHeadProvisionalElements()},o.prototype.replaceBody=function(){var t;return t=this.relocateCurrentBodyPermanentElements(),this.activateNewBodyScriptElements(),this.assignNewBody(),this.replacePlaceholderElementsWithClonedPermanentElements(t)},o.prototype.shouldRender=function(){return this.newSnapshot.isVisitable()&&this.trackedElementsAreIdentical()},o.prototype.trackedElementsAreIdentical=function(){return this.currentHeadDetails.getTrackedElementSignature()===this.newHeadDetails.getTrackedElementSignature()},o.prototype.copyNewHeadStylesheetElements=function(){var t,e,r,n,o;for(n=this.getNewHeadStylesheetElements(),o=[],e=0,r=n.length;r>e;e++)t=n[e],o.push(document.head.appendChild(t));return o},o.prototype.copyNewHeadScriptElements=function(){var t,e,r,n,o;for(n=this.getNewHeadScriptElements(),o=[],e=0,r=n.length;r>e;e++)t=n[e],o.push(document.head.appendChild(this.createScriptElement(t)));return o},o.prototype.removeCurrentHeadProvisionalElements=function(){var t,e,r,n,o;for(n=this.getCurrentHeadProvisionalElements(),o=[],e=0,r=n.length;r>e;e++)t=n[e],o.push(document.head.removeChild(t));return o},o.prototype.copyNewHeadProvisionalElements=function(){var t,e,r,n,o;for(n=this.getNewHeadProvisionalElements(),o=[],e=0,r=n.length;r>e;e++)t=n[e],o.push(document.head.appendChild(t));return o},o.prototype.relocateCurrentBodyPermanentElements=function(){var e,n,o,i,s,a,u;for(a=this.getCurrentBodyPermanentElements(),u=[],e=0,n=a.length;n>e;e++)i=a[e],s=t(i),o=this.newSnapshot.getPermanentElementById(i.id),r(i,s.element),r(o,i),u.push(s);return u},o.prototype.replacePlaceholderElementsWithClonedPermanentElements=function(t){var e,n,o,i,s,a,u;for(u=[],o=0,i=t.length;i>o;o++)a=t[o],n=a.element,s=a.permanentElement,e=s.cloneNode(!0),u.push(r(n,e));return u},o.prototype.activateNewBodyScriptElements=function(){var t,e,n,o,i,s;for(i=this.getNewBodyScriptElements(),s=[],e=0,o=i.length;o>e;e++)n=i[e],t=this.createScriptElement(n),s.push(r(n,t));return s},o.prototype.assignNewBody=function(){return document.body=this.newBody},o.prototype.focusFirstAutofocusableElement=function(){var t;return null!=(t=this.newSnapshot.findFirstAutofocusableElement())?t.focus():void 0},o.prototype.getNewHeadStylesheetElements=function(){return this.newHeadDetails.getStylesheetElementsNotInDetails(this.currentHeadDetails)},o.prototype.getNewHeadScriptElements=function(){return this.newHeadDetails.getScriptElementsNotInDetails(this.currentHeadDetails)},o.prototype.getCurrentHeadProvisionalElements=function(){return this.currentHeadDetails.getProvisionalElements()},o.prototype.getNewHeadProvisionalElements=function(){return this.newHeadDetails.getProvisionalElements()},o.prototype.getCurrentBodyPermanentElements=function(){return this.currentSnapshot.getPermanentElementsPresentInSnapshot(this.newSnapshot)},o.prototype.getNewBodyScriptElements=function(){return this.newBody.querySelectorAll("script")},o}(e.Renderer),t=function(t){var e;return e=document.createElement("meta"),e.setAttribute("name","turbolinks-permanent-placeholder"),e.setAttribute("content",t.id),{element:e,permanentElement:t}},r=function(t,e){var r;return(r=t.parentNode)?r.replaceChild(e,t):void 0}}.call(this),function(){var t=function(t,e){function n(){this.constructor=t}for(var o in e)r.call(e,o)&&(t[o]=e[o]);return n.prototype=e.prototype,t.prototype=new n,t.__super__=e.prototype,t},r={}.hasOwnProperty;e.ErrorRenderer=function(e){function r(t){var e;e=document.createElement("html"),e.innerHTML=t,this.newHead=e.querySelector("head"),this.newBody=e.querySelector("body")}return t(r,e),r.prototype.render=function(t){return this.renderView(function(e){return function(){return e.replaceHeadAndBody(),e.activateBodyScriptElements(),t()}}(this))},r.prototype.replaceHeadAndBody=function(){var t,e;return e=document.head,t=document.body,e.parentNode.replaceChild(this.newHead,e),t.parentNode.replaceChild(this.newBody,t)},r.prototype.activateBodyScriptElements=function(){var t,e,r,n,o,i;for(n=this.getScriptElements(),i=[],e=0,r=n.length;r>e;e++)o=n[e],t=this.createScriptElement(o),i.push(o.parentNode.replaceChild(t,o));return i},r.prototype.getScriptElements=function(){return document.documentElement.querySelectorAll("script")},r}(e.Renderer)}.call(this),function(){e.View=function(){function t(t){this.delegate=t,this.htmlElement=document.documentElement}return t.prototype.getRootLocation=function(){return this.getSnapshot().getRootLocation()},t.prototype.getElementForAnchor=function(t){return this.getSnapshot().getElementForAnchor(t)},t.prototype.getSnapshot=function(){return e.Snapshot.fromHTMLElement(this.htmlElement)},t.prototype.render=function(t,e){var r,n,o;return o=t.snapshot,r=t.error,n=t.isPreview,this.markAsPreview(n),null!=o?this.renderSnapshot(o,n,e):this.renderError(r,e)},t.prototype.markAsPreview=function(t){return t?this.htmlElement.setAttribute("data-turbolinks-preview",""):this.htmlElement.removeAttribute("data-turbolinks-preview")},t.prototype.renderSnapshot=function(t,r,n){return e.SnapshotRenderer.render(this.delegate,n,this.getSnapshot(),e.Snapshot.wrap(t),r)},t.prototype.renderError=function(t,r){return e.ErrorRenderer.render(this.delegate,r,t)},t}()}.call(this),function(){var t=function(t,e){return function(){return t.apply(e,arguments)}};e.ScrollManager=function(){function r(r){this.delegate=r,this.onScroll=t(this.onScroll,this),this.onScroll=e.throttle(this.onScroll)}return r.prototype.start=function(){return this.started?void 0:(addEventListener("scroll",this.onScroll,!1),this.onScroll(),this.started=!0)},r.prototype.stop=function(){return this.started?(removeEventListener("scroll",this.onScroll,!1),this.started=!1):void 0},r.prototype.scrollToElement=function(t){return t.scrollIntoView()},r.prototype.scrollToPosition=function(t){var e,r;return e=t.x,r=t.y,window.scrollTo(e,r)},r.prototype.onScroll=function(t){return this.updatePosition({x:window.pageXOffset,y:window.pageYOffset})},r.prototype.updatePosition=function(t){var e;return this.position=t,null!=(e=this.delegate)?e.scrollPositionChanged(this.position):void 0},r}()}.call(this),function(){e.SnapshotCache=function(){function t(t){this.size=t,this.keys=[],this.snapshots={}}var r;return t.prototype.has=function(t){var e;return e=r(t),e in this.snapshots},t.prototype.get=function(t){var e;if(this.has(t))return e=this.read(t),this.touch(t),e},t.prototype.put=function(t,e){return this.write(t,e),this.touch(t),e},t.prototype.read=function(t){var e;return e=r(t),this.snapshots[e]},t.prototype.write=function(t,e){var n;return n=r(t),this.snapshots[n]=e},t.prototype.touch=function(t){var e,n;return n=r(t),e=this.keys.indexOf(n),e>-1&&this.keys.splice(e,1),this.keys.unshift(n),this.trim()},t.prototype.trim=function(){var t,e,r,n,o;for(n=this.keys.splice(this.size),o=[],t=0,r=n.length;r>t;t++)e=n[t],o.push(delete this.snapshots[e]);return o},r=function(t){return e.Location.wrap(t).toCacheKey()},t}()}.call(this),function(){var t=function(t,e){return function(){return t.apply(e,arguments)}};e.Visit=function(){function r(r,n,o){this.controller=r,this.action=o,this.performScroll=t(this.performScroll,this),this.identifier=e.uuid(),this.location=e.Location.wrap(n),this.adapter=this.controller.adapter,this.state="initialized",this.timingMetrics={}}var n;return r.prototype.start=function(){return"initialized"===this.state?(this.recordTimingMetric("visitStart"),this.state="started",this.adapter.visitStarted(this)):void 0},r.prototype.cancel=function(){var t;return"started"===this.state?(null!=(t=this.request)&&t.cancel(),this.cancelRender(),this.state="canceled"):void 0},r.prototype.complete=function(){var t;return"started"===this.state?(this.recordTimingMetric("visitEnd"),this.state="completed","function"==typeof(t=this.adapter).visitCompleted&&t.visitCompleted(this),this.controller.visitCompleted(this)):void 0},r.prototype.fail=function(){var t;return"started"===this.state?(this.state="failed","function"==typeof(t=this.adapter).visitFailed?t.visitFailed(this):void 0):void 0},r.prototype.changeHistory=function(){var t,e;return this.historyChanged?void 0:(t=this.location.isEqualTo(this.referrer)?"replace":this.action,e=n(t),this.controller[e](this.location,this.restorationIdentifier),this.historyChanged=!0)},r.prototype.issueRequest=function(){return this.shouldIssueRequest()&&null==this.request?(this.progress=0,this.request=new e.HttpRequest(this,this.location,this.referrer),this.request.send()):void 0},r.prototype.getCachedSnapshot=function(){var t;return!(t=this.controller.getCachedSnapshotForLocation(this.location))||null!=this.location.anchor&&!t.hasAnchor(this.location.anchor)||"restore"!==this.action&&!t.isPreviewable()?void 0:t},r.prototype.hasCachedSnapshot=function(){return null!=this.getCachedSnapshot()},r.prototype.loadCachedSnapshot=function(){var t,e;return(e=this.getCachedSnapshot())?(t=this.shouldIssueRequest(),this.render(function(){var r;return this.cacheSnapshot(),this.controller.render({snapshot:e,isPreview:t},this.performScroll),"function"==typeof(r=this.adapter).visitRendered&&r.visitRendered(this),t?void 0:this.complete()})):void 0},r.prototype.loadResponse=function(){return null!=this.response?this.render(function(){var t,e;return this.cacheSnapshot(),this.request.failed?(this.controller.render({error:this.response},this.performScroll),"function"==typeof(t=this.adapter).visitRendered&&t.visitRendered(this),this.fail()):(this.controller.render({snapshot:this.response},this.performScroll),"function"==typeof(e=this.adapter).visitRendered&&e.visitRendered(this),this.complete())}):void 0},r.prototype.followRedirect=function(){return this.redirectedToLocation&&!this.followedRedirect?(this.location=this.redirectedToLocation,this.controller.replaceHistoryWithLocationAndRestorationIdentifier(this.redirectedToLocation,this.restorationIdentifier),this.followedRedirect=!0):void 0},r.prototype.requestStarted=function(){var t;return this.recordTimingMetric("requestStart"),"function"==typeof(t=this.adapter).visitRequestStarted?t.visitRequestStarted(this):void 0},r.prototype.requestProgressed=function(t){var e;return this.progress=t,"function"==typeof(e=this.adapter).visitRequestProgressed?e.visitRequestProgressed(this):void 0},r.prototype.requestCompletedWithResponse=function(t,r){return this.response=t,null!=r&&(this.redirectedToLocation=e.Location.wrap(r)),this.adapter.visitRequestCompleted(this)},r.prototype.requestFailedWithStatusCode=function(t,e){return this.response=e,this.adapter.visitRequestFailedWithStatusCode(this,t)},r.prototype.requestFinished=function(){var t;return this.recordTimingMetric("requestEnd"),"function"==typeof(t=this.adapter).visitRequestFinished?t.visitRequestFinished(this):void 0},r.prototype.performScroll=function(){return this.scrolled?void 0:("restore"===this.action?this.scrollToRestoredPosition()||this.scrollToTop():this.scrollToAnchor()||this.scrollToTop(),this.scrolled=!0)},r.prototype.scrollToRestoredPosition=function(){var t,e;return t=null!=(e=this.restorationData)?e.scrollPosition:void 0,null!=t?(this.controller.scrollToPosition(t),!0):void 0},r.prototype.scrollToAnchor=function(){return null!=this.location.anchor?(this.controller.scrollToAnchor(this.location.anchor),!0):void 0},r.prototype.scrollToTop=function(){return this.controller.scrollToPosition({x:0,y:0})},r.prototype.recordTimingMetric=function(t){var e;return null!=(e=this.timingMetrics)[t]?e[t]:e[t]=(new Date).getTime()},r.prototype.getTimingMetrics=function(){return e.copyObject(this.timingMetrics)},n=function(t){switch(t){case"replace":return"replaceHistoryWithLocationAndRestorationIdentifier";case"advance":case"restore":return"pushHistoryWithLocationAndRestorationIdentifier"}},r.prototype.shouldIssueRequest=function(){return"restore"===this.action?!this.hasCachedSnapshot():!0},r.prototype.cacheSnapshot=function(){return this.snapshotCached?void 0:(this.controller.cacheSnapshot(),this.snapshotCached=!0)},r.prototype.render=function(t){return this.cancelRender(),this.frame=requestAnimationFrame(function(e){return function(){return e.frame=null,t.call(e)}}(this))},r.prototype.cancelRender=function(){return this.frame?cancelAnimationFrame(this.frame):void 0},r}()}.call(this),function(){var t=function(t,e){return function(){return t.apply(e,arguments)}};e.Controller=function(){function r(){this.clickBubbled=t(this.clickBubbled,this),this.clickCaptured=t(this.clickCaptured,this),this.pageLoaded=t(this.pageLoaded,this),this.history=new e.History(this),this.view=new e.View(this),this.scrollManager=new e.ScrollManager(this),this.restorationData={},this.clearCache(),this.setProgressBarDelay(500)}return r.prototype.start=function(){return e.supported&&!this.started?(addEventListener("click",this.clickCaptured,!0),addEventListener("DOMContentLoaded",this.pageLoaded,!1),this.scrollManager.start(),this.startHistory(),this.started=!0,this.enabled=!0):void 0},r.prototype.disable=function(){return this.enabled=!1},r.prototype.stop=function(){return this.started?(removeEventListener("click",this.clickCaptured,!0),removeEventListener("DOMContentLoaded",this.pageLoaded,!1),this.scrollManager.stop(),this.stopHistory(),this.started=!1):void 0},r.prototype.clearCache=function(){return this.cache=new e.SnapshotCache(10)},r.prototype.visit=function(t,r){var n,o;return null==r&&(r={}),t=e.Location.wrap(t),this.applicationAllowsVisitingLocation(t)?this.locationIsVisitable(t)?(n=null!=(o=r.action)?o:"advance",this.adapter.visitProposedToLocationWithAction(t,n)):window.location=t:void 0},r.prototype.startVisitToLocationWithAction=function(t,r,n){var o;return e.supported?(o=this.getRestorationDataForIdentifier(n),this.startVisit(t,r,{restorationData:o})):window.location=t},r.prototype.setProgressBarDelay=function(t){return this.progressBarDelay=t},r.prototype.startHistory=function(){return this.location=e.Location.wrap(window.location),this.restorationIdentifier=e.uuid(),this.history.start(),this.history.replace(this.location,this.restorationIdentifier)},r.prototype.stopHistory=function(){return this.history.stop()},r.prototype.pushHistoryWithLocationAndRestorationIdentifier=function(t,r){return this.restorationIdentifier=r,this.location=e.Location.wrap(t),this.history.push(this.location,this.restorationIdentifier)},r.prototype.replaceHistoryWithLocationAndRestorationIdentifier=function(t,r){return this.restorationIdentifier=r,this.location=e.Location.wrap(t),this.history.replace(this.location,this.restorationIdentifier)},r.prototype.historyPoppedToLocationWithRestorationIdentifier=function(t,r){var n;return this.restorationIdentifier=r,this.enabled?(n=this.getRestorationDataForIdentifier(this.restorationIdentifier),this.startVisit(t,"restore",{restorationIdentifier:this.restorationIdentifier,restorationData:n,historyChanged:!0}),this.location=e.Location.wrap(t)):this.adapter.pageInvalidated()},r.prototype.getCachedSnapshotForLocation=function(t){var e;return null!=(e=this.cache.get(t))?e.clone():void 0},r.prototype.shouldCacheSnapshot=function(){return this.view.getSnapshot().isCacheable(); +},r.prototype.cacheSnapshot=function(){var t,r;return this.shouldCacheSnapshot()?(this.notifyApplicationBeforeCachingSnapshot(),r=this.view.getSnapshot(),t=this.lastRenderedLocation,e.defer(function(e){return function(){return e.cache.put(t,r.clone())}}(this))):void 0},r.prototype.scrollToAnchor=function(t){var e;return(e=this.view.getElementForAnchor(t))?this.scrollToElement(e):this.scrollToPosition({x:0,y:0})},r.prototype.scrollToElement=function(t){return this.scrollManager.scrollToElement(t)},r.prototype.scrollToPosition=function(t){return this.scrollManager.scrollToPosition(t)},r.prototype.scrollPositionChanged=function(t){var e;return e=this.getCurrentRestorationData(),e.scrollPosition=t},r.prototype.render=function(t,e){return this.view.render(t,e)},r.prototype.viewInvalidated=function(){return this.adapter.pageInvalidated()},r.prototype.viewWillRender=function(t){return this.notifyApplicationBeforeRender(t)},r.prototype.viewRendered=function(){return this.lastRenderedLocation=this.currentVisit.location,this.notifyApplicationAfterRender()},r.prototype.pageLoaded=function(){return this.lastRenderedLocation=this.location,this.notifyApplicationAfterPageLoad()},r.prototype.clickCaptured=function(){return removeEventListener("click",this.clickBubbled,!1),addEventListener("click",this.clickBubbled,!1)},r.prototype.clickBubbled=function(t){var e,r,n;return this.enabled&&this.clickEventIsSignificant(t)&&(r=this.getVisitableLinkForNode(t.target))&&(n=this.getVisitableLocationForLink(r))&&this.applicationAllowsFollowingLinkToLocation(r,n)?(t.preventDefault(),e=this.getActionForLink(r),this.visit(n,{action:e})):void 0},r.prototype.applicationAllowsFollowingLinkToLocation=function(t,e){var r;return r=this.notifyApplicationAfterClickingLinkToLocation(t,e),!r.defaultPrevented},r.prototype.applicationAllowsVisitingLocation=function(t){var e;return e=this.notifyApplicationBeforeVisitingLocation(t),!e.defaultPrevented},r.prototype.notifyApplicationAfterClickingLinkToLocation=function(t,r){return e.dispatch("turbolinks:click",{target:t,data:{url:r.absoluteURL},cancelable:!0})},r.prototype.notifyApplicationBeforeVisitingLocation=function(t){return e.dispatch("turbolinks:before-visit",{data:{url:t.absoluteURL},cancelable:!0})},r.prototype.notifyApplicationAfterVisitingLocation=function(t){return e.dispatch("turbolinks:visit",{data:{url:t.absoluteURL}})},r.prototype.notifyApplicationBeforeCachingSnapshot=function(){return e.dispatch("turbolinks:before-cache")},r.prototype.notifyApplicationBeforeRender=function(t){return e.dispatch("turbolinks:before-render",{data:{newBody:t}})},r.prototype.notifyApplicationAfterRender=function(){return e.dispatch("turbolinks:render")},r.prototype.notifyApplicationAfterPageLoad=function(t){return null==t&&(t={}),e.dispatch("turbolinks:load",{data:{url:this.location.absoluteURL,timing:t}})},r.prototype.startVisit=function(t,e,r){var n;return null!=(n=this.currentVisit)&&n.cancel(),this.currentVisit=this.createVisit(t,e,r),this.currentVisit.start(),this.notifyApplicationAfterVisitingLocation(t)},r.prototype.createVisit=function(t,r,n){var o,i,s,a,u;return i=null!=n?n:{},a=i.restorationIdentifier,s=i.restorationData,o=i.historyChanged,u=new e.Visit(this,t,r),u.restorationIdentifier=null!=a?a:e.uuid(),u.restorationData=e.copyObject(s),u.historyChanged=o,u.referrer=this.location,u},r.prototype.visitCompleted=function(t){return this.notifyApplicationAfterPageLoad(t.getTimingMetrics())},r.prototype.clickEventIsSignificant=function(t){return!(t.defaultPrevented||t.target.isContentEditable||t.which>1||t.altKey||t.ctrlKey||t.metaKey||t.shiftKey)},r.prototype.getVisitableLinkForNode=function(t){return this.nodeIsVisitable(t)?e.closest(t,"a[href]:not([target]):not([download])"):void 0},r.prototype.getVisitableLocationForLink=function(t){var r;return r=new e.Location(t.getAttribute("href")),this.locationIsVisitable(r)?r:void 0},r.prototype.getActionForLink=function(t){var e;return null!=(e=t.getAttribute("data-turbolinks-action"))?e:"advance"},r.prototype.nodeIsVisitable=function(t){var r;return(r=e.closest(t,"[data-turbolinks]"))?"false"!==r.getAttribute("data-turbolinks"):!0},r.prototype.locationIsVisitable=function(t){return t.isPrefixedBy(this.view.getRootLocation())&&t.isHTML()},r.prototype.getCurrentRestorationData=function(){return this.getRestorationDataForIdentifier(this.restorationIdentifier)},r.prototype.getRestorationDataForIdentifier=function(t){var e;return null!=(e=this.restorationData)[t]?e[t]:e[t]={}},r}()}.call(this),function(){!function(){var t,e;if((t=e=document.currentScript)&&!e.hasAttribute("data-turbolinks-suppress-warning"))for(;t=t.parentNode;)if(t===document.body)return console.warn("You are loading Turbolinks from a + ` + var jsMinAllRegex = / + var result = data + .replace(jsMinAllRegex, code) + // .replace('/js/js_min_all.js', `${cdnHost}/react/build/js/js_min_all.js?v=${newVersion}`) // .replace('/js/js_min_all_2.js', `${cdnHost}/react/build/js/js_min_all_2.js?v=${newVersion}`) // ${cdnHost} 加了cdn后,这个文件里的字体文件加载会有跨域的报错 ../fonts/fontawesome-webfont.eot @@ -204,10 +227,11 @@ function generateNewIndexJsp() { .replace('/css/iconfont.css', `${cdnHost}/react/build/css/iconfont.css?v=${newVersion}`) .replace(/\/js\/create_kindeditor.js/g, `${cdnHost}/react/build/js/create_kindeditor.js?v=${newVersion}`) + .replace(mainRegex, '') // .replace('/react/build/./static/css/main', `${cdnHost}/react/build/./static/css/main`) // .replace('/react/build/./static/js/main', `${cdnHost}/react/build/./static/js/main`) - .replace(/https:\/\/testeduplus2.educoder.net/g, ''); + // .replace(/https:\/\/testeduplus2.educoder.net/g, ''); // .replace(/http:\/\/testbdweb.educoder.net/g, ''); // .replace('/css/css_min_all.css', '/react/build/css/css_min_all.css'); diff --git a/public/react/src/App.css b/public/react/src/App.css index a6f1d45e7..2b3d8d08c 100644 --- a/public/react/src/App.css +++ b/public/react/src/App.css @@ -55,6 +55,10 @@ html, body { .markdown-body p { white-space: pre-wrap; } +/* https://www.educoder.net/courses/2346/group_homeworks/34405/question */ +.renderAsHtml.markdown-body p { + white-space: inherit; +} /* resize */ .editormd .CodeMirror { border-right: none !important; diff --git a/public/react/src/App.js b/public/react/src/App.js index e6f55f5d2..b40af3e0b 100644 --- a/public/react/src/App.js +++ b/public/react/src/App.js @@ -1,4 +1,5 @@ import React, {Component} from 'react'; +import './public-path'; import logo from './logo.svg'; import './App.css'; import {LocaleProvider} from 'antd' diff --git a/public/react/src/common/TextUtil.js b/public/react/src/common/TextUtil.js index 4c83131f1..74cdef3e6 100644 --- a/public/react/src/common/TextUtil.js +++ b/public/react/src/common/TextUtil.js @@ -9,6 +9,7 @@ export function markdownToHTML(oldContent, selector) { window.$('#md_div').html('') // markdown to html if (selector && oldContent && oldContent.startsWith('{ return( -

    - +

    + { item.is_pdf && item.is_pdf == true ? - {item.title} + 30 }> + {item.title} + : - {item.title} + 30 }> + {item.title} + } {item.filesize}

    diff --git a/public/react/src/modules/courses/Resource/Fileslistitem.js b/public/react/src/modules/courses/Resource/Fileslistitem.js index 925bcc817..b06ab3dc1 100644 --- a/public/react/src/modules/courses/Resource/Fileslistitem.js +++ b/public/react/src/modules/courses/Resource/Fileslistitem.js @@ -129,12 +129,16 @@ class Fileslistitem extends Component{ .catch(function (error) { console.log(error); }); - } + } + + eventStop = (event) =>{ + event.stopPropagation() + } render(){ const { checkBox, - discussMessage, + discussMessage,index } = this.props; return( @@ -190,9 +194,9 @@ class Fileslistitem extends Component{ white-space:nowrap } `} -
    -
    - +
    window.$(`.sourceitem${index} input`).click() }> +
    this.eventStop(event)}> + {checkBox} { @@ -283,16 +287,15 @@ class Fileslistitem extends Component{ {this.props.isAdmin? - - + this.eventStop(event)}> - this.settingList()}>设置 - + this.settingList()}>设置 + :""} {this.props.isStudent===true&&this.props.current_user.login===discussMessage.author.login? - + this.eventStop(event)}> { + const checkBoxValues = this.state.checkBoxValues.slice(0); + const index = checkBoxValues.indexOf(item.id); + if (index != -1) { + _.remove(checkBoxValues, (listItem)=> listItem === item.id) + } else { + checkBoxValues.push(item.id); + } + this.onCheckBoxChange(checkBoxValues) + } PaginationTask=(page)=>{ let {search,order,selectpage,checkAllValue,checkBoxValues}=this.state; @@ -787,7 +798,7 @@ class Fileslists extends Component{ showSearchInput={true} > - {this.props.isAdmin()?
    + {this.props.isAdmin()? files===undefined?'' :files.length===0? "":
    {this.props.isAdmin()? 已选 {checkBoxValues.length} 个:""}
    @@ -897,7 +908,7 @@ class Fileslists extends Component{ { files&&files.map((item, index) => { return ( -
    +
    this.onItemClick(item)}>
    :""} Settingtypes={(id)=>this.Settingtypes(id)} coursesId={this.props.match.params.coursesId} - updatafiledfun={()=>this.updatafiled()} + updatafiledfun={()=>this.updatafiled()} + index={index} >
    @@ -948,21 +960,23 @@ class Fileslists extends Component{ />:""}
    -
    -
    - -

    暂时还没有相关数据哦!

    -
    - - + { + files===undefined?'' :files.length===0?:"" + } ) } } -export default Fileslists; \ No newline at end of file +export default Fileslists; + +{/*
    */} + {/*
    */} + {/**/} + {/*

    暂时还没有相关数据哦!

    */} +{/*
    */} \ No newline at end of file diff --git a/public/react/src/modules/courses/boards/BoardsNew.js b/public/react/src/modules/courses/boards/BoardsNew.js index 2df6270c2..0b27ea8b8 100644 --- a/public/react/src/modules/courses/boards/BoardsNew.js +++ b/public/react/src/modules/courses/boards/BoardsNew.js @@ -376,10 +376,15 @@ class BoardsNew extends Component{ dropdownRender={menu => (
    {menu} - -
    this.refs['addDirModal'].open()}> - 添加目录 -
    + { + isAdmin && + + +
    this.refs['addDirModal'].open()}> + 添加目录 +
    +
    + }
    )} > diff --git a/public/react/src/modules/courses/boards/TopicDetail.js b/public/react/src/modules/courses/boards/TopicDetail.js index 432c597ee..542157bfb 100644 --- a/public/react/src/modules/courses/boards/TopicDetail.js +++ b/public/react/src/modules/courses/boards/TopicDetail.js @@ -24,7 +24,7 @@ import '../../forums/RightSection.css' import './TopicDetail.css' import '../common/courseMessage.css' import { Pagination, Tooltip } from 'antd' -import { bytesToSize, ConditionToolTip, markdownToHTML, MarkdownToHtml } from 'educoder' +import { bytesToSize, ConditionToolTip, markdownToHTML, MarkdownToHtml , setImagesUrl } from 'educoder' import SendToCourseModal from '../coursesPublic/modal/SendToCourseModal' import CBreadcrumb from '../common/CBreadcrumb' import { generateComments, generateChildComments, _findById, handleContentBeforeCreateNew, addNewComment @@ -57,6 +57,7 @@ class TopicDetail extends Component { pageCount: 1, comments: [], goldRewardDialogOpen: false, + author:undefined } } componentDidMount() { @@ -85,7 +86,8 @@ class TopicDetail extends Component { memo: Object.assign({}, { ...response.data.data, replies_count: response.data.data.total_replies_count - }, {...this.state.memo}) + }, {...this.state.memo}), + author:response.data.data.author }, () => { }) @@ -514,7 +516,7 @@ class TopicDetail extends Component { render() { const { match, history } = this.props const { recommend_shixun, current_user,author_info } = this.props; - const { memo, comments, hasMoreComments, goldRewardDialogOpen, pageCount, total_count } = this.state; + const { memo, comments, hasMoreComments, goldRewardDialogOpen, pageCount, total_count , author } = this.state; const messageId = match.params.topicId if (this.state.memoLoading || !current_user) { return
    @@ -599,51 +601,54 @@ class TopicDetail extends Component { }
    -
    - {moment(memo.created_on).fromNow()} 发布 -
    - -
    -
    - -
    - - {/* { current_user.admin && - - - - } */} - - - - {memo.visits || '1'} - - - { !!memo.total_replies_count && - - - - { memo.total_replies_count } - - - } - {!!memo.praises_count && - - - - { memo.praises_count } +
    + +
    +
    + {author && author.name} + {moment(memo.created_on).fromNow()} 发布 +
    + +
    + + {/* { current_user.admin && + + - + } */} + + + + {memo.visits || '1'} + + + { !!memo.total_replies_count && + + + + { memo.total_replies_count } + + } - - + {!!memo.total_praises_count && + + + + { memo.total_praises_count } + + + } + + +
    +
    diff --git a/public/react/src/modules/courses/boards/index.js b/public/react/src/modules/courses/boards/index.js index db3232b23..60d327799 100644 --- a/public/react/src/modules/courses/boards/index.js +++ b/public/react/src/modules/courses/boards/index.js @@ -363,9 +363,9 @@ class Boards extends Component{ */} - {isAdmin &&
    -
    - {isAdmin && 已选 {checkBoxValues.length} 个} + {messages&&messages.length == 0?"": isAdmin &&
    +
    + {isAdmin&&已选 {checkBoxValues.length} 个}
    { !!isAdmin && diff --git a/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js b/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js index 3a7e25fcd..ae40fedda 100644 --- a/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js +++ b/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js @@ -15,7 +15,7 @@ import WorkDetailPageHeader from './common/WorkDetailPageHeader' import CommonWorkAppraiseReply from './reply/CommonWorkAppraiseReply' import Example from './TestHooks' import CommonWorkAppraiseReviseAttachments from './CommonWorkAppraiseReviseAttachments' - +import LeaderIcon from './common/LeaderIcon' const { Option} = Select; const CheckboxGroup = Checkbox.Group; const confirm = Modal.confirm; @@ -88,6 +88,14 @@ class CommonWorkAppraise extends Component{ console.log(error) }) } + componentDidUpdate(prevProps, prevState) { + if (this.props.match.params.studentWorkId != prevProps.match.params.studentWorkId) { + this.getWork(); + this.getReviseAttachments() + this.commonWorkAppraiseReply && this.commonWorkAppraiseReply.fetchAllComments() + } + } + componentDidMount() { this.getWork(); this.getReviseAttachments() @@ -156,12 +164,13 @@ class CommonWorkAppraise extends Component{ attachments, homework_id, project_info, work_members, is_evaluation, description, update_user_name, update_time, commit_time, author_name, revise_attachments, revise_reason, atta_update_user, atta_update_time, atta_update_user_login, - Modalstype,Modalstopval,ModalCancel,ModalSave,loadtype + Modalstype,Modalstopval,ModalCancel,ModalSave,loadtype, is_leader_work } =this.state; let courseId=this.props.match.params.coursesId; let category_id=this.props.match.params.category_id; let studentWorkId=this.props.match.params.studentWorkId; + const isAdmin = this.props.isAdmin() return(
    - 其他组员 + 全部组员
    -
    - {work_members.map((item, index) => { - return item.user_name + ' ' - })} +
    +
    + 当前组员:{author_name} {is_leader_work && } +
    +
    + 其他组员: + {work_members.map((item, index) => { + return + {isAdmin ? + this.props.toWorkDetailPage(this.props.match.params, null, item.work_id)} + > + {item.user_name} + : {item.user_name}} + {item.is_leader && } + + })} +
    +
    } @@ -266,6 +290,7 @@ class CommonWorkAppraise extends Component{ {/* task_type={datalist&&datalist.task_type} */} {this.commonWorkAppraiseReply = ref}} >
    diff --git a/public/react/src/modules/courses/busyWork/CommonWorkList.js b/public/react/src/modules/courses/busyWork/CommonWorkList.js index 528aa1d9e..28e54fff3 100644 --- a/public/react/src/modules/courses/busyWork/CommonWorkList.js +++ b/public/react/src/modules/courses/busyWork/CommonWorkList.js @@ -15,7 +15,7 @@ import WorkDetailPageHeader from './common/WorkDetailPageHeader' import PublishRightnow from './PublishRightnow' import ModulationModal from "../coursesPublic/ModulationModal"; import AccessoryModal from "../coursesPublic/AccessoryModal"; - +import LeaderIcon from './common/LeaderIcon' const { Option} = Select; const CheckboxGroup = Checkbox.Group; const confirm = Modal.confirm; @@ -97,7 +97,12 @@ function buildColumns(that, student_works, studentData) { }} title={text && text.length > 5 ? text : ''}> {/* */} - {text} + {record.is_leader ? +
    +
    {text}
    + +
    + : {text}}
    ), }] diff --git a/public/react/src/modules/courses/busyWork/CommonWorkQuestion.js b/public/react/src/modules/courses/busyWork/CommonWorkQuestion.js index f400cd9a2..d2ce6b8e4 100644 --- a/public/react/src/modules/courses/busyWork/CommonWorkQuestion.js +++ b/public/react/src/modules/courses/busyWork/CommonWorkQuestion.js @@ -91,7 +91,7 @@ class CommonWorkQuestion extends Component{ {/* 内容区 */}
    - + { attachments && attachments.map((item) => { return (
    diff --git a/public/react/src/modules/courses/busyWork/UseBank.js b/public/react/src/modules/courses/busyWork/UseBank.js index ca65e74be..951408014 100644 --- a/public/react/src/modules/courses/busyWork/UseBank.js +++ b/public/react/src/modules/courses/busyWork/UseBank.js @@ -128,7 +128,7 @@ class UseBank extends Component{ }) } onSave = () => { - + debugger const { checkBoxValues } = this.state; const { object_type } = this.props if(checkBoxValues.length==0){ diff --git a/public/react/src/modules/courses/busyWork/common/LeaderIcon.js b/public/react/src/modules/courses/busyWork/common/LeaderIcon.js new file mode 100644 index 000000000..526e165c5 --- /dev/null +++ b/public/react/src/modules/courses/busyWork/common/LeaderIcon.js @@ -0,0 +1,19 @@ +import React,{Component} from "React"; + +export default function LeaderIcon(props = {}) { + let icon = null; + if (props.small) { + icon =
    组长
    + } else { + icon =
    组长
    + + } + return icon +} \ No newline at end of file diff --git a/public/react/src/modules/courses/busyWork/common/WorkDetailPageHeader.js b/public/react/src/modules/courses/busyWork/common/WorkDetailPageHeader.js index a092c5066..4177be8a4 100644 --- a/public/react/src/modules/courses/busyWork/common/WorkDetailPageHeader.js +++ b/public/react/src/modules/courses/busyWork/common/WorkDetailPageHeader.js @@ -85,8 +85,7 @@ class WorkDetailPageHeader extends Component{ background: #fff; } .workDetailPageHeader .summaryname { - line-height: 20px; - margin-top: 13px; + line-height:30px } `} -
    - +
    + {homework_name} {/* {homework_name} */} - {category && 返回} + {category && 返回} {this.props.update_atta && diff --git a/public/react/src/modules/courses/busyWork/commonWork.js b/public/react/src/modules/courses/busyWork/commonWork.js index f9c34cfcf..d5ac0be68 100644 --- a/public/react/src/modules/courses/busyWork/commonWork.js +++ b/public/react/src/modules/courses/busyWork/commonWork.js @@ -143,7 +143,9 @@ class commonWork extends Component{ this.setState({ order:e.key==="all"?"":e.key, page:1, - isSpin:true + isSpin:true, + checkBoxValues:[], + checkAll:false }) let {search}=this.state; this.getList(1,search,e.key==="all"?"":e.key); diff --git a/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js b/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js index af2d115fc..cc29cb2a0 100644 --- a/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js +++ b/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js @@ -750,7 +750,8 @@ class Coursesleftnav extends Component{ {/*分班*/} {item.type==="course_group"?
    this.Navmodalnames(e,2,"course_group",item.id)}>添加分班
    :""} {/*分班*/} - {item.type==="course_group"?
    this.Navmodalnames(e,5,"editname",item.id,item.name)}>重命名
    :
    this.Navmodalnames(e,3,"editname",item.id,item.name)}>重命名
    } + {/*{item.type==="course_group"? :""}*/} +
    this.Navmodalnames(e,3,"editname",item.id,item.name)}>重命名
    this.edithidden(e,item.id)}>隐藏
    this.editSetup(e,item.id)}>置顶
    diff --git a/public/react/src/modules/courses/coursesPublic/NoneData.js b/public/react/src/modules/courses/coursesPublic/NoneData.js index 73406ab5c..35d7a5271 100644 --- a/public/react/src/modules/courses/coursesPublic/NoneData.js +++ b/public/react/src/modules/courses/coursesPublic/NoneData.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import {getImageUrl} from 'educoder'; +import { getImageUrl , getUrl } from 'educoder'; class NoneData extends Component{ constructor(props) { @@ -9,7 +9,20 @@ class NoneData extends Component{ const { style } = this.props; return(
    - + +

    暂时还没有相关数据哦!

    ) diff --git a/public/react/src/modules/courses/coursesPublic/PathModal.js b/public/react/src/modules/courses/coursesPublic/PathModal.js index 07ce55024..33a2cb68d 100644 --- a/public/react/src/modules/courses/coursesPublic/PathModal.js +++ b/public/react/src/modules/courses/coursesPublic/PathModal.js @@ -180,11 +180,13 @@ class PathModal extends Component{ }else{ // this.homeworkstart //调用立即发布弹窗 + // this.props.showNotification(response.data.message) this.props.hidecouseShixunModal(); - this.props.courseshomeworkstart(response.data.category_id,response.data.homework_ids) + this.props.updataleftNavfun() + // this.props.courseshomeworkstart(response.data.category_id,response.data.homework_ids) // this.props.showNotification("选用成功") // this.props.showNotification(response.data.message) - // this.props.homeworkupdatalists(Coursename,page,order); + this.props.homeworkupdatalists(this.props.Coursename,this.props.page,this.props.order); } // if(response.status===200) { diff --git a/public/react/src/modules/courses/coursesPublic/ShixunModal.js b/public/react/src/modules/courses/coursesPublic/ShixunModal.js index 2a53cf104..24bb7310e 100644 --- a/public/react/src/modules/courses/coursesPublic/ShixunModal.js +++ b/public/react/src/modules/courses/coursesPublic/ShixunModal.js @@ -186,7 +186,8 @@ class ShixunModal extends Component{ // this.props.showNotification(response.data.message) }else{ - this.props.courseshomeworkstart(response.data.category_id,response.data.homework_ids) + // this.props.courseshomeworkstart(response.data.category_id,response.data.homework_ids) + this.props.homeworkupdatalists(this.props.Coursename,this.props.page,this.props.order); this.props.hidecouseShixunModal() } this.setState({ diff --git a/public/react/src/modules/courses/coursesPublic/modal/SendToCourseModal.js b/public/react/src/modules/courses/coursesPublic/modal/SendToCourseModal.js index af3fc1a30..c4c306a12 100644 --- a/public/react/src/modules/courses/coursesPublic/modal/SendToCourseModal.js +++ b/public/react/src/modules/courses/coursesPublic/modal/SendToCourseModal.js @@ -1,209 +1,209 @@ -import React, { Component } from "react"; -import { Modal, Checkbox, Input, Spin} from "antd"; -import axios from 'axios' -import ModalWrapper from "../../common/ModalWrapper" -import InfiniteScroll from 'react-infinite-scroller'; - -const Search = Input.Search -const pageCount = 15; -class SendToCourseModal extends Component{ - constructor(props){ - super(props); - this.state={ - checkBoxValues: [], - course_lists: [], - course_lists_after_filter: [], - searchValue: '', - hasMore: true, - loading: false, - page: 1 - } - } - fetchCourseList = (arg_page) => { - const page = arg_page || this.state.page; - // search=''& - let url = `/courses/mine.json?page=${page}&page_size=${pageCount}` - const searchValue = this.state.searchValue.trim() - if (searchValue) { - url += `&search=${searchValue}` - } - this.setState({ loading: true }) - axios.get(url, { - }) - .then((response) => { - if (!response.data.data || response.data.data.length == 0) { - this.setState({ - course_lists: page == 1 ? [] : this.state.course_lists, - page, - loading: false, - hasMore: false, - }) - } else { - this.setState({ - course_lists: page == 1 ? response.data.data : this.state.course_lists.concat(response.data.data), - course_lists_after_filter: response.data.data, - page, - loading: false, - hasMore: response.data.data.length == pageCount - }) - } - - }) - .catch(function (error) { - console.log(error); - }); - } - componentDidMount() { - setTimeout(() => { - this.fetchCourseList() - }, 500) - - } - setVisible = (visible) => { - this.refs.modalWrapper.setVisible(visible) - if (visible == false) { - this.setState({ - checkBoxValues: [] - }) - } - } - - onSendOk = () => { - if (!this.state.checkBoxValues || this.state.checkBoxValues.length == 0) { - this.props.showNotification('请先选择要发送至的课堂') - return; - } - if(this.props.url==="/files/bulk_send.json"){ - axios.post("/files/bulk_send.json", { - course_id:this.props.match.params.coursesId, - ids: this.props.selectedMessageIds, - to_course_ids: this.state.checkBoxValues - }) - .then((response) => { - if (response.data.status == 0) { - this.setVisible(false) - this.props.gobackonSend(response.data.message) - } - }) - .catch(function (error) { - console.log(error); - }); - }else{ - const bid = this.props.match.params.boardId - const url = `/boards/${bid}/messages/bulk_send.json` - axios.post(url, { - ids: this.props.selectedMessageIds, - to_course_ids: this.state.checkBoxValues - }) - .then((response) => { - if (response.data.status == 0) { - this.setVisible(false) - this.props.showNotification('发送成功') - } - }) - .catch(function (error) { - console.log(error); - }); - } - - } - - onOk = () => { - const { course_lists, checkBoxValues } = this.state - this.onSendOk() - // this.props.onOk && this.props.onOk(checkBoxValues) - - // this.refs.modalWrapper.setVisible(false) - } - - onCheckBoxChange = (checkBoxValues) => { - this.setState({ - checkBoxValues: checkBoxValues - }) - } - - onSearchChange = (e) => { - this.setState({ - searchValue: e.target.value - }) - } - handleInfiniteOnLoad = () => { - console.log('loadmore...') - this.fetchCourseList(this.state.page + 1) - } - - onSearch = () => { - // const course_lists_after_filter = this.state.course_lists.filter( item => item.name.indexOf(this.state.searchValue) != -1 ) - // this.setState({ course_lists_after_filter }) - this.fetchCourseList(1) - } - render(){ - const { course_lists, checkBoxValues, searchValue, loading, hasMore } = this.state - const { moduleName } = this.props - return( - - -

    选择的{moduleName}发送到指定课堂

    - - - -
    - {/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */} -
    - - - - { course_lists && course_lists.map( course => { - return ( -

    - - -

    - ) - }) } -
    - {loading && hasMore && ( -
    - -
    - )} - {/* TODO */} - {/* { - !hasMore &&
    没有更多了。。
    - } */} -
    -
    -
    -
    - ) - } -} -export default SendToCourseModal; - - +import React, { Component } from "react"; +import { Modal, Checkbox, Input, Spin} from "antd"; +import axios from 'axios' +import ModalWrapper from "../../common/ModalWrapper" +import InfiniteScroll from 'react-infinite-scroller'; + +const Search = Input.Search +const pageCount = 15; +class SendToCourseModal extends Component{ + constructor(props){ + super(props); + this.state={ + checkBoxValues: [], + course_lists: [], + course_lists_after_filter: [], + searchValue: '', + hasMore: true, + loading: false, + page: 1 + } + } + fetchCourseList = (arg_page) => { + const page = arg_page || this.state.page; + // search=''& + let url = `/courses/mine.json?page=${page}&page_size=${pageCount}` + const searchValue = this.state.searchValue.trim() + if (searchValue) { + url += `&search=${searchValue}` + } + this.setState({ loading: true }) + axios.get(url, { + }) + .then((response) => { + if (!response.data.data || response.data.data.length == 0) { + this.setState({ + course_lists: page == 1 ? [] : this.state.course_lists, + page, + loading: false, + hasMore: false, + }) + } else { + this.setState({ + course_lists: page == 1 ? response.data.data : this.state.course_lists.concat(response.data.data), + course_lists_after_filter: response.data.data, + page, + loading: false, + hasMore: response.data.data.length == pageCount + }) + } + + }) + .catch(function (error) { + console.log(error); + }); + } + componentDidMount() { + setTimeout(() => { + this.fetchCourseList() + }, 500) + + } + setVisible = (visible) => { + this.refs.modalWrapper.setVisible(visible) + if (visible == false) { + this.setState({ + checkBoxValues: [] + }) + } + } + + onSendOk = () => { + if (!this.state.checkBoxValues || this.state.checkBoxValues.length == 0) { + this.props.showNotification('请先选择要发送至的课堂') + return; + } + if(this.props.url==="/files/bulk_send.json"){ + axios.post("/files/bulk_send.json", { + course_id:this.props.match.params.coursesId, + ids: this.props.selectedMessageIds, + to_course_ids: this.state.checkBoxValues + }) + .then((response) => { + if (response.data.status == 0) { + this.setVisible(false) + this.props.gobackonSend(response.data.message) + } + }) + .catch(function (error) { + console.log(error); + }); + }else{ + const bid = this.props.match.params.boardId + const url = `/boards/${bid}/messages/bulk_send.json` + axios.post(url, { + ids: this.props.selectedMessageIds, + to_course_ids: this.state.checkBoxValues + }) + .then((response) => { + if (response.data.status == 0) { + this.setVisible(false) + this.props.showNotification('发送成功') + } + }) + .catch(function (error) { + console.log(error); + }); + } + + } + + onOk = () => { + const { course_lists, checkBoxValues } = this.state + this.onSendOk() + // this.props.onOk && this.props.onOk(checkBoxValues) + + // this.refs.modalWrapper.setVisible(false) + } + + onCheckBoxChange = (checkBoxValues) => { + this.setState({ + checkBoxValues: checkBoxValues + }) + } + + onSearchChange = (e) => { + this.setState({ + searchValue: e.target.value + }) + } + handleInfiniteOnLoad = () => { + console.log('loadmore...') + this.fetchCourseList(this.state.page + 1) + } + + onSearch = () => { + // const course_lists_after_filter = this.state.course_lists.filter( item => item.name.indexOf(this.state.searchValue) != -1 ) + // this.setState({ course_lists_after_filter }) + this.fetchCourseList(1) + } + render(){ + const { course_lists, checkBoxValues, searchValue, loading, hasMore } = this.state + const { moduleName } = this.props + return( + + +

    选择的{moduleName}发送到指定课堂

    + + + +
    + {/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */} +
    + + + + { course_lists && course_lists.map( course => { + return ( +

    + + +

    + ) + }) } +
    + {loading && hasMore && ( +
    + +
    + )} + {/* TODO */} + {/* { + !hasMore &&
    没有更多了。。
    + } */} +
    +
    +
    +
    + ) + } +} +export default SendToCourseModal; + + diff --git a/public/react/src/modules/courses/css/members.css b/public/react/src/modules/courses/css/members.css index ff6f0d99d..df3f884d9 100644 --- a/public/react/src/modules/courses/css/members.css +++ b/public/react/src/modules/courses/css/members.css @@ -1,80 +1,80 @@ -.studentList_operation_ul{ - color: #999; - font-size: 12px; - float: right; - margin-top: 2px; -} -.studentList_operation_ul li{ - float: left; - padding:0px 20px; - position: relative; - cursor: pointer; - flex: 0 0 26px; - line-height: 26px; -} -.studentList_operation_ul li.li_line:after{ - position: absolute; - content: ''; - width: 1px; - height: 12px; - background-color: #EDEDED; - right: 0px; - top:6px; -} -.studentList_operation_ul li:last-child{ - padding-right: 0px; -} -.studentList_operation_ul li:last-child:after{ - width: 0px; -} - -/* 基础的下拉列表、列如排序等 */ -.drop_down_normal li{ - padding: 0px 20px; - height: 34px; - line-height: 34px; - min-width: 96px; - color: #333; - font-size: 14px; - cursor: pointer; - width: 100%; -} - -.stu_table table{ - line-height: 1.2; -} -.stu_table .classesName{ - display: block; - max-width: 428px; -} -.stu_table .ant-table-thead > tr > th{ - padding:21px 16px; - border-bottom: none; -} -.stu_table .ant-table-tbody tr:last-child td{ - border-bottom: none; -} -.stu_table table .ant-table-tbody > tr:hover:not(.ant-table-expanded-row) > td{ - background-color: #fff; -} - -.stu_head{ - padding-bottom: 15px; -} -.ant-modal-body{ - padding:30px 40px; -} -.color-dark-21{ - color: #212121; -} -.tabletd { - background-color:#E6F7FF; -} - -.yslminheigth{ - min-height: 20px; -} - -.yslminheigths{ - min-height: 21px; +.studentList_operation_ul{ + color: #999; + font-size: 12px; + float: right; + margin-top: 2px; +} +.studentList_operation_ul li{ + float: left; + padding:0px 20px; + position: relative; + cursor: pointer; + flex: 0 0 26px; + line-height: 26px; +} +.studentList_operation_ul li.li_line:after{ + position: absolute; + content: ''; + width: 1px; + height: 12px; + background-color: #EDEDED; + right: 0px; + top:6px; +} +.studentList_operation_ul li:last-child{ + padding-right: 0px; +} +.studentList_operation_ul li:last-child:after{ + width: 0px; +} + +/* 基础的下拉列表、列如排序等 */ +.drop_down_normal li{ + padding: 0px 20px; + height: 34px; + line-height: 34px; + min-width: 96px; + color: #333; + font-size: 14px; + cursor: pointer; + width: 100%; +} + +.stu_table table{ + line-height: 1.2; +} +.stu_table .classesName{ + display: block; + max-width: 428px; +} +.stu_table .ant-table-thead > tr > th{ + padding:21px 16px; + border-bottom: none; +} +.stu_table .ant-table-tbody tr:last-child td{ + border-bottom: none; +} +.stu_table table .ant-table-tbody > tr:hover:not(.ant-table-expanded-row) > td{ + background-color: #fff; +} + +.stu_head{ + padding-bottom: 15px; +} +.ant-modal-body{ + padding:30px 40px; +} +.color-dark-21{ + color: #212121; +} +.tabletd { + background-color:#E6F7FF; +} + +.yslminheigth{ + min-height: 20px; +} + +.yslminheigths{ + min-height: 21px; } \ No newline at end of file diff --git a/public/react/src/modules/courses/exercise/Exercise.js b/public/react/src/modules/courses/exercise/Exercise.js index 4331bdc6f..83227fb5a 100644 --- a/public/react/src/modules/courses/exercise/Exercise.js +++ b/public/react/src/modules/courses/exercise/Exercise.js @@ -171,7 +171,20 @@ class Exercise extends Component{ checkAllValue: checkedValues.length == exercises.length }) } - // 全选or反选 + + + onItemClick = (item) => { + const checkBoxValues = this.state.checkBoxValues.slice(0); + const index = checkBoxValues.indexOf(item.id); + if (index != -1) { + _.remove(checkBoxValues, (listItem)=> listItem === item.id) + } else { + checkBoxValues.push(item.id) + } + this.onCheckBoxChange(checkBoxValues) + } + + // 全选or反选 onCheckAll = (e) => { this.setState({ checkAllValue: e.target.checked @@ -507,7 +520,7 @@ class Exercise extends Component{
    - {this.props.isAdmin()?
    + {this.props.isAdmin()?exercises && exercises.length ===0?"":
    已选 {checkBoxValues.length} 个
    @@ -559,9 +572,9 @@ class Exercise extends Component{ {...this.props} {...this.state} item={item} - key={key} - checkBox={ this.onItemClick(item)} + index={key} + onItemClick={this.onItemClick} + checkBox={} > ) diff --git a/public/react/src/modules/courses/exercise/ExerciseListItem.js b/public/react/src/modules/courses/exercise/ExerciseListItem.js index e890b92ef..5248f4c1a 100644 --- a/public/react/src/modules/courses/exercise/ExerciseListItem.js +++ b/public/react/src/modules/courses/exercise/ExerciseListItem.js @@ -52,17 +52,17 @@ class ExerciseListItem extends Component{ }) } render(){ - let{item,checkBox}=this.props; + let{item,checkBox,index}=this.props; let {coursesId,Id}=this.props.match.params const IsAdmin =this.props.isAdmin(); const IsStudent =this.props.isStudent(); // console.log(this.props.current_user.user_id) return( -
    +
    window.$(`.exerciseitem${index} input`).click() }> { - IsAdmin && - + IsAdmin && + {checkBox} } @@ -96,20 +96,20 @@ class ExerciseListItem extends Component{ {/*{item.exercise_name}*/} { - this.props.isAdmin()? {item.exercise_name}:"" + to={`/courses/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`}>{item.exercise_name}:"" } { this.props.isStudent()? - {item.exercise_name}:"" + {item.exercise_name}:"" } { this.props.isNotMember()? item.lock_status === 0 ? {item.exercise_name} - : {item.exercise_name}:"" + : {item.exercise_name}:"" } { @@ -165,8 +165,8 @@ class ExerciseListItem extends Component{ { IsAdmin &&
    - 编辑 - 设置 + 编辑 + 设置
    }

    @@ -193,7 +193,7 @@ class ExerciseListItem extends Component{
    {item.current_status ===0&&item.exercise_status>1?
  • 继续答题
  • : item.current_status ===1&&item.exercise_status>1?
  • 查看答题
  • : - item.current_status ===2&&item.exercise_status>1?
  • this.setgameexercise(`/courses/${coursesId}/exercises/${item.id}/users/${this.props.current_user.login}`)}>开始答题
  • :""} + item.current_status ===2&&item.exercise_status>1?
  • this.setgameexercise(`/courses/${coursesId}/exercises/${item.id}/users/${this.props.current_user.login}`)}>开始答题
  • :""}
    }
    diff --git a/public/react/src/modules/courses/exercise/ExerciseReviewAndAnswer.js b/public/react/src/modules/courses/exercise/ExerciseReviewAndAnswer.js index cdbc7218b..f38ad7435 100644 --- a/public/react/src/modules/courses/exercise/ExerciseReviewAndAnswer.js +++ b/public/react/src/modules/courses/exercise/ExerciseReviewAndAnswer.js @@ -541,6 +541,18 @@ class ExerciseReviewAndAnswer extends Component{ .inputNumber30 .ant-input-number-input-wrap .ant-input-number-input{ height: 28px; } + .setRadioStyle{ + width:100%; + cursor:pointer; + } + .setRadioStyle span:last-child{ + flex:1; + display:flex; + } + .setRadioStyle .ant-radio,.setRadioStyle .ant-checkbox{ + height:16px; + margin-top:2px; + } `} {/*

    */} - + { questionType.question_choices && questionType.question_choices.map((item,key)=>{ let prefix = `${tagArray[key]}.` return(

    - {prefix} - {/* */} - {/* */} - + + {prefix} + +

    ) }) diff --git a/public/react/src/modules/courses/exercise/question/single.js b/public/react/src/modules/courses/exercise/question/single.js index a879bad74..5156019d4 100644 --- a/public/react/src/modules/courses/exercise/question/single.js +++ b/public/react/src/modules/courses/exercise/question/single.js @@ -40,18 +40,18 @@ class single extends Component{ let isJudge = questionType.question_type == 2 return(
    - + { questionType.question_choices && questionType.question_choices.map((item,key)=>{ let prefix = isJudge ? undefined : `${tagArray[key]}.` return( -

    - {prefix} - {/* */} - {/* */} - +

    + + {prefix} + +

    ) }) diff --git a/public/react/src/modules/courses/gradinforms/Bullsubdirectory.js b/public/react/src/modules/courses/gradinforms/Bullsubdirectory.js index ebfd2d51b..b9ec4b75c 100644 --- a/public/react/src/modules/courses/gradinforms/Bullsubdirectory.js +++ b/public/react/src/modules/courses/gradinforms/Bullsubdirectory.js @@ -1,5 +1,5 @@ import React,{ Component } from "react"; -import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form } from "antd"; +import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form,Row, Col } from "antd"; import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder'; import './myysleduinforms.css' import axios from 'axios'; @@ -165,18 +165,25 @@ class Bullsubdirectory extends Component{ { whethertoeditysl === false?
    -
    -
    {myname}
    - { - this.props.isAdmin() === true ? - (this.props.yslbool===false? - this.bianji(true)}> - : - "" - ) - - :"" - } +
    +
    +
    + {myname} +
    +
    + + { + this.props.isAdmin() === true ? + (this.props.yslbool===false? + this.bianji(true)}> + : + "" + ) + :"" + } + +
    +
    diff --git a/public/react/src/modules/courses/gradinforms/myysleduinforms.css b/public/react/src/modules/courses/gradinforms/myysleduinforms.css index 1e86607ec..ab2884ffe 100644 --- a/public/react/src/modules/courses/gradinforms/myysleduinforms.css +++ b/public/react/src/modules/courses/gradinforms/myysleduinforms.css @@ -68,7 +68,6 @@ } .fudonyingxiangysl{ width: 100%; - height: 66px; } .yslbianji{ padding-top: 31px; @@ -79,3 +78,5 @@ .ysldashed{ border:1px dashed #EEE; } +.yslclear{ clear: both; +} diff --git a/public/react/src/modules/courses/graduation/tasks/GraduateTaskItem.js b/public/react/src/modules/courses/graduation/tasks/GraduateTaskItem.js index d30944ef0..92a4832db 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduateTaskItem.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduateTaskItem.js @@ -151,16 +151,12 @@ class GraduateTaskItem extends Component{ coursesId, categoryid, taskid, - + index, + isAdmin } = this.props; - // console.log(discussMessage) - - - - return( -
    +
    window.$(`.taskitem${index} input`).click() }> - { checkBox } - + + { checkBox } + {/* style={{borderTop:data===undefined?"":data.course_identity<4?'1px solid #EBEBEB':'1px solid transparent'}} */} diff --git a/public/react/src/modules/courses/graduation/tasks/index.js b/public/react/src/modules/courses/graduation/tasks/index.js index b54815b2f..18e6f3deb 100644 --- a/public/react/src/modules/courses/graduation/tasks/index.js +++ b/public/react/src/modules/courses/graduation/tasks/index.js @@ -13,6 +13,7 @@ import Modals from '../../../modals/Modals'; import UseBank from "../../busyWork/UseBank"; import '../../css/members.css'; import '../style.css'; +import NoneData from "../../coursesPublic/NoneData"; class GraduationTasks extends Component{ @@ -350,8 +351,6 @@ class GraduationTasks extends Component{ checkBoxValues: checkedValues, checkAllValue:type }) - - } @@ -384,7 +383,9 @@ class GraduationTasks extends Component{ this.setState({ order: e.key, - isSpin:true + isSpin:true, + checkBoxValues:[], + checkAllValue:false }); let newkey=e.key; @@ -563,6 +564,7 @@ class GraduationTasks extends Component{ let {search,page,order,all_count} = this.state; this.fetchAll(search,page,order,all_count) + } getcourse_groupslist=(id)=>{ this.setState({ @@ -696,7 +698,7 @@ class GraduationTasks extends Component{ */} - {this.props.isAdmin()?
    + {this.props.isAdmin()?all_count===undefined?'' :all_count===0?"":
    已选 {checkBoxValues.length} 个
    @@ -726,10 +728,10 @@ class GraduationTasks extends Component{ } `} - { tasks.map((item, index) => { + { tasks&&tasks.map((item, index) => { // console.log(item) return ( -
    +
    @@ -770,18 +773,11 @@ class GraduationTasks extends Component{ />
    } -
    -
    - -

    暂时还没有相关数据哦!

    -
    + + { + tasks===undefined?'' :tasks.length===0? :"" + }
    @@ -790,4 +786,16 @@ class GraduationTasks extends Component{ ) } } -export default GraduationTasks; \ No newline at end of file +export default GraduationTasks; + +{/*
    */} + {/*
    */} + {/**/} + {/*

    暂时还没有相关数据哦!

    */} +{/*
    */} diff --git a/public/react/src/modules/courses/graduation/topics/GraduateTopicDetailInfo.js b/public/react/src/modules/courses/graduation/topics/GraduateTopicDetailInfo.js index 0c76cd9de..033033c42 100644 --- a/public/react/src/modules/courses/graduation/topics/GraduateTopicDetailInfo.js +++ b/public/react/src/modules/courses/graduation/topics/GraduateTopicDetailInfo.js @@ -6,7 +6,7 @@ import '../style.css' import axios from "axios"; import GraduateTopicReply from './GraduateTopicReply' -import { ConditionToolTip,MarkdownToHtml } from 'educoder' +import { ConditionToolTip , MarkdownToHtml , AttachmentList } from 'educoder' const $=window.$; const type={1: "设计",2: "论文", 3: "创作"} @@ -59,10 +59,11 @@ class GraduateTopicDetailTable extends Component{
    { topicInfo && topicInfo.attachment_list.length>0 && -

    - { +

    + {/* { topicInfo.attachment_list.map((item,key)=>{ return( +
  • 30 }> @@ -72,8 +73,9 @@ class GraduateTopicDetailTable extends Component{
  • ) }) - } -

    + } */} + +
    }
    diff --git a/public/react/src/modules/courses/graduation/topics/GraduateTopicItem.js b/public/react/src/modules/courses/graduation/topics/GraduateTopicItem.js index 9f61e69d4..bac04c699 100644 --- a/public/react/src/modules/courses/graduation/topics/GraduateTopicItem.js +++ b/public/react/src/modules/courses/graduation/topics/GraduateTopicItem.js @@ -47,7 +47,7 @@ class GraduateTopicItem extends Component{ } -
    +
    window.$(`.topicItem${index} input`).click() }> - { isAdmin ? checkBox : ""} + { isAdmin ? {checkBox} : ""}
    -
    - 姓名: - {this.setState({name: e.target.value})}} - style={{ width: '221px'}} - > - 单位: - {/* {this.setState({school_name: e.target.value})}} - style={{ width: '200px'}}> - */} - {this.setState({school_name: value})}} - > - this.fetchMemberList(1)} - style={{ height: '30px', lineHeight: '30px', marginLeft: '10px', width: '70px'}} - >搜索 -
    - {/* */} - - -

    - - - - - - -

    - - { loading || users.length ?
    - {/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */} -
    - - - - { users.map( candidate => { - return ( -

    - - - 12 }> - - - - - 12 }> - - - - - - -

    - ) - }) } -
    - {loading && hasMore && ( -
    - -
    - )} - -
    -
    - {course_groups && course_groups.length &&
    - 所选学生分班至(选填): - -
    } -
    : } -
    - - ) - } -} - -AddStudentModal.contextType = ThemeContext; -export default AddStudentModal; +import React, { Component } from "react"; +import { Modal, Checkbox, Input, Spin, Select, Divider } from "antd"; +import axios from 'axios' +import ModalWrapper from "../../common/ModalWrapper" +import InfiniteScroll from 'react-infinite-scroller'; +import { ROLE_TEACHER_NUM, ROLE_ASSISTANT_NUM } from '../common' +import NoneData from '../../coursesPublic/NoneData' +import { ConditionToolTip, ThemeContext } from 'educoder' +import SchoolSelect from '../../coursesPublic/form/SchoolSelect' + +const Option = Select.Option; +const pageCount = 15; +class AddStudentModal extends Component{ + constructor(props){ + super(props); + this.state={ + checkBoxValues: [], + users: [], + hasMore: true, + loading: false, + courseGroup: '', + page: 1, + isSpin:false + } + } + fetchMemberList = (arg_page) => { + const courseId = this.props.match.params.coursesId + const page = arg_page || this.state.page; + const { name, school_name } = this.state + let url = `/courses/${courseId}/search_users.json?page=${page}&limit=${pageCount}&school_name=${school_name || ''}&name=${name || ''}` + this.setState({ loading: true }) + axios.get(url) + .then((response) => { + if (!response.data.users || response.data.users.length == 0) { + this.setState({ + users: page == 1 ? response.data.users : this.state.users, + page, + loading: false, + hasMore: false, + }) + } else { + this.setState({ + users: page == 1 ? response.data.users : this.state.users.concat(response.data.users), + page, + loading: false, + hasMore: response.data.users.length == pageCount + }) + } + + }) + .catch(function (error) { + console.log(error); + }); + } + componentDidMount() { + + + } + fetchOptions = () => { + // add_teacher_popup + const courseId = this.props.match.params.coursesId + + let url = `/courses/${courseId}/all_course_groups.json` + + axios.get(url, { + }) + .then((response) => { + if (response.data.course_groups && response.data.course_groups.length) { + this.setState({ + course_groups: response.data.course_groups, + courseGroup: response.data.course_groups[0].id + }) + } else { + // showNotification('') + } + }) + .catch(function (error) { + console.log(error); + }); + } + setVisible = (visible) => { + if (visible) { + this.setState({school_name: this.props.user.user_school}) + this.fetchMemberList() + this.fetchOptions() + } + this.refs.modalWrapper.setVisible(visible) + if (visible == false) { + this.setState({ + checkBoxValues: [] + }) + } + } + + onSendOk = () => { + + if(!this.state.checkBoxValues || this.state.checkBoxValues.length == 0) { + this.props.showNotification('请从列表中先选择用户。') + return; + } + this.setState({ + isSpin:true + }) + const courseId = this.props.match.params.coursesId + const url = `/courses/${courseId}/add_students_by_search.json` + const params = { + "user_ids": this.state.checkBoxValues + } + const { courseGroup } = this.state + if (courseGroup) { + params.course_group_id = courseGroup + } + axios.post(url, params) + .then((response) => { + if (response.data.status == 0) { + this.setVisible(false) + this.props.showNotification('添加成功') + this.props.addStudentSuccess && this.props.addStudentSuccess(params) + this.setState({ + isSpin:false + }) + } + }) + .catch(function (error) { + console.log(error); + }); + } + + onOk = () => { + this.onSendOk() + } + + onCheckBoxChange = (checkBoxValues) => { + this.setState({ + checkBoxValues: checkBoxValues + }) + } + + handleInfiniteOnLoad = () => { + this.fetchMemberList(this.state.page + 1) + } + + onSearch = () => { + this.fetchMemberList(1) + } + handleCourseGroupChange = (value) => { + this.setState({ + courseGroup: value + }) + } + render(){ + const { users, checkBoxValues, loading, hasMore, name, school_name + , courseGroup, course_groups,isSpin } = this.state + const { moduleName } = this.props + let theme = this.context; + return( + + +
    + 姓名: + {this.setState({name: e.target.value})}} + style={{ width: '221px'}} + > + 单位: + {/* {this.setState({school_name: e.target.value})}} + style={{ width: '200px'}}> + */} + {this.setState({school_name: value})}} + > + this.fetchMemberList(1)} + style={{ height: '30px', lineHeight: '30px', marginLeft: '10px', width: '70px'}} + >搜索 +
    + {/* */} + + +

    + + + + + + +

    + + { loading || users.length ?
    + {/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */} +
    + + + + { users.map( candidate => { + return ( +

    + + + 12 }> + + + + + 12 }> + + + + + + +

    + ) + }) } +
    + {loading && hasMore && ( +
    + +
    + )} + +
    +
    + {course_groups && course_groups.length &&
    + 所选学生分班至(选填): + +
    } +
    : } +
    +
    + ) + } +} + +AddStudentModal.contextType = ThemeContext; +export default AddStudentModal; diff --git a/public/react/src/modules/courses/members/modal/AddTeacherModal.js b/public/react/src/modules/courses/members/modal/AddTeacherModal.js index 21902a782..b397f7838 100644 --- a/public/react/src/modules/courses/members/modal/AddTeacherModal.js +++ b/public/react/src/modules/courses/members/modal/AddTeacherModal.js @@ -1,355 +1,355 @@ -import React, { Component } from "react"; -import { Modal, Checkbox, Input, Spin, Select, Divider, Icon } from "antd"; -import axios from 'axios' -import ModalWrapper from "../../common/ModalWrapper" -import InfiniteScroll from 'react-infinite-scroller'; -import { ROLE_TEACHER_NUM, ROLE_ASSISTANT_NUM } from '../common' -import { ConditionToolTip, ActionBtn } from 'educoder' -import NoneData from '../../coursesPublic/NoneData' -import AddGraduationGroupModal from './AddGraduationGroupModal' -import SchoolSelect from '../../coursesPublic/form/SchoolSelect' - -const Option = Select.Option; -const pageCount = 15; -let timeout, currentValue -class AddTeacherModal extends Component{ - constructor(props){ - super(props); - this.state={ - school_names: [], - checkBoxValues: [], - candidates: [], - hasMore: true, - loading: false, - page: 1 - } - } - fetchMemberList = (arg_page) => { - const courseId = this.props.match.params.coursesId - const page = arg_page || this.state.page; - const { name, school_name } = this.state - let url = `/courses/${courseId}/search_teacher_candidate.json` - this.setState({ loading: true }) - axios.post(url, { - page: page, - limit: pageCount, - school_name: school_name || '', - name: name || '' - }) - .then((response) => { - if (!response.data.candidates || response.data.candidates.length == 0) { - this.setState({ - candidates: page == 1 ? response.data.candidates : this.state.candidates, - page, - loading: false, - hasMore: false, - }) - } else { - this.setState({ - candidates: page == 1 ? response.data.candidates : this.state.candidates.concat(response.data.candidates), - page, - loading: false, - hasMore: response.data.candidates.length == pageCount - }) - } - - }) - .catch(function (error) { - console.log(error); - }); - } - componentDidMount() { - - - } - onAddGraduationGroupOk = () => { - this.fetchOptions() - } - fetchOptions = () => { - // add_teacher_popup - const courseId = this.props.match.params.coursesId - - let url = `/courses/${courseId}/add_teacher_popup.json` - - axios.get(url, { - }) - .then((response) => { - - if (response.data.school_name) { - this.setState({ - school_name: response.data.school_name - }, () => this.fetchMemberList()) - } else { - this.fetchMemberList() - - } - if (response.data.graduation_groups) { - this.setState({ - graduation_groups: response.data.graduation_groups - }) - } - if (response.data.course_groups) { - this.setState({ - course_groups: response.data.course_groups - }) - } - - }) - .catch(function (error) { - console.log(error); - }); - } - setVisible = (visible) => { - if (visible) { - this.fetchOptions() - } - this.refs.modalWrapper.setVisible(visible) - if (visible == false) { - this.setState({ - checkBoxValues: [] - }) - } - } - - onSendOk = () => { - const courseId = this.props.match.params.coursesId - const url = `/courses/${courseId}/add_teacher.json` - if (this.state.checkBoxValues.length == 0) { - this.props.showNotification('请先在下面列表中选择要添加教师的成员') - return - } - const params = { - "user_list": this.state.checkBoxValues.map (item => { return { 'user_id': item }}) , - // "graduation_group_id": "2", - // "course_group_id": "820", - "role": this.props.isTeacher ? ROLE_TEACHER_NUM : ROLE_ASSISTANT_NUM - } - const { graduationGroup, courseGroup } = this.state - if (graduationGroup) { - params.graduation_group_id = graduationGroup - } - if (courseGroup) { - params.course_group_id = courseGroup - } - axios.post(url, params) - .then((response) => { - if (response.data.status == 0) { - this.setVisible(false) - this.props.showNotification('添加成功') - this.props.addTeacherSuccess && this.props.addTeacherSuccess(params) - } - }) - .catch(function (error) { - console.log(error); - }); - } - - onOk = () => { - this.onSendOk() - } - - onCheckBoxChange = (checkBoxValues) => { - this.setState({ - checkBoxValues: checkBoxValues - }) - } - - handleInfiniteOnLoad = () => { - this.fetchMemberList(this.state.page + 1) - } - - onSearch = () => { - this.fetchMemberList(1) - } - handleGradationGroupChange = (value) => { - this.setState({ - graduationGroup: value - }) - } - handleCourseGroupChange = (value) => { - this.setState({ - courseGroup: value - }) - } - onOrgNameChange = (value) => { - // console.log('school_name: ', value) - this.setState({ school_name: value }) - } - - hasGraduationModule = () => { - const { course_modules } = this.props; - const result = course_modules && course_modules.filter( item => { - return item.type == 'graduation' - }) - return result && result.length > 0 - } - - render(){ - const { candidates, checkBoxValues, loading, hasMore, name, school_name, school_names - , graduationGroup, graduation_groups, courseGroup, course_groups } = this.state - const { moduleName } = this.props - - return( - - - -
    - 姓名: - {this.setState({name: e.target.value})}} - style={{ width: '200px', marginRight: '18px' }}> - - 单位: - - {/* */} - this.fetchMemberList(1)} - style={{ height: '30px', lineHeight: '30px', marginLeft: '10px', width: '70px'}} - >搜索 -
    - {/* graduation_groups && !!graduation_groups.length */} - - -

    - - - - - - -

    - { loading || candidates.length ?
    - {/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */} -
    - - - - { candidates && candidates.map( candidate => { - return ( -

    - - - {/* "color":"#4c4c4c" */} - 12 }> - - - - - 12 }> - - - - - - -

    - ) - }) } -
    - {loading && hasMore && ( -
    - -
    - )} - -
    -
    -
    : } -
    - { this.hasGraduationModule() &&
    - 添加至答辩组: - -
    } - - { course_groups && !!course_groups.length &&
    - 管理权限: - -
    } -
    -
    - ) - } -} -export default AddTeacherModal; +import React, { Component } from "react"; +import { Modal, Checkbox, Input, Spin, Select, Divider, Icon } from "antd"; +import axios from 'axios' +import ModalWrapper from "../../common/ModalWrapper" +import InfiniteScroll from 'react-infinite-scroller'; +import { ROLE_TEACHER_NUM, ROLE_ASSISTANT_NUM } from '../common' +import { ConditionToolTip, ActionBtn } from 'educoder' +import NoneData from '../../coursesPublic/NoneData' +import AddGraduationGroupModal from './AddGraduationGroupModal' +import SchoolSelect from '../../coursesPublic/form/SchoolSelect' + +const Option = Select.Option; +const pageCount = 15; +let timeout, currentValue +class AddTeacherModal extends Component{ + constructor(props){ + super(props); + this.state={ + school_names: [], + checkBoxValues: [], + candidates: [], + hasMore: true, + loading: false, + page: 1 + } + } + fetchMemberList = (arg_page) => { + const courseId = this.props.match.params.coursesId + const page = arg_page || this.state.page; + const { name, school_name } = this.state + let url = `/courses/${courseId}/search_teacher_candidate.json` + this.setState({ loading: true }) + axios.post(url, { + page: page, + limit: pageCount, + school_name: school_name || '', + name: name || '' + }) + .then((response) => { + if (!response.data.candidates || response.data.candidates.length == 0) { + this.setState({ + candidates: page == 1 ? response.data.candidates : this.state.candidates, + page, + loading: false, + hasMore: false, + }) + } else { + this.setState({ + candidates: page == 1 ? response.data.candidates : this.state.candidates.concat(response.data.candidates), + page, + loading: false, + hasMore: response.data.candidates.length == pageCount + }) + } + + }) + .catch(function (error) { + console.log(error); + }); + } + componentDidMount() { + + + } + onAddGraduationGroupOk = () => { + this.fetchOptions() + } + fetchOptions = () => { + // add_teacher_popup + const courseId = this.props.match.params.coursesId + + let url = `/courses/${courseId}/add_teacher_popup.json` + + axios.get(url, { + }) + .then((response) => { + + if (response.data.school_name) { + this.setState({ + school_name: response.data.school_name + }, () => this.fetchMemberList()) + } else { + this.fetchMemberList() + + } + if (response.data.graduation_groups) { + this.setState({ + graduation_groups: response.data.graduation_groups + }) + } + if (response.data.course_groups) { + this.setState({ + course_groups: response.data.course_groups + }) + } + + }) + .catch(function (error) { + console.log(error); + }); + } + setVisible = (visible) => { + if (visible) { + this.fetchOptions() + } + this.refs.modalWrapper.setVisible(visible) + if (visible == false) { + this.setState({ + checkBoxValues: [] + }) + } + } + + onSendOk = () => { + const courseId = this.props.match.params.coursesId + const url = `/courses/${courseId}/add_teacher.json` + if (this.state.checkBoxValues.length == 0) { + this.props.showNotification('请先在下面列表中选择要添加教师的成员') + return + } + const params = { + "user_list": this.state.checkBoxValues.map (item => { return { 'user_id': item }}) , + // "graduation_group_id": "2", + // "course_group_id": "820", + "role": this.props.isTeacher ? ROLE_TEACHER_NUM : ROLE_ASSISTANT_NUM + } + const { graduationGroup, courseGroup } = this.state + if (graduationGroup) { + params.graduation_group_id = graduationGroup + } + if (courseGroup) { + params.course_group_id = courseGroup + } + axios.post(url, params) + .then((response) => { + if (response.data.status == 0) { + this.setVisible(false) + this.props.showNotification('添加成功') + this.props.addTeacherSuccess && this.props.addTeacherSuccess(params) + } + }) + .catch(function (error) { + console.log(error); + }); + } + + onOk = () => { + this.onSendOk() + } + + onCheckBoxChange = (checkBoxValues) => { + this.setState({ + checkBoxValues: checkBoxValues + }) + } + + handleInfiniteOnLoad = () => { + this.fetchMemberList(this.state.page + 1) + } + + onSearch = () => { + this.fetchMemberList(1) + } + handleGradationGroupChange = (value) => { + this.setState({ + graduationGroup: value + }) + } + handleCourseGroupChange = (value) => { + this.setState({ + courseGroup: value + }) + } + onOrgNameChange = (value) => { + // console.log('school_name: ', value) + this.setState({ school_name: value }) + } + + hasGraduationModule = () => { + const { course_modules } = this.props; + const result = course_modules && course_modules.filter( item => { + return item.type == 'graduation' + }) + return result && result.length > 0 + } + + render(){ + const { candidates, checkBoxValues, loading, hasMore, name, school_name, school_names + , graduationGroup, graduation_groups, courseGroup, course_groups } = this.state + const { moduleName } = this.props + + return( + + + +
    + 姓名: + {this.setState({name: e.target.value})}} + style={{ width: '200px', marginRight: '18px' }}> + + 单位: + + {/* */} + this.fetchMemberList(1)} + style={{ height: '30px', lineHeight: '30px', marginLeft: '10px', width: '70px'}} + >搜索 +
    + {/* graduation_groups && !!graduation_groups.length */} + + +

    + + + + + + +

    + { loading || candidates.length ?
    + {/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */} +
    + + + + { candidates && candidates.map( candidate => { + return ( +

    + + + {/* "color":"#4c4c4c" */} + 12 }> + + + + + 12 }> + + + + + + +

    + ) + }) } +
    + {loading && hasMore && ( +
    + +
    + )} + +
    +
    +
    : } +
    + { this.hasGraduationModule() &&
    + 添加至答辩组: + +
    } + + { course_groups && !!course_groups.length &&
    + 管理权限: + +
    } +
    +
    + ) + } +} +export default AddTeacherModal; diff --git a/public/react/src/modules/courses/members/modal/CreateGroupByImportModal.js b/public/react/src/modules/courses/members/modal/CreateGroupByImportModal.js index 54c0df912..d5e77da9d 100644 --- a/public/react/src/modules/courses/members/modal/CreateGroupByImportModal.js +++ b/public/react/src/modules/courses/members/modal/CreateGroupByImportModal.js @@ -13,12 +13,15 @@ class CreateGroupByImportModal extends Component{ constructor(props){ super(props); this.state={ - errorTip:undefined } } - + fetchMemberList = (arg_page) => { + } + componentDidMount() { + + + } onSendOk = () => { - const courseId = this.props.match.params.coursesId let url = `/courses/${courseId}/create_group_by_importing_file.json` @@ -109,7 +112,7 @@ class CreateGroupByImportModal extends Component{ render(){ const { candidates, checkBoxValues, loading, hasMore, name, school_name, school_names - , graduationGroup, graduation_groups, courseGroup, course_groups , fileList , errorTip } = this.state + , graduationGroup, graduation_groups, courseGroup, course_groups , fileList } = this.state const { moduleName } = this.props const props = { @@ -129,18 +132,15 @@ class CreateGroupByImportModal extends Component{ onOk={this.onOk} className="createGroupByImport" > - -

    - -

    -

    点击或拖拽文件到这里上传

    -

    - 单个文件最大150MB -

    -
    -

    - {errorTip} -

    + +

    + +

    +

    点击或拖拽文件到这里上传

    +

    + 单个文件最大150MB +

    +
    ) } diff --git a/public/react/src/modules/courses/members/studentsList.js b/public/react/src/modules/courses/members/studentsList.js index 2a510789e..cc7485101 100644 --- a/public/react/src/modules/courses/members/studentsList.js +++ b/public/react/src/modules/courses/members/studentsList.js @@ -35,6 +35,7 @@ const buildColumns = (that) => { dataIndex: 'login', key: 'login', align:'center', + width:"10%", className:"color-grey-6", render: (login, record) => { return { dataIndex: 'student_id', key: 'student_id', align:'center', + width:"10%", className:"color-grey-6", render: (student_id, record) => { - return 10 ? student_id : ''} + return 10 ? student_id : ''} style={{maxWidth: '160px'}} >{student_id} } }]; @@ -69,7 +71,7 @@ const buildColumns = (that) => { dataIndex: 'course_group_name', key: 'course_group_name', align:'center', - width:"50%", + width:"40%", className:"color-grey-6" }) } diff --git a/public/react/src/modules/courses/new/CoursesNew.js b/public/react/src/modules/courses/new/CoursesNew.js index 46380d85b..edee26a27 100644 --- a/public/react/src/modules/courses/new/CoursesNew.js +++ b/public/react/src/modules/courses/new/CoursesNew.js @@ -81,22 +81,19 @@ class CoursesNew extends Component { is_public: data.is_public === 1 ? true : false, Realnamecertification: data.authentication, Professionalcertification:data.professional_certification, - checkbofrups:data.course_modules, + // checkbofrups:data.course_modules, }); - try { - if(data.course_modules===undefined||data.course_modules.length===0){ - this.setState({ - checkbofrups:this.state.checkbofrup, - }); - } - }catch (e) { - this.setState({ - checkbofrups:this.state.checkbofrup, - }); - } - - - + // try { + // if(data.course_modules===undefined||data.course_modules.length===0){ + // this.setState({ + // checkbofrups:this.state.checkbofrup, + // }); + // } + // }catch (e) { + // this.setState({ + // checkbofrups:this.state.checkbofrup, + // }); + // } this.handleSearchschool(data.school); }).catch((error) => { console.log(error); @@ -464,7 +461,7 @@ class CoursesNew extends Component { this.applyForAddOrgForm.setVisible(true) } render() { - let {datatime,school,searchlistscholl,checkbofrups} = this.state; + let {datatime,school,searchlistscholl} = this.state; const {getFieldDecorator} = this.props.form; const propsWithoutForm = Object.assign({}, this.props) delete propsWithoutForm.form @@ -705,17 +702,6 @@ class CoursesNew extends Component { "shixun_homework", "common_homework", "group_homework", "exercise", "attachment", "course_group", ], })( - this.props.match.params.coursesId != undefined? - - { - checkbofrups===undefined?"":checkbofrups.length===0?"":checkbofrups.map((item,key)=>{ - return( - {item.module_name} - ) - }) - } - - : 实训作业 普通作业 diff --git a/public/react/src/modules/courses/new/Goldsubject.js b/public/react/src/modules/courses/new/Goldsubject.js index a51e535e9..80530c7ed 100644 --- a/public/react/src/modules/courses/new/Goldsubject.js +++ b/public/react/src/modules/courses/new/Goldsubject.js @@ -144,20 +144,18 @@ class Goldsubject extends Component { course_module_types: data.course_module_types, school:data.school, Whethertocreateanewclassroom:false, - checkbofrups:data.course_modules, }); - - try { - if(data.course_modules===undefined||data.course_modules.length===0){ - this.setState({ - checkbofrups:this.state.checkbofrup, - }); - } - }catch (e) { - this.setState({ - checkbofrups:this.state.checkbofrup, - }); - } + // try { + // if(data.course_modules===undefined||data.course_modules.length===0){ + // this.setState({ + // checkbofrups:this.state.checkbofrup, + // }); + // } + // }catch (e) { + // this.setState({ + // checkbofrups:this.state.checkbofrup, + // }); + // } this.handleSearchschool(data.school); }).catch((error) => { console.log(error); @@ -609,7 +607,7 @@ class Goldsubject extends Component { this.applyForAddOrgForm.setVisible(true) } render() { - let {datatime,datatimetwo,school,searchlistscholl,Whethertocreateanewclassroom,checkbofrups} = this.state; + let {datatime,datatimetwo,school,searchlistscholl,Whethertocreateanewclassroom} = this.state; const {getFieldDecorator} = this.props.form; const propsWithoutForm = Object.assign({}, this.props) delete propsWithoutForm.form @@ -884,25 +882,6 @@ class Goldsubject extends Component { "announcement","online_learning","shixun_homework","common_homework", ], })( - this.props.match.params.coursesId != undefined? - - { - checkbofrups===undefined?"":checkbofrups.length===0?"":checkbofrups.map((item,key)=>{ - return( - item.module_type==="announcement"? - 公告栏 - : - item.module_type==="online_learning"? - 在线学习 - : - item.module_type==="graduation"?"": - item.module_type==="group_homework"?"": - {item.module_name} - ) - }) - } - - : 公告栏 在线学习 diff --git a/public/react/src/modules/courses/poll/Poll.js b/public/react/src/modules/courses/poll/Poll.js index 07be2196c..a01c142a4 100644 --- a/public/react/src/modules/courses/poll/Poll.js +++ b/public/react/src/modules/courses/poll/Poll.js @@ -288,6 +288,7 @@ class Poll extends Component{ }) let{type,StudentList_value}=this.state this.InitList(type,StudentList_value,1); + this.props.updataleftNavfun(); } }).catch((error)=>{ console.log(error); @@ -595,7 +596,8 @@ class Poll extends Component{ {...this.state} courseType={course_types} item={item} - key={key} + index={key} + onItemClick={this.onItemClick} checkBox={ this.onItemClick(item)}>} > ) diff --git a/public/react/src/modules/courses/poll/PollListItem.js b/public/react/src/modules/courses/poll/PollListItem.js index 50c471e76..6f081b952 100644 --- a/public/react/src/modules/courses/poll/PollListItem.js +++ b/public/react/src/modules/courses/poll/PollListItem.js @@ -16,7 +16,7 @@ class PollListItem extends Component{ super(props); } render(){ - let{item,checkBox,courseType}=this.props; + let{item,checkBox,courseType,index}=this.props; let {coursesId}=this.props.match.params; const IsAdmin =this.props.isAdmin(); @@ -28,10 +28,10 @@ class PollListItem extends Component{ let canNotLink = !isAdminOrStudent && item.lock_status == 0 return( -
    +
    window.$(`.pollitem${index} input`).click() }> { IsAdmin && - + {checkBox} } diff --git a/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js b/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js index 38ab63a4f..942c06800 100644 --- a/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js +++ b/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js @@ -124,13 +124,19 @@ class ShixunhomeWorkItem extends Component{ }) } - editname = (name,id) => { + // 实训详情,阻止冒泡 + stopPro = (event) => { + event.stopPropagation() + } + + editname = (name,id,event) => { this.setState({ ModalsRenametype:true, NavmodalValue:name, Navmodalname:"重命名", url:`/homework_commons/${id}/alter_name.json` }) + event.stopPropagation() } cannerNavmoda=()=>{ this.setState({ @@ -157,88 +163,74 @@ class ShixunhomeWorkItem extends Component{ const { checkBox, discussMessage, - taskid, + taskid,index } = this.props; - // - - // allow_late: true //是否开启补交 - - // homework_id: 9250 - - // shixun_identifier: "25ykhpvl" - - // - // console.log("this.props.isAdmin"); - - return( -
    - {this.state.ModalsRenametype===true? - this.cannerNavmoda()} - /> - :""} - - - - {visible===true?:""} - - - -
    -

    实训已经更新了,正在为您重置!

    -
    - -
    - -
    -

    本实训的开启时间:{shixunsmessage}
    开启时间之前不能挑战 -

    -
    -
    - {/*取消*/} - 知道啦 -
    - {/*

    */} - {/*知道了*/} - {/*

    */} -
    - + + { + this.state.ModalsRenametype===true? + this.cannerNavmoda()} + /> + :""} + + {visible===true?:""} + +
    +

    实训已经更新了,正在为您重置!

    +
    + +
    + + +
    +

    本实训的开启时间:{shixunsmessage}
    开启时间之前不能挑战 +

    +
    +
    + {/*取消*/} + 知道啦 +
    + {/*

    */} + {/*知道了*/} + {/*

    */} +
    +
    window.$(`.shixunitem${index} input`).click() } > - {this.props.isAdmin?checkBox:""} + {this.props.isAdmin? + {checkBox} + : + "" + }
    - {this.props.isAdmin?
    - 实训详情 - {this.props.isAdminOrCreator()?this.editname(discussMessage.name,discussMessage.homework_id)} className={"btn colorblue ml20 font-16"}>重命名:""} + {this.props.isAdmin?
    this.stopPro(event)} className={this.props.isAdminOrCreator()?"homepagePostSetting homepagePostSettingname":"homepagePostSetting homepagePostSettingbox"} style={{"right":"-2px","top":"44px","display":"block"}}> + 实训详情 + {this.props.isAdminOrCreator()?this.editname(discussMessage.name,discussMessage.homework_id,event)} className={"btn colorblue ml20 font-16"}>重命名:""} {/* 设置*/} 设置
    :""} @@ -408,6 +404,7 @@ class ShixunhomeWorkItem extends Component{
    + ) } } diff --git a/public/react/src/modules/courses/shixunHomework/shixunHomework.js b/public/react/src/modules/courses/shixunHomework/shixunHomework.js index 74d142129..c7fa2e70a 100644 --- a/public/react/src/modules/courses/shixunHomework/shixunHomework.js +++ b/public/react/src/modules/courses/shixunHomework/shixunHomework.js @@ -587,6 +587,8 @@ class ShixunHomework extends Component{ let {Coursename,page}=this.state; this.setState({ order: e.key, + checkBoxValues:[], + checkedtype:false, isSpin:true }); let newkey=e.key; @@ -655,6 +657,7 @@ class ShixunHomework extends Component{ } + savedelete=()=>{ let {Coursename,page,order,checkBoxValues,datas}=this.state; let category_id=this.props.match.params.category_id; @@ -966,7 +969,7 @@ class ShixunHomework extends Component{ category_id={this.props.match.params.category_id} visible={shixunmodal} shixunmodallist={shixunmodallist} - // funshixunmodallist={(search,type,loading,page)=>this.funshixunmodallist(search,type,loading,page)} + homeworkupdatalists={(Coursename,page,order)=>this.homeworkupdatalist(Coursename,page,order)} hometypepvisible={hometypepvisible} hidecouseShixunModal={this.hidecouseShixunModal} newshixunmodallist={newshixunmodallist} @@ -1019,8 +1022,8 @@ class ShixunHomework extends Component{

    - {datas&&datas.category_name===undefined||datas&&datas.category_name===null?datas&&datas.main_category_name:datas&&datas.category_name+" 作业列表"} - {/* 实训作业*/} + {/*{datas&&datas.category_name===undefined||datas&&datas.category_name===null?datas&&datas.main_category_name:datas&&datas.category_name+" 作业列表"}*/} + 实训作业

  • {this.props.isAdmin()===true?datas&&datas.category_name===undefined||datas&&datas.category_name===null? @@ -1035,7 +1038,7 @@ class ShixunHomework extends Component{

    -

    +

    共 {datas&&datas.all_count}个实训作业 已发布:{datas&&datas.published_count}个 @@ -1062,7 +1065,9 @@ class ShixunHomework extends Component{
    - {this.props.isAdmin()===true?
    + {this.props.isAdmin()===true? + datas===undefined?'' :datas.homeworks.length===0?"": +
    已选 {checkBoxValues&&checkBoxValues.length} 个 @@ -1152,7 +1157,7 @@ class ShixunHomework extends Component{ // console.log("++++++++++++++++++++++++++++++++++++++++++") // console.log(JSON.stringify(this.props)) return ( -
    +
    :""} match={this.props.match} + index={index} coursedata={this.props.coursedata} coursupdata={()=>this.homeworkupdatalist(Coursename,page,order)} course_identity={datas.course_identity} @@ -1203,18 +1209,10 @@ class ShixunHomework extends Component{
    + { + datas===undefined?'' :datas.homeworks.length===0? :"" + } -
    -
    -

    暂时还没有相关数据哦!

    -
    @@ -1223,3 +1221,14 @@ class ShixunHomework extends Component{ } } export default ShixunHomework; +// {/*
    */} +// {/*
    */} +// {/**/} +// {/*

    暂时还没有相关数据哦!

    */} +// {/*
    */} \ No newline at end of file diff --git a/public/react/src/modules/page/MainContentContainer.js b/public/react/src/modules/page/MainContentContainer.js index 3214fe5d5..f50ec9d21 100644 --- a/public/react/src/modules/page/MainContentContainer.js +++ b/public/react/src/modules/page/MainContentContainer.js @@ -224,12 +224,15 @@ class MainContentContainer extends Component { } componentDidUpdate(prevProps, prevState, snapshot) { - const { game } = this.props + const { game, challenge } = this.props if (game && prevProps.game && prevProps.game.identifier !== game.identifier) { // 切换关卡时,停止轮训 this.oldGameIdentifier = prevProps.game.identifier; + this.doFileUpdateRequestOnCodeMirrorBlur(prevProps) + } else if (challenge && (challenge.pathIndex || prevProps.challenge.pathIndex) && challenge.pathIndex != prevProps.challenge.pathIndex) { + this.doFileUpdateRequestOnCodeMirrorBlur(prevProps) } } @@ -386,8 +389,8 @@ class MainContentContainer extends Component { } - doFileUpdateRequestOnCodeMirrorBlur = () => { - var fileUpdatePromise = this.doFileUpdateRequest(true) + doFileUpdateRequestOnCodeMirrorBlur = (props) => { + var fileUpdatePromise = this.doFileUpdateRequest(true, undefined, props) if (fileUpdatePromise) { fileUpdatePromise.then((resData) => { if (resData.status === -1) { // 保存文件出现异常 @@ -496,7 +499,8 @@ class MainContentContainer extends Component { } // forTest true 是评测时触发的file_update - doFileUpdateRequest(checkIfCodeChanged, forTest) { + doFileUpdateRequest(checkIfCodeChanged, forTest, props) { + const _props = props || this.props; const { codeStatus } = this.state; if (!forTest && codeStatus !== UPDATED) { // 已修改状态才能保存 return; @@ -521,7 +525,7 @@ class MainContentContainer extends Component { }) return null; } - const { challenge, output_sets, onRunCodeTestFinish, myshixun } = this.props + const { challenge, output_sets, onRunCodeTestFinish, myshixun } = _props // var url = `${locationPath}/file_update?path=${encodeURIComponent(challenge.path)}` var url = `/myshixuns/${myshixun.identifier}/update_file.json` diff --git a/public/react/src/modules/page/layers/ImageLayerOfCommentHOC.js b/public/react/src/modules/page/layers/ImageLayerOfCommentHOC.js index 50072c627..d19aa03ec 100644 --- a/public/react/src/modules/page/layers/ImageLayerOfCommentHOC.js +++ b/public/react/src/modules/page/layers/ImageLayerOfCommentHOC.js @@ -37,6 +37,8 @@ export function ImageLayerOfCommentHOC(options = {}) { } // jQuery._data( $('.newMain')[0], "events" ) componentDidMount() { + this.props.wrappedComponentRef && this.props.wrappedComponentRef(this.refs['wrappedComponentRef']) + // commentsDelegateParent #game_left_contents #tab_con_4 setTimeout(() => { $(options.parentSelector || ".commentsDelegateParent") @@ -60,7 +62,7 @@ export function ImageLayerOfCommentHOC(options = {}) { - + ) diff --git a/public/react/src/modules/page/main/ActionView.js b/public/react/src/modules/page/main/ActionView.js index 1a887fa75..4933ba0ac 100644 --- a/public/react/src/modules/page/main/ActionView.js +++ b/public/react/src/modules/page/main/ActionView.js @@ -52,11 +52,18 @@ class ActionView extends Component { componentDidMount() { // request window._tpiWidthResize = () => { - if (window.$('#actionView').width() < 580) { - window.$('.time_limit').hide() - } else { - window.$('.time_limit').show() - } + const _w = window.$('#actionView').width(); + // if (_w < 446) { + // window.$('#time-consuming').hide() + // // window.$('#time-consuming').hide() + // } else if (_w < 746) { + // // 文字放出来之前是 580 + // window.$('#time-consuming').show() + // window.$('.time_limit').hide() + // } else { + // window.$('#time-consuming').show() + // window.$('.time_limit').show() + // } } } @@ -70,24 +77,50 @@ class ActionView extends Component { return (
    {!!time_limit && - {`本关最大执行时间:${real_time_limit}秒`}} + {`本关最大执行时间:${real_time_limit}秒`} + {!gameBuilding && record && } + } {!gameBuilding && record ? - - { record } 秒 - + // + 本次评测耗时(编译、运行总时间):{ record } 秒 + : ""} {/*将第一个按钮改为visibility方式隐藏,不然加载时测评按钮会出现没有垂直居中的情况*/} @@ -108,7 +141,7 @@ class ActionView extends Component { {/*未发布的都能跳转*/} { !gameBuilding && ((game && (game.status === 2 || shixun.status < 2) || shixun && shixun.task_pass ) && !!game.next_game) ? - + @@ -117,11 +150,11 @@ class ActionView extends Component { -
    +
    { st === 1 && game.status === 2 ? - 测评 @@ -130,7 +163,7 @@ class ActionView extends Component { : gameBuilding ? - 测评 diff --git a/public/react/src/modules/page/tpiPageForMobile.css b/public/react/src/modules/page/tpiPageForMobile.css index c30f40636..a2d903823 100644 --- a/public/react/src/modules/page/tpiPageForMobile.css +++ b/public/react/src/modules/page/tpiPageForMobile.css @@ -14,13 +14,16 @@ min-width: 280px; } - #time-consuming .time_limit { - display: none; - } + .actionViewfirstButton { display: none !important; } } +@media (max-width: 800px) { + #time-consuming .time_limit { + display: none; + } +} @media (max-width: 628px) { .-header-right { display: none } .exitBtn span { display: none } diff --git a/public/react/src/modules/paths/PathDetail/DetailCardsEditAndAdd.js b/public/react/src/modules/paths/PathDetail/DetailCardsEditAndAdd.js index e9770e969..9f4d49a04 100644 --- a/public/react/src/modules/paths/PathDetail/DetailCardsEditAndAdd.js +++ b/public/react/src/modules/paths/PathDetail/DetailCardsEditAndAdd.js @@ -297,43 +297,49 @@ class DetailCardsEditAndAdd extends Component{ contentViewScrolladd=(e)=>{ + const {ChooseShixunList}=this.state; //滑动到底判断 if(e.currentTarget.scrollHeight-e.currentTarget.scrollTop===e.currentTarget.clientHeight){ - // console.log("到达底部"); - this.setState({ - hometypepvisible:true - }) - let pathId=this.props.pathid; - let {search,page,type,ChooseShixunListshixun_list}=this.state; - let newpage=page+1; - let newChooseShixunListshixun_list=ChooseShixunListshixun_list; - let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+newpage - if(search!="" && search!=undefined){ - url+="&search="+search; - } - if(type!=0){ - url+="&type="+type; - } - axios.get(url).then((result)=>{ - if(result.status===200){ - let list =result.data.shixun_list; - - for(var i=0; i{ - console.log(error); - }) + if(ChooseShixunList.shixun_list.length===0){ + return + }else{ + // console.log("到达底部"); + this.setState({ + hometypepvisible:true + }) + let pathId=this.props.pathid; + let {search,page,type,ChooseShixunListshixun_list}=this.state; + let newpage=page+1; + let newChooseShixunListshixun_list=ChooseShixunListshixun_list; + let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+newpage + if(search!="" && search!=undefined){ + url+="&search="+search; + } + if(type!=0){ + url+="&type="+type; + } + axios.get(url).then((result)=>{ + if(result.status===200){ + let list =result.data.shixun_list; + + for(var i=0; i{ + console.log(error); + }) + + } } diff --git a/public/react/src/modules/paths/PathDetail/DetailCardsEditAndEdit.js b/public/react/src/modules/paths/PathDetail/DetailCardsEditAndEdit.js index 719994fdf..b6c7e53b2 100644 --- a/public/react/src/modules/paths/PathDetail/DetailCardsEditAndEdit.js +++ b/public/react/src/modules/paths/PathDetail/DetailCardsEditAndEdit.js @@ -338,50 +338,59 @@ class DetailCardsEditAndEdit extends Component{ contentViewScrolledit=(e)=>{ //滑动到底判断 - + const {ChooseShixunList}=this.state; if(e.currentTarget.scrollHeight-e.currentTarget.scrollTop===e.currentTarget.clientHeight){ - this.setState({ - hometypepvisible:true - }) - // console.log("到达底部"); - let {page,type,search,ChooseShixunListshixun_list}=this.state; + if(ChooseShixunList.shixun_list.length===0){ + return + }else{ + this.setState({ + hometypepvisible:true + }) + // console.log("到达底部"); - let newpage=page+1; + let {page,type,search,ChooseShixunListshixun_list}=this.state; - let pathId=this.props.pathid; + let newpage=page+1; - let newChooseShixunListshixun_list=ChooseShixunListshixun_list; + let pathId=this.props.pathid; - let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+newpage + let newChooseShixunListshixun_list=ChooseShixunListshixun_list; - if(search!="" && search!=undefined){ - url+="&search="+search; - } + let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+newpage - if(type!=0){ - url+="&type="+type; - } - axios.get(url).then((result)=>{ - if(result.status===200){ + if(search!="" && search!=undefined){ + url+="&search="+search; + } + + if(type!=0){ + url+="&type="+type; + } + axios.get(url).then((result)=>{ + if(result.status===200){ + + let list =result.data.shixun_list; + + for(var i=0; i{ + console.log(error); + }) + + + } - let list =result.data.shixun_list; - for(var i=0; i{ - console.log(error); - }) } diff --git a/public/react/src/modules/paths/PathDetail/addCollaborators.js b/public/react/src/modules/paths/PathDetail/addCollaborators.js index 0b99fd467..056e69b31 100644 --- a/public/react/src/modules/paths/PathDetail/addCollaborators.js +++ b/public/react/src/modules/paths/PathDetail/addCollaborators.js @@ -14,7 +14,8 @@ class addCollaborators extends Component{ search:'', partnerListid:[], checkAll: false, - optionss:[] + optionss:[], + useristrue:false } } addBox=()=>{ @@ -70,6 +71,13 @@ class addCollaborators extends Component{ let {partnerListid} =this.state; let id=this.props.match.params.pathId; let url="/paths/"+id+"/add_subject_members.json" + + if(partnerListid.length===0){ + this.setState({ + useristrue:true + }) + return + } axios.post(url,{ user_ids:partnerListid }).then((response) => { @@ -87,9 +95,17 @@ class addCollaborators extends Component{ } addCollaboratorsid=(id)=>{ - this.setState({ - partnerListid:id - }) + if(id.length===0){ + this.setState({ + partnerListid:id, + }) + }else{ + this.setState({ + partnerListid:id, + useristrue:false + }) + } + } onCheckAllChange = (e) => { @@ -145,7 +161,7 @@ class addCollaborators extends Component{ } render(){ - let {addPartner,search,partnerList,optionss,checkAll,partnerListid} = this.state; + let {addPartner,search,partnerList,optionss,checkAll,partnerListid,useristrue} = this.state; return( this.props.detailInfoList===undefined?"":this.props.detailInfoList.allow_add_member===true? @@ -199,6 +215,7 @@ class addCollaborators extends Component{ } + {useristrue===true?请先选择用户:""}
    取消 确定 diff --git a/public/react/src/modules/tpm/SiderBar.js b/public/react/src/modules/tpm/SiderBar.js index beab18fdc..7cee11cf2 100644 --- a/public/react/src/modules/tpm/SiderBar.js +++ b/public/react/src/modules/tpm/SiderBar.js @@ -115,7 +115,7 @@ class SiderBar extends Component { ` } - +

    微信扫一扫

    关注公众号

    diff --git a/public/react/src/modules/tpm/challengesnew/TPMevaluation.js b/public/react/src/modules/tpm/challengesnew/TPMevaluation.js index 985a838fb..60161d829 100644 --- a/public/react/src/modules/tpm/challengesnew/TPMevaluation.js +++ b/public/react/src/modules/tpm/challengesnew/TPMevaluation.js @@ -475,7 +475,10 @@ export default class TPMevaluation extends Component { } handpathoptionvalue=(value)=>{ this.setState({ - pathoptionvalue:value + pathoptionvalue:value, + shixunfileexpectpicturepath:undefined, + shixunfilestandardpicturepath:undefined, + shixunfilepicturepath:undefined }) } showrepositoryurltip=(type)=>{ @@ -640,19 +643,20 @@ export default class TPMevaluation extends Component { let id = this.props.match.params.shixunId; let{checkpointId}=this.state; let url = "/shixuns/"+id+"/challenges/"+checkpointId+".json"; + let newchallenge={ + path:shixunfilepath, + exec_path:shixunfilepathplay, + show_type:pathoptionvalue, + original_picture_path:pathoptionvalue===-1?undefined:shixunfileexpectpicturepath===undefined?null:shixunfileexpectpicturepath, + expect_picture_path:pathoptionvalue===-1?undefined:shixunfilestandardpicturepath===undefined?null:shixunfilestandardpicturepath, + picture_path:pathoptionvalue===-1?undefined:shixunfilepicturepath===undefined?null:shixunfilepicturepath, + test_set_score:newscorevalue, + test_set_average:markvalue, + web_route:web_route===null?undefined:web_route + } axios.put(url,{ tab:1, - challenge:{ - path:shixunfilepath, - exec_path:shixunfilepathplay, - show_type:pathoptionvalue, - original_picture_path:shixunfileexpectpicturepath, - expect_picture_path:shixunfilestandardpicturepath, - picture_path:shixunfilepicturepath, - test_set_score:newscorevalue, - test_set_average:markvalue, - web_route:web_route===null?undefined:web_route - }, + challenge:newchallenge, test_set:evaluationlist } ).then((response) => { diff --git a/public/react/src/modules/tpm/shixunchild/Collaborators/Collaborators.js b/public/react/src/modules/tpm/shixunchild/Collaborators/Collaborators.js index 1662635ba..ea99b740d 100644 --- a/public/react/src/modules/tpm/shixunchild/Collaborators/Collaborators.js +++ b/public/react/src/modules/tpm/shixunchild/Collaborators/Collaborators.js @@ -45,7 +45,8 @@ class Collaborators extends Component { collaboratorListsumtype:true, user_name:undefined, school_name:undefined, - spinnings:false + spinnings:false, + useristrue:false } } componentDidMount() { @@ -217,10 +218,20 @@ class Collaborators extends Component { } else { alltype = false } - this.setState({ - Searchadmin: newlist, - allChangechecked: alltype - }) + + if(newlist.length===0){ + this.setState({ + Searchadmin: newlist, + allChangechecked: alltype, + }) + }else{ + this.setState({ + Searchadmin: newlist, + allChangechecked: alltype, + useristrue:false + }) + } + } allChange = (e) => { @@ -260,6 +271,13 @@ class Collaborators extends Component { } } } + + if(user_ids.length===0){ + this.setState({ + useristrue:true + }) + return + } let url = "/shixuns/" + id + "/shixun_members_added.json"; axios.post(url, { user_ids: user_ids @@ -405,7 +423,8 @@ class Collaborators extends Component { collaboratorListsum, collaboratorListsumtype, user_name, - school_name + school_name, + useristrue } = this.state; let {loadingContent} = this.props; const radioStyle = { @@ -547,7 +566,7 @@ class Collaborators extends Component {
    - + {useristrue===true?请先选择用户:""}
    this.CollaboratorsshowModal("cooperation")}>取消 diff --git a/public/react/src/modules/tpm/shixuns/shixunCss/shixunCard.css b/public/react/src/modules/tpm/shixuns/shixunCss/shixunCard.css index f3c4a30da..4470aaec1 100644 --- a/public/react/src/modules/tpm/shixuns/shixunCss/shixunCard.css +++ b/public/react/src/modules/tpm/shixuns/shixunCss/shixunCard.css @@ -1,45 +1,45 @@ -.ml350 { - margin-left: 40%; -} - -.ml32 { - margin-left: 32%; -} - -.square-Item{ - /*min-height: 324px;*/ -} -.square-img{ - min-height: 210px; -} -.task-hide{ - margin-bottom: 0em; -} -.backFAFAFA{ - background:#FAFAFA; -} - -.demo { - width: 500px; - background-color: #0dcecb; - text-align: center; - padding:50px; -} -.next-loading { - margin-bottom: 5px; - width:100%; -} - -.next-rating-overlay .next-icon{ - color: #FFA800!important; -} - -.custom-pagination { - display: inline-block; - margin-left: 10px; -} - -.ml425{ - margin-left:42.5%; - margin-top:20px; +.ml350 { + margin-left: 40%; +} + +.ml32 { + margin-left: 32%; +} + +.square-Item{ + /*min-height: 324px;*/ +} +.square-img{ + min-height: 210px; +} +.task-hide{ + margin-bottom: 0em; +} +.backFAFAFA{ + background:#FAFAFA; +} + +.demo { + width: 500px; + background-color: #0dcecb; + text-align: center; + padding:50px; +} +.next-loading { + margin-bottom: 5px; + width:100%; +} + +.next-rating-overlay .next-icon{ + color: #FFA800!important; +} + +.custom-pagination { + display: inline-block; + margin-left: 10px; +} + +.ml425{ + margin-left:42.5%; + margin-top:20px; } \ No newline at end of file diff --git a/public/react/src/modules/user/usersInfo/InfosBank.js b/public/react/src/modules/user/usersInfo/InfosBank.js index 8adc7ba50..2abc15220 100644 --- a/public/react/src/modules/user/usersInfo/InfosBank.js +++ b/public/react/src/modules/user/usersInfo/InfosBank.js @@ -1,249 +1,249 @@ -import React, { Component } from 'react'; -import {Pagination,Spin,Checkbox,Modal} from 'antd'; -import moment from 'moment'; -import axios from 'axios'; -import NoneData from '../../courses/coursesPublic/NoneData' -import {getImageUrl} from 'educoder'; -import "./usersInfo.css" -import Modals from '../../modals/Modals' - -const dateFormat ="YYYY-MM-DD HH:mm" -class InfosBank extends Component{ - constructor(props){ - super(props); - this.state={ - category:"common", - type:"publicly", - page:1, - per_page:16, - sort_by:"updated_at", - CoursesId:undefined, - - totalCount:undefined, - data:undefined, - isSpin:false, - - dialogOpen:false, - modalsTopval:undefined, - modalsBottomval:undefined, - modalSave:undefined - } - } - - componentDidMount=()=>{ - this.setState({ - isSpin:true - }) - let{category,type,page,sort_by,CoursesId}=this.state; - this.getCourses(category,type,page,sort_by,CoursesId); - } - - getCourses=(category,type,page,sort_by,CoursesId)=>{ - let url=`/users/${this.props.match.params.username}/question_banks.json`; - axios.get((url),{params:{ - category, - type, - page, - sort_by, - per_page:category && page ==1?17:16, - course_list_id:CoursesId - }}).then((result)=>{ - if(result){ - this.setState({ - totalCount:result.data.count, - data:result.data, - isSpin:false - }) - } - }).catch((error)=>{ - console.log(error); - }) - } - - //切换种类 - changeCategory=(cate)=>{ - this.setState({ - category:cate, - page:1, - isSpin:true - }) - let{type,sort_by,CoursesId}=this.state; - this.getCourses(cate,type,1,sort_by,CoursesId); - } - //切换状态 - changeType=(type)=>{ - this.setState({ - type:type, - page:1, - isSpin:true - }) - let{category,sort_by,CoursesId}=this.state; - this.getCourses(category,type,1,sort_by,CoursesId); - } - //切换页数 - changePage=(page)=>{ - this.setState({ - page, - isSpin:true - }) - let{category,type,sort_by,CoursesId}=this.state; - this.getCourses(category,type,page,sort_by,CoursesId); - } - - // 进入课堂 - turnToCourses=(url)=>{ - this.props.history.push(url); - } - - // 切换排序方式 - changeOrder= (sort)=>{ - this.setState({ - sort_by:sort, - isSpin:true - }) - let{category,type,page,CoursesId}=this.state; - this.getCourses(category,type,page,sort,CoursesId); - } - - changeCourseListId =(CoursesId)=>{ - this.setState({ - CoursesId, - isSpin:true - }) - let{category,type,sort,page}=this.state; - this.getCourses(category,type,page,sort,CoursesId); - } - - //设为公开/删除 - setPublic=(index)=>{ - this.setState({ - dialogOpen:true, - modalsTopval:index==1?"您确定要公开吗?":"确定要删除该题吗?", - modalsBottomval:index==1?"公开后不能重设为私有":"", - modalSave:()=>this.sureOperation(index) - }) - } - // 确定--设为公开/删除 - sureOperation=()=>{ - - } - - //弹框隐藏 - handleDialogClose=()=>{ - this.setState({ - dialogOpen:false - }) - } - - render(){ - let{ - category, - type, - page, - data, - totalCount, - sort_by, - isSpin, - CoursesId, - dialogOpen, - modalsTopval, - modalsBottomval,modalSave - } = this.state; - let isStudent = this.props.isStudent(); - let is_current=this.props.is_current; - return( -
    - - -
    -
  • this.changeType("publicly")}>{is_current ? "我":"TA"}的题库
  • -
  • this.changeType("personal")}>公共题库
  • -
    -
    - -
    -
      -
    • this.changeCourseListId()}> - 全部 -
    • - { - data && data.course_list && data.course_list.map((item,key)=>{ - return( -
    • this.changeCourseListId(`${item.id}`)}> - {item.name} -
    • - ) - }) - } -
    -
    -
    -

    - 共参与{totalCount}个题库 -

    -
  • - {sort_by=="updated_at"?"时间最新":sort_by=="name"?"作业名称":"贡献者"} -
      -
    • this.changeOrder("updated_at")}>时间最新
    • -
    • this.changeOrder("name")}>作业名称
    • -
    • this.changeOrder("contributor")}>贡献者
    • -
    -
  • -
    -

    -
    - { - !data || data.question_banks.length==0 && - } - { - data && data.question_banks && data.question_banks.map((item,key)=>{ - return( -
    -
    - -
    -
    -

    - {item.name} - 发送 - { - item.is_public ==false ? - this.setPublic(1)} className="bank_public color-blue_4C fr mr60">设为公开:"" - } -

    -

    - {item.quotes_count}次引用 - {item.solve_count}次答题 - {moment(item.updated_at).format('YYYY-MM-DD HH:mm')} - this.setPublic(2)}>删除 - {item.course_list_name} -

    -
    -
    - ) - }) - } -
    - { - totalCount > 15 && -
    - -
    - } - -
    - ) - } -} +import React, { Component } from 'react'; +import {Pagination,Spin,Checkbox,Modal} from 'antd'; +import moment from 'moment'; +import axios from 'axios'; +import NoneData from '../../courses/coursesPublic/NoneData' +import {getImageUrl} from 'educoder'; +import "./usersInfo.css" +import Modals from '../../modals/Modals' + +const dateFormat ="YYYY-MM-DD HH:mm" +class InfosBank extends Component{ + constructor(props){ + super(props); + this.state={ + category:"common", + type:"publicly", + page:1, + per_page:16, + sort_by:"updated_at", + CoursesId:undefined, + + totalCount:undefined, + data:undefined, + isSpin:false, + + dialogOpen:false, + modalsTopval:undefined, + modalsBottomval:undefined, + modalSave:undefined + } + } + + componentDidMount=()=>{ + this.setState({ + isSpin:true + }) + let{category,type,page,sort_by,CoursesId}=this.state; + this.getCourses(category,type,page,sort_by,CoursesId); + } + + getCourses=(category,type,page,sort_by,CoursesId)=>{ + let url=`/users/${this.props.match.params.username}/question_banks.json`; + axios.get((url),{params:{ + category, + type, + page, + sort_by, + per_page:category && page ==1?17:16, + course_list_id:CoursesId + }}).then((result)=>{ + if(result){ + this.setState({ + totalCount:result.data.count, + data:result.data, + isSpin:false + }) + } + }).catch((error)=>{ + console.log(error); + }) + } + + //切换种类 + changeCategory=(cate)=>{ + this.setState({ + category:cate, + page:1, + isSpin:true + }) + let{type,sort_by,CoursesId}=this.state; + this.getCourses(cate,type,1,sort_by,CoursesId); + } + //切换状态 + changeType=(type)=>{ + this.setState({ + type:type, + page:1, + isSpin:true + }) + let{category,sort_by,CoursesId}=this.state; + this.getCourses(category,type,1,sort_by,CoursesId); + } + //切换页数 + changePage=(page)=>{ + this.setState({ + page, + isSpin:true + }) + let{category,type,sort_by,CoursesId}=this.state; + this.getCourses(category,type,page,sort_by,CoursesId); + } + + // 进入课堂 + turnToCourses=(url)=>{ + this.props.history.push(url); + } + + // 切换排序方式 + changeOrder= (sort)=>{ + this.setState({ + sort_by:sort, + isSpin:true + }) + let{category,type,page,CoursesId}=this.state; + this.getCourses(category,type,page,sort,CoursesId); + } + + changeCourseListId =(CoursesId)=>{ + this.setState({ + CoursesId, + isSpin:true + }) + let{category,type,sort,page}=this.state; + this.getCourses(category,type,page,sort,CoursesId); + } + + //设为公开/删除 + setPublic=(index)=>{ + this.setState({ + dialogOpen:true, + modalsTopval:index==1?"您确定要公开吗?":"确定要删除该题吗?", + modalsBottomval:index==1?"公开后不能重设为私有":"", + modalSave:()=>this.sureOperation(index) + }) + } + // 确定--设为公开/删除 + sureOperation=()=>{ + + } + + //弹框隐藏 + handleDialogClose=()=>{ + this.setState({ + dialogOpen:false + }) + } + + render(){ + let{ + category, + type, + page, + data, + totalCount, + sort_by, + isSpin, + CoursesId, + dialogOpen, + modalsTopval, + modalsBottomval,modalSave + } = this.state; + let isStudent = this.props.isStudent(); + let is_current=this.props.is_current; + return( +
    + + + +
    + +
    +
      +
    • this.changeCourseListId()}> + 全部 +
    • + { + data && data.course_list && data.course_list.map((item,key)=>{ + return( +
    • this.changeCourseListId(`${item.id}`)}> + {item.name} +
    • + ) + }) + } +
    +
    +
    +

    + 共参与{totalCount}个题库 +

    +
  • + {sort_by=="updated_at"?"时间最新":sort_by=="name"?"作业名称":"贡献者"} +
      +
    • this.changeOrder("updated_at")}>时间最新
    • +
    • this.changeOrder("name")}>作业名称
    • +
    • this.changeOrder("contributor")}>贡献者
    • +
    +
  • +
    +

    +
    + { + !data || data.question_banks.length==0 && + } + { + data && data.question_banks && data.question_banks.map((item,key)=>{ + return( +
    +
    + +
    +
    +

    + {item.name} + 发送 + { + item.is_public ==false ? + this.setPublic(1)} className="bank_public color-blue_4C fr mr60">设为公开:"" + } +

    +

    + {item.quotes_count}次引用 + {item.solve_count}次答题 + {moment(item.updated_at).format('YYYY-MM-DD HH:mm')} + this.setPublic(2)}>删除 + {item.course_list_name} +

    +
    +
    + ) + }) + } +
    + { + totalCount > 15 && +
    + +
    + } +
    +
    + ) + } +} export default InfosBank; \ No newline at end of file diff --git a/public/react/src/modules/user/usersInfo/InfosBanner.js b/public/react/src/modules/user/usersInfo/InfosBanner.js index 92dd4f1d2..08bea57ed 100644 --- a/public/react/src/modules/user/usersInfo/InfosBanner.js +++ b/public/react/src/modules/user/usersInfo/InfosBanner.js @@ -1,115 +1,122 @@ -import React, { Component } from 'react'; - -import {Link} from 'react-router-dom'; -import {Tooltip,Menu} from 'antd'; -import {getImageUrl} from 'educoder'; - -import "./usersInfo.css" -import "../../courses/css/members.css" -import "../../courses/css/Courses.css" - -import banner from '../../../images/account/infobanner.png' - -class InfosBanner extends Component{ - constructor(props){ - super(props); - } - render(){ - let { - data , - id, - login, - moduleName, - current_user, - }=this.props; - let is_current=this.props.is_current; - let {username}= this.props.match.params; - let {pathname}=this.props.location; - moduleName=pathname.split("/")[3]; - return( -
    -
    -
    -

    头像

    -
    -

    - {data && data.name} - { - data && is_current == false && data.identity =="学生" ? "" : - - } -

    -

    - - - - - - -

    -
    -
    -
    - {is_current ? "我":"TA"}的经验值 - {data && data.experience} -
    -
    - {is_current ? "我":"TA"}的金币 - {data && data.grade} -
    - { - is_current ? - - { - data && data.attendance_signed ? - 已签到 - : - 签到 - } - - : - - 私信 - - } -
    -
    -
    -
  • - this.setState({moduleName: 'courses'})} - to={`/users/${username}/courses`}>翻转课堂 -
  • -
  • - this.setState({moduleName: 'shixuns'})} - to={`/users/${username}/shixuns`}>实训项目 -
  • -
  • - this.setState({moduleName: 'paths'})} - to={`/users/${username}/paths`}>实践课程 -
  • -
  • - this.setState({moduleName: 'projects'})} - to={`/users/${username}/projects`}>开发项目 -
  • -
  • - this.setState({moduleName: 'package'})} - to={`/users/${username}/package`}>众包 -
  • - {((is_current && current_user && current_user.is_teacher ) || current_user && current_user.admin) - &&
  • - this.setState({moduleName: 'videos'})} - to={`/users/${username}/videos`}>视频 -
  • } -
    -
    -
    - ) - } -} +import React, { Component } from 'react'; + +import {Link} from 'react-router-dom'; +import {Tooltip,Menu} from 'antd'; +import {getImageUrl} from 'educoder'; + +import "./usersInfo.css" +import "../../courses/css/members.css" +import "../../courses/css/Courses.css" + +import { LinkAfterLogin } from 'educoder' + +class InfosBanner extends Component{ + constructor(props){ + super(props); + } + render(){ + let { + data , + id, + login, + moduleName, + current_user, + }=this.props; + let is_current=this.props.is_current; + let {username}= this.props.match.params; + let {pathname}=this.props.location; + moduleName=pathname.split("/")[3]; + return( +
    +
    +
    +

    头像

    +
    +

    + {data && data.name} + { + data && is_current == false && data.identity =="学生" ? "" : + + } +

    +

    + + + + + + +

    +
    +
    +
    + {is_current ? "我":"TA"}的经验值 + {data && data.experience} +
    +
    + {is_current ? "我":"TA"}的金币 + {data && data.grade} +
    + { + is_current ? + + { + data && data.attendance_signed ? + 已签到 + : + 签到 + } + + : + + + 私信 + + + } +
    +
    +
    +
  • + this.setState({moduleName: 'courses'})} + to={`/users/${username}/courses`}>翻转课堂 +
  • +
  • + this.setState({moduleName: 'shixuns'})} + to={`/users/${username}/shixuns`}>开发社区 +
  • +
  • + this.setState({moduleName: 'paths'})} + to={`/users/${username}/paths`}>实践课程 +
  • +
  • + this.setState({moduleName: 'projects'})} + to={`/users/${username}/projects`}>项目 +
  • +
  • + this.setState({moduleName: 'package'})} + to={`/users/${username}/package`}>众包 +
  • + {((is_current && current_user && current_user.is_teacher ) || current_user && current_user.admin) + &&
  • + this.setState({moduleName: 'videos'})} + to={`/users/${username}/videos`}>视频 +
  • } +
    +
    +
    + ) + } +} export default InfosBanner; \ No newline at end of file diff --git a/public/react/src/modules/user/usersInfo/InfosCourse.js b/public/react/src/modules/user/usersInfo/InfosCourse.js index c4c1c77e0..bc401d4d7 100644 --- a/public/react/src/modules/user/usersInfo/InfosCourse.js +++ b/public/react/src/modules/user/usersInfo/InfosCourse.js @@ -130,7 +130,7 @@ class InfosCourse extends Component{ this.props.current_user && this.props.current_user.user_identity != "学生" ? : "" } { - (!data || data.courses.length==0) && (!is_current || (this.props.current_user && this.props.current_user.user_identity === "学生" )) && + (!data || (data && data.courses.length==0)) && category && } { data && data.courses && data.courses.map((item,key)=>{ diff --git a/public/react/src/modules/user/usersInfo/InfosPath.js b/public/react/src/modules/user/usersInfo/InfosPath.js index cb02ed604..554d8380f 100644 --- a/public/react/src/modules/user/usersInfo/InfosPath.js +++ b/public/react/src/modules/user/usersInfo/InfosPath.js @@ -152,7 +152,7 @@ class InfosPath extends Component{ this.props.current_user && this.props.current_user.user_identity != "学生" ? :"" } { - (!data || data.subjects.length==0) && (!is_current || (this.props.current_user && this.props.current_user.user_identity === "学生" )) && + (!data || (data && data.subjects.length==0)) && category && } { data && data.subjects && data.subjects.map((item,key)=>{ diff --git a/public/react/src/modules/user/usersInfo/InfosProject.js b/public/react/src/modules/user/usersInfo/InfosProject.js index 2018f7b73..5aea5117b 100644 --- a/public/react/src/modules/user/usersInfo/InfosProject.js +++ b/public/react/src/modules/user/usersInfo/InfosProject.js @@ -125,7 +125,7 @@ class InfosProject extends Component{ :"" } { - (!data || data.projects.length==0) && (!is_current || (this.props.current_user && this.props.current_user.user_identity === "学生" )) && + (!data || (data && data.projects.length==0)) && category && } { data && data.projects && data.projects.map((item,key)=>{ diff --git a/public/react/src/modules/user/usersInfo/InfosShixun.js b/public/react/src/modules/user/usersInfo/InfosShixun.js index 94ef3c29b..4799626a9 100644 --- a/public/react/src/modules/user/usersInfo/InfosShixun.js +++ b/public/react/src/modules/user/usersInfo/InfosShixun.js @@ -1,14 +1,11 @@ import React, { Component } from 'react'; -import { SnackbarHOC } from 'educoder'; -import {BrowserRouter as Router,Route,Switch} from 'react-router-dom'; -import {Tooltip,Menu,Pagination,Spin} from 'antd'; -import Loadable from 'react-loadable'; -import Loading from '../../../Loading'; + +import { Pagination , Spin } from 'antd'; + import NoneData from '../../courses/coursesPublic/NoneData' import axios from 'axios'; -import {getImageUrl,setImagesUrl} from 'educoder'; -import { TPMIndexHOC } from '../../tpm/TPMIndexHOC'; -import { CNotificationHOC } from '../../courses/common/CNotificationHOC' +import { setImagesUrl } from 'educoder'; + import "./usersInfo.css" import Create from './publicCreatNew' @@ -115,7 +112,7 @@ class InfosShixun extends Component{ totalCount, isSpin } = this.state; - let isStudent = this.props.isStudent(); + let is_current=this.props.is_current; return(
    @@ -157,20 +154,18 @@ class InfosShixun extends Component{
    { - page == 1 && is_current && !category && this.props.current_user && this.props.current_user.user_identity != "学生" ? + page == 1 && is_current && !category && this.props.current_user && this.props.current_user.user_identity != "学生" ? :"" } { - (!data || data.shixuns.length==0) && (!is_current || (this.props.current_user && this.props.current_user.user_identity === "学生" )) && + (!data || (data && data.shixuns.length==0)) && category && } { data && data.shixuns && data.shixuns.map((item,key)=>{ return(
    this.turnToCourses(`/shixuns/${item.identifier}/challenges`)}> { - item.tag &&
    {item.tag} - {/**/} -
    + item.tag &&
    {item.tag}
    } diff --git a/public/react/src/modules/user/usersInfo/banner_out.js b/public/react/src/modules/user/usersInfo/banner_out.js index 7afcf50fb..986a66cd3 100644 --- a/public/react/src/modules/user/usersInfo/banner_out.js +++ b/public/react/src/modules/user/usersInfo/banner_out.js @@ -1,190 +1,190 @@ -import React, { Component } from 'react'; - -import {Link} from 'react-router-dom'; -import {Tooltip,Menu} from 'antd'; -import {getImageUrl} from 'educoder'; - -import "./usersInfo.css" -import "../../courses/css/members.css" -import "../../courses/css/Courses.css" -class banner_out extends Component{ - constructor(props){ - super(props); - } - render(){ - let { - data , - is_current, - is_edit, - sign, - type, - followed, - id, - login, - moduleName, - next_gold - }=this.props; - let {username}= this.props.match.params; - return( -
    -
    -
    -
    -
    -
    - - -
    - {is_current ? "我":"TA"}的金币 - {data && data.grade} -
    -
    - 头像 -
    -
    - {is_current ? "我":"TA"}的粉丝 - {data && data.fan_count} -
    - -
    - {is_current ? "我":"TA"}的关注 - {data && data.follow_count} -
    - - {data && data.name} -
    -
    -
    -
    - { - data && is_current == false && data.identity =="学生" ? "" : {data && data.identity} - } - - - - - - - - - - - - - - - - - - - - - {/* */} - { - data && data.college_identifier && - - - - - - } -
    -
    -
    -

    - { - is_edit && is_current ? - - : - is_current ? - {sign || "这家伙很懒,什么都没留下~"} - : - {sign || "这家伙很懒,什么都没留下~"} - } -

    - { - is_current ? -
    - { - data && data.attendance_signed ? - - 已签到 -

    明日签到 +{next_gold} 金币

    -
    - : - 签到 - // 试用申请 - } -
    - : - - } -
    -
    -
    -
  • - this.setState({moduleName: 'courses'})} - to={`/users/${username}/courses`}>课堂 -
  • -
  • - this.setState({moduleName: 'shixuns'})} - to={`/users/${username}/shixuns`}>实训 -
  • -
  • - this.setState({moduleName: 'paths'})} - to={`/users/${username}/paths`}>实践课程 -
  • -
  • - this.setState({moduleName: 'projects'})} - to={`/users/${username}/projects`}>开发项目 -
  • - -
  • - this.setState({moduleName: 'package'})} - to={`/users/${username}/package`}>众包 -
  • - - {/*{ data && data.identity!="学生" &&
  • 题库
  • }*/} - -
    -
    -
    -
    -
    - ) - } -} +import React, { Component } from 'react'; + +import {Link} from 'react-router-dom'; +import {Tooltip,Menu} from 'antd'; +import {getImageUrl} from 'educoder'; + +import "./usersInfo.css" +import "../../courses/css/members.css" +import "../../courses/css/Courses.css" +class banner_out extends Component{ + constructor(props){ + super(props); + } + render(){ + let { + data , + is_current, + is_edit, + sign, + type, + followed, + id, + login, + moduleName, + next_gold + }=this.props; + let {username}= this.props.match.params; + return( +
    +
    +
    +
    +
    +
    +
    + {is_current ? "我":"TA"}的经验值 + {data && data.experience} +
    + +
    + {is_current ? "我":"TA"}的金币 + {data && data.grade} +
    +
    + 头像 +
    +
    + {is_current ? "我":"TA"}的粉丝 + {data && data.fan_count} +
    + +
    + {is_current ? "我":"TA"}的关注 + {data && data.follow_count} +
    + + {data && data.name} +
    +
    +
    +
    + { + data && is_current == false && data.identity =="学生" ? "" : {data && data.identity} + } + + + + + + + + + + + + + + + + + + + + + {/* */} + { + data && data.college_identifier && + + + + + + } +
    +
    +
    +

    + { + is_edit && is_current ? + + : + is_current ? + {sign || "这家伙很懒,什么都没留下~"} + : + {sign || "这家伙很懒,什么都没留下~"} + } +

    + { + is_current ? +
    + { + data && data.attendance_signed ? + + 已签到 +

    明日签到 +{next_gold} 金币

    +
    + : + 签到 + // 试用申请 + } +
    + : + + } +
    +
    +
    +
  • + this.setState({moduleName: 'courses'})} + to={`/users/${username}/courses`}>课堂 +
  • +
  • + this.setState({moduleName: 'shixuns'})} + to={`/users/${username}/shixuns`}>实训 +
  • +
  • + this.setState({moduleName: 'paths'})} + to={`/users/${username}/paths`}>实践课程 +
  • +
  • + this.setState({moduleName: 'projects'})} + to={`/users/${username}/projects`}>开发项目 +
  • + +
  • + this.setState({moduleName: 'package'})} + to={`/users/${username}/package`}>众包 +
  • + + {/*{ data && data.identity!="学生" &&
  • 题库
  • }*/} + +
    +
    +
    +
    +
    + ) + } +} export default banner_out; \ No newline at end of file diff --git a/public/react/src/public-path.js b/public/react/src/public-path.js new file mode 100644 index 000000000..548a1f734 --- /dev/null +++ b/public/react/src/public-path.js @@ -0,0 +1,6 @@ +/*global __webpack_public_path__ */ +if ( window.location.host == 'pre-newweb.educoder.net') { + __webpack_public_path__ = 'https://testali-cdn.educoder.net/react/build/' +} else if ( window.location.host == 'www.educoder.net') { + __webpack_public_path__ = 'https://ali-cdn.educoder.net/react/build/' +} \ No newline at end of file diff --git a/public/stylesheets/educoder/edu-all.css b/public/stylesheets/educoder/edu-all.css index c4718c076..de4cfb6b7 100644 --- a/public/stylesheets/educoder/edu-all.css +++ b/public/stylesheets/educoder/edu-all.css @@ -121,7 +121,7 @@ em.vertical-line{display: inline-block;width: 2px;background: #999;height: 10px} .tag-green .tag-name{display: block;width: auto; /*background-image: url("/images/educoder/tag1.png");*/ background: rgba(000,000,000,0.56); - border: 1px solid #fff; + border: 1px solid rgba(255,255,255,0.56); border-radius: 3px; font-size: 12px; /*opacity: 0.56;*/ @@ -448,8 +448,8 @@ table.text-file{} /*-------------------------------实训路径-------------------------------*/ .path-head{width: 100%;height: 300px;background-image: url("/images/educoder/path.png"); - background-color: #081C4B; - background-size: cover; + background-color: #000a4f; + /*background-size: cover;*/ background-position: center; background-repeat: no-repeat; }