diff --git a/app/assets/images/bootstrap/glyphicons-halflings.png b/app/assets/images/bootstrap/glyphicons-halflings.png new file mode 100644 index 0000000..92d4445 Binary files /dev/null and b/app/assets/images/bootstrap/glyphicons-halflings.png differ diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index a406fb6..7b87799 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -10,4 +10,10 @@ //= require pjax //= require active_scaffold //= require slides +//= require bootstrap-tooltip +//= require bootstrap-popover //= require_self + +$(function(){ + $('[rel=popover]').popover(); +}); \ No newline at end of file diff --git a/app/assets/javascripts/bootstrap-popover.js b/app/assets/javascripts/bootstrap-popover.js new file mode 100644 index 0000000..57864fc --- /dev/null +++ b/app/assets/javascripts/bootstrap-popover.js @@ -0,0 +1,95 @@ +/* =========================================================== + * bootstrap-popover.js v2.0.0 + * http://twitter.github.com/bootstrap/javascript.html#popovers + * =========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================================================== */ + + +!function( $ ) { + + "use strict" + + var Popover = function ( element, options ) { + this.init('popover', element, options) + } + + /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js + ========================================== */ + + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, { + + constructor: Popover + + , setContent: function () { + var $tip = this.tip() + , title = this.getTitle() + , content = this.getContent() + + $tip.find('.title')[ $.type(title) == 'object' ? 'append' : 'html' ](title) + $tip.find('.content > *')[ $.type(content) == 'object' ? 'append' : 'html' ](content) + + $tip.removeClass('fade top bottom left right in') + } + + , hasContent: function () { + return this.getTitle() || this.getContent() + } + + , getContent: function () { + var content + , $e = this.$element + , o = this.options + + content = $e.attr('data-content') + || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content) + + content = content.toString().replace(/(^\s*|\s*$)/, "") + + return content + } + + , tip: function() { + if (!this.$tip) { + this.$tip = $(this.options.template) + } + return this.$tip + } + + }) + + + /* POPOVER PLUGIN DEFINITION + * ======================= */ + + $.fn.popover = function ( option ) { + return this.each(function () { + var $this = $(this) + , data = $this.data('popover') + , options = typeof option == 'object' && option + if (!data) $this.data('popover', (data = new Popover(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.popover.Constructor = Popover + + $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, { + placement: 'right' + , content: '' + , template: '

' + }) + +}( window.jQuery ) diff --git a/app/assets/javascripts/bootstrap-tooltip.js b/app/assets/javascripts/bootstrap-tooltip.js new file mode 100644 index 0000000..67fca5e --- /dev/null +++ b/app/assets/javascripts/bootstrap-tooltip.js @@ -0,0 +1,273 @@ +/* =========================================================== + * bootstrap-tooltip.js v2.0.0 + * http://twitter.github.com/bootstrap/javascript.html#tooltips + * Inspired by the original jQuery.tipsy by Jason Frame + * =========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + +!function( $ ) { + + "use strict" + + /* TOOLTIP PUBLIC CLASS DEFINITION + * =============================== */ + + var Tooltip = function ( element, options ) { + this.init('tooltip', element, options) + } + + Tooltip.prototype = { + + constructor: Tooltip + + , init: function ( type, element, options ) { + var eventIn + , eventOut + + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.enabled = true + + if (this.options.trigger != 'manual') { + eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus' + eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur' + this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this)) + } + + this.options.selector ? + (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : + this.fixTitle() + } + + , getOptions: function ( options ) { + options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data()) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay + , hide: options.delay + } + } + + return options + } + + , enter: function ( e ) { + var self = $(e.currentTarget)[this.type](this._options).data(this.type) + + if (!self.options.delay || !self.options.delay.show) { + self.show() + } else { + self.hoverState = 'in' + setTimeout(function() { + if (self.hoverState == 'in') { + self.show() + } + }, self.options.delay.show) + } + } + + , leave: function ( e ) { + var self = $(e.currentTarget)[this.type](this._options).data(this.type) + + if (!self.options.delay || !self.options.delay.hide) { + self.hide() + } else { + self.hoverState = 'out' + setTimeout(function() { + if (self.hoverState == 'out') { + self.hide() + } + }, self.options.delay.hide) + } + } + + , show: function () { + var $tip + , inside + , pos + , actualWidth + , actualHeight + , placement + , tp + + if (this.hasContent() && this.enabled) { + $tip = this.tip() + this.setContent() + + if (this.options.animation) { + $tip.addClass('fade') + } + + placement = typeof this.options.placement == 'function' ? + this.options.placement.call(this, $tip[0], this.$element[0]) : + this.options.placement + + inside = /in/.test(placement) + + $tip + .remove() + .css({ top: 0, left: 0, display: 'block' }) + .appendTo(inside ? this.$element : document.body) + + pos = this.getPosition(inside) + + actualWidth = $tip[0].offsetWidth + actualHeight = $tip[0].offsetHeight + + switch (inside ? placement.split(' ')[1] : placement) { + case 'bottom': + tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2} + break + case 'top': + tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2} + break + case 'left': + tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth} + break + case 'right': + tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width} + break + } + + if (this.options['z-index']) tp['z-index'] = this.options['z-index'] + + $tip + .css(tp) + .addClass(placement) + .addClass('in') + } + } + + , setContent: function () { + var $tip = this.tip() + $tip.find('.tooltip-inner').html(this.getTitle()) + $tip.removeClass('fade in top bottom left right') + } + + , hide: function () { + var that = this + , $tip = this.tip() + + $tip.removeClass('in') + + function removeWithAnimation() { + var timeout = setTimeout(function () { + $tip.off($.support.transition.end).remove() + }, 500) + + $tip.one($.support.transition.end, function () { + clearTimeout(timeout) + $tip.remove() + }) + } + + $.support.transition && this.$tip.hasClass('fade') ? + removeWithAnimation() : + $tip.remove() + } + + , fixTitle: function () { + var $e = this.$element + if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title') + } + } + + , hasContent: function () { + return this.getTitle() + } + + , getPosition: function (inside) { + return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), { + width: this.$element[0].offsetWidth + , height: this.$element[0].offsetHeight + }) + } + + , getTitle: function () { + var title + , $e = this.$element + , o = this.options + + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + + title = title.toString().replace(/(^\s*|\s*$)/, "") + + return title + } + + , tip: function () { + return this.$tip = this.$tip || $(this.options.template) + } + + , validate: function () { + if (!this.$element[0].parentNode) { + this.hide() + this.$element = null + this.options = null + } + } + + , enable: function () { + this.enabled = true + } + + , disable: function () { + this.enabled = false + } + + , toggleEnabled: function () { + this.enabled = !this.enabled + } + + , toggle: function () { + this[this.tip().hasClass('in') ? 'hide' : 'show']() + } + + } + + + /* TOOLTIP PLUGIN DEFINITION + * ========================= */ + + $.fn.tooltip = function ( option ) { + return this.each(function () { + var $this = $(this) + , data = $this.data('tooltip') + , options = typeof option == 'object' && option + if (!data) $this.data('tooltip', (data = new Tooltip(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.tooltip.Constructor = Tooltip + + $.fn.tooltip.defaults = { + animation: true + , delay: 0 + , selector: false + , placement: 'top' + , trigger: 'hover' + , title: '' + , template: '
' + , 'z-index': false + } + +}( window.jQuery ) diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 5e26b32..e0bdc8c 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -5,6 +5,8 @@ *= require normalize +*= require bootstrap/bootstrap + *= require theme/base *= require theme/theme *= require theme/error_explanation diff --git a/app/assets/stylesheets/bootstrap/bootstrap.scss b/app/assets/stylesheets/bootstrap/bootstrap.scss new file mode 100644 index 0000000..c4f9256 --- /dev/null +++ b/app/assets/stylesheets/bootstrap/bootstrap.scss @@ -0,0 +1,545 @@ +.icon { + background-image: url(image-path('bootstrap/glyphicons-halflings.png')); + background-position: 14px 14px; + background-repeat: no-repeat; + display: inline-block; + vertical-align: text-top; + width: 14px; + height: 14px; + *margin-right: .3em; +} +.icon:last-child { + *margin-left: 0; +} +.icon.white { + background-image: url(../img/glyphicons-halflings-white.png); +} +.icon.glass { + background-position: 0 0; +} +.icon.music { + background-position: -24px 0; +} +.icon.search { + background-position: -48px 0; +} +.icon.envelope { + background-position: -72px 0; +} +.icon.heart { + background-position: -96px 0; +} +.icon.star { + background-position: -120px 0; +} +.icon.star-empty { + background-position: -144px 0; +} +.icon.user { + background-position: -168px 0; +} +.icon.film { + background-position: -192px 0; +} +.icon.th-large { + background-position: -216px 0; +} +.icon.th { + background-position: -240px 0; +} +.icon.th-list { + background-position: -264px 0; +} +.icon.ok { + background-position: -288px 0; +} +.icon.remove { + background-position: -312px 0; +} +.icon.zoom-in { + background-position: -336px 0; +} +.icon.zoom-out { + background-position: -360px 0; +} +.icon.off { + background-position: -384px 0; +} +.icon.signal { + background-position: -408px 0; +} +.icon.cog { + background-position: -432px 0; +} +.icon.trash { + background-position: -456px 0; +} +.icon.home { + background-position: 0 -24px; +} +.icon.file { + background-position: -24px -24px; +} +.icon.time { + background-position: -48px -24px; +} +.icon.road { + background-position: -72px -24px; +} +.icon.download-alt { + background-position: -96px -24px; +} +.icon.download { + background-position: -120px -24px; +} +.icon.upload { + background-position: -144px -24px; +} +.icon.inbox { + background-position: -168px -24px; +} +.icon.play-circle { + background-position: -192px -24px; +} +.icon.repeat { + background-position: -216px -24px; +} +.icon.refresh { + background-position: -240px -24px; +} +.icon.list-alt { + background-position: -264px -24px; +} +.icon.lock { + background-position: -287px -24px; +} +.icon.flag { + background-position: -312px -24px; +} +.icon.headphones { + background-position: -336px -24px; +} +.icon.volume-off { + background-position: -360px -24px; +} +.icon.volume-down { + background-position: -384px -24px; +} +.icon.volume-up { + background-position: -408px -24px; +} +.icon.qrcode { + background-position: -432px -24px; +} +.icon.barcode { + background-position: -456px -24px; +} +.icon.tag { + background-position: 0 -48px; +} +.icon.tags { + background-position: -25px -48px; +} +.icon.book { + background-position: -48px -48px; +} +.icon.bookmark { + background-position: -72px -48px; +} +.icon.print { + background-position: -96px -48px; +} +.icon.camera { + background-position: -120px -48px; +} +.icon.font { + background-position: -144px -48px; +} +.icon.bold { + background-position: -167px -48px; +} +.icon.italic { + background-position: -192px -48px; +} +.icon.text-height { + background-position: -216px -48px; +} +.icon.text-width { + background-position: -240px -48px; +} +.icon.align-left { + background-position: -264px -48px; +} +.icon.align-center { + background-position: -288px -48px; +} +.icon.align-right { + background-position: -312px -48px; +} +.icon.align-justify { + background-position: -336px -48px; +} +.icon.list { + background-position: -360px -48px; +} +.icon.indent-left { + background-position: -384px -48px; +} +.icon.indent-right { + background-position: -408px -48px; +} +.icon.facetime-video { + background-position: -432px -48px; +} +.icon.picture { + background-position: -456px -48px; +} +.icon.pencil { + background-position: 0 -72px; +} +.icon.map-marker { + background-position: -24px -72px; +} +.icon.adjust { + background-position: -48px -72px; +} +.icon.tint { + background-position: -72px -72px; +} +.icon.edit { + background-position: -96px -72px; +} +.icon.share { + background-position: -120px -72px; +} +.icon.check { + background-position: -144px -72px; +} +.icon.move { + background-position: -168px -72px; +} +.icon.step-backward { + background-position: -192px -72px; +} +.icon.fast-backward { + background-position: -216px -72px; +} +.icon.backward { + background-position: -240px -72px; +} +.icon.play { + background-position: -264px -72px; +} +.icon.pause { + background-position: -288px -72px; +} +.icon.stop { + background-position: -312px -72px; +} +.icon.forward { + background-position: -336px -72px; +} +.icon.fast-forward { + background-position: -360px -72px; +} +.icon.step-forward { + background-position: -384px -72px; +} +.icon.eject { + background-position: -408px -72px; +} +.icon.chevron-left { + background-position: -432px -72px; +} +.icon.chevron-right { + background-position: -456px -72px; +} +.icon.plus-sign { + background-position: 0 -96px; +} +.icon.minus-sign { + background-position: -24px -96px; +} +.icon.remove-sign { + background-position: -48px -96px; +} +.icon.ok-sign { + background-position: -72px -96px; +} +.icon.question-sign { + background-position: -96px -96px; +} +.icon.info-sign { + background-position: -120px -96px; +} +.icon.screenshot { + background-position: -144px -96px; +} +.icon.remove-circle { + background-position: -168px -96px; +} +.icon.ok-circle { + background-position: -192px -96px; +} +.icon.ban-circle { + background-position: -216px -96px; +} +.icon.arrow-left { + background-position: -240px -96px; +} +.icon.arrow-right { + background-position: -264px -96px; +} +.icon.arrow-up { + background-position: -289px -96px; +} +.icon.arrow-down { + background-position: -312px -96px; +} +.icon.share-alt { + background-position: -336px -96px; +} +.icon.resize-full { + background-position: -360px -96px; +} +.icon.resize-small { + background-position: -384px -96px; +} +.icon.plus { + background-position: -408px -96px; +} +.icon.minus { + background-position: -433px -96px; +} +.icon.asterisk { + background-position: -456px -96px; +} +.icon.exclamation-sign { + background-position: 0 -120px; +} +.icon.gift { + background-position: -24px -120px; +} +.icon.leaf { + background-position: -48px -120px; +} +.icon.fire { + background-position: -72px -120px; +} +.icon.eye-open { + background-position: -96px -120px; +} +.icon.eye-close { + background-position: -120px -120px; +} +.icon.warning-sign { + background-position: -144px -120px; +} +.icon.plane { + background-position: -168px -120px; +} +.icon.calendar { + background-position: -192px -120px; +} +.icon.random { + background-position: -216px -120px; +} +.icon.comment { + background-position: -240px -120px; +} +.icon.magnet { + background-position: -264px -120px; +} +.icon.chevron-up { + background-position: -288px -120px; +} +.icon.chevron-down { + background-position: -313px -119px; +} +.icon.retweet { + background-position: -336px -120px; +} +.icon.shopping-cart { + background-position: -360px -120px; +} +.icon.folder-close { + background-position: -384px -120px; +} +.icon.folder-open { + background-position: -408px -120px; +} +.icon.resize-vertical { + background-position: -432px -119px; +} +.icon.resize-horizontal { + background-position: -456px -118px; +} +.tooltip { + position: absolute; + z-index: 1020; + display: block; + visibility: visible; + padding: 5px; + font-size: 11px; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.tooltip.top { + margin-top: -2px; +} +.tooltip.right { + margin-left: 2px; +} +.tooltip.bottom { + margin-top: 2px; +} +.tooltip.left { + margin-left: -2px; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid #000000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #000000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #000000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #000000; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + padding: 5px; +} +.popover.top { + margin-top: -5px; +} +.popover.right { + margin-left: 5px; +} +.popover.bottom { + margin-top: 5px; +} +.popover.left { + margin-left: -5px; +} +.popover.top .arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid #000000; +} +.popover.right .arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #000000; +} +.popover.bottom .arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #000000; +} +.popover.left .arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #000000; +} +.popover .arrow { + position: absolute; + width: 0; + height: 0; +} +.popover .inner { + padding: 3px; + width: 280px; + overflow: hidden; + background: #000000; + background: rgba(0, 0, 0, 0.8); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); +} +.popover .title { + padding: 9px 15px; + line-height: 1; + background-color: #f5f5f5; + border-bottom: 1px solid #eee; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; + + -webkit-margin-before: 0; + -webkit-margin-after: 0; +} +.popover .content { + padding: 14px; + background-color: #ffffff; + -webkit-border-radius: 0 0 3px 3px; + -moz-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.popover .content p, .popover .content ul, .popover .content ol { + margin-bottom: 0; +} diff --git a/app/assets/stylesheets/overrides.css.erb b/app/assets/stylesheets/overrides.css.erb deleted file mode 100644 index 5a96ee2..0000000 --- a/app/assets/stylesheets/overrides.css.erb +++ /dev/null @@ -1,35 +0,0 @@ -#main .block .content p { - font-size: 16px; -} - -#main .block .content h2 { - margin-left: 0; -} - -#main .block .content .active-scaffold-header h2 { - font-size: 160%; -} - -#main .block .content .active-scaffold th a { - text-shadow: none; -} - -#main .block .content .active-scaffold th p { - font: bold 11px arial, sans-serif; - text-shadow: none; -} - -body.errors #main .inner { - margin-top: 15px; -} - -#as_domains-active-scaffold .name-column, -#as_hosts-active-scaffold .name-column { - font-weight: bold; - text-shadow: none; -} - -.flash .alert { - border: 1px solid #bb9004; - background: #f9c006 url(<%= image_path("messages/warning.png") %>) no-repeat 10px center; -} diff --git a/app/assets/stylesheets/overrides.css.scss b/app/assets/stylesheets/overrides.css.scss new file mode 100644 index 0000000..eec0638 --- /dev/null +++ b/app/assets/stylesheets/overrides.css.scss @@ -0,0 +1,65 @@ +#main .block .content p { + font-size: 16px; +} + +#main .block .content h2 { + margin-left: 0; +} + +#main .block .content .active-scaffold-header h2 { + font-size: 160%; +} + +#main .block .content .active-scaffold th a { + text-shadow: none; +} + +#main .block .content .active-scaffold th p { + font: bold 11px arial, sans-serif; + text-shadow: none; +} + +body.errors #main .inner { + margin-top: 15px; +} + +#as_domains-active-scaffold .name-column, +#as_hosts-active-scaffold .name-column { + font-weight: bold; + text-shadow: none; +} + +#as_domains-active-scaffold tr.shared-domain { + &.record { + background-color: mix(#E6F2FF, lighten(yellow, 30%)); + } + &.record td { + border-bottom: solid 1px #C5DBF7; + border-left: solid 1px #C5DBF7; + } + + &.even-record { + background-color: mix(#fff, lighten(yellow, 40%)); + } + &.even-record td { + border-left-color: #ddd; + } + + &.record td.sorted { + background-color: mix(#B9DCFF, lighten(yellow, 30%)); + border-bottom-color: #AFD0F5; + } + + &.even-record td.sorted { + background-color: mix(#E6F2FF, lighten(yellow, 40%)); + border-bottom-color: #AFD0F5; + } + &.record td.actions table td { + border: none; + } +} + +.flash .alert { + border: 1px solid #bb9004; + background: #f9c006 url(image-path("messages/warning.png")) no-repeat 10px center; +} diff --git a/app/models/ability.rb b/app/models/ability.rb index 0527f30..7daaccd 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -1,5 +1,5 @@ class Ability - CRUD = [:read, :create, :edit, :destroy] + CRUD = [:read, :create, :update, :destroy] include CanCan::Ability attr_accessor :user @@ -48,7 +48,7 @@ class Ability def action_aliases alias_action :row, :show_search, :render_field, :to => :read alias_action :update_column, :add_association, :edit_associated, - :edit_associated, :new_existing, :add_existing, :to => :edit + :edit_associated, :new_existing, :add_existing, :to => :update alias_action :delete, :destroy_existing, :to => :destroy end diff --git a/app/views/domains/_form_association_footer.html.erb b/app/views/domains/_form_association_footer.html.erb index c07da7a..b9aea05 100644 --- a/app/views/domains/_form_association_footer.html.erb +++ b/app/views/domains/_form_association_footer.html.erb @@ -1,5 +1,4 @@ -<% -# hide "Replace with new" for SOA record +<% # hide "Replace with new" for SOA record begin remote_controller = active_scaffold_controller_for(column.association.klass) diff --git a/app/views/domains/_list_record.html.erb b/app/views/domains/_list_record.html.erb new file mode 100644 index 0000000..60fca19 --- /dev/null +++ b/app/views/domains/_list_record.html.erb @@ -0,0 +1,15 @@ +<% # customize row class to highlight shared domains + +record = list_record if list_record # compat with render :partial :collection +columns ||= list_columns +tr_class = cycle("", "even-record") +tr_class += " shared-domain" if cannot?(:crud_permissions, record) +url_options = params_for(:action => :list, :id => record.id) +action_links ||= active_scaffold_config.action_links.member +-%> + + + <%= render :partial => 'list_record_columns', :locals => {:record => record, :columns => columns} %> + <%= render :partial => 'list_actions', :locals => {:record => record, :url_options => url_options, :action_links => action_links} unless action_links.empty? %> + <%= render_nested_view(action_links, url_options, record) unless @nested_auto_open.nil? %> + diff --git a/app/views/domains/_list_record_columns.html.erb b/app/views/domains/_list_record_columns.html.erb index 23d515e..82bfd1f 100644 --- a/app/views/domains/_list_record_columns.html.erb +++ b/app/views/domains/_list_record_columns.html.erb @@ -3,6 +3,7 @@ <% columns.each do |column| %> <% authorized = record.authorized_for?(:crud_type => :read, :column => column.name) -%> <% column_value = authorized ? get_column_value(record, column) : active_scaffold_config.list.empty_field_text -%> + <% can_crud_permissions = can?(:crud_permissions, record) -%> <% if column.name == :name %> @@ -13,6 +14,13 @@ else column_value end %> + <% unless can_crud_permissions %> + <% who = "#{record.user.name} #{mail_to record.user.email}" %> + + <% end %> <% elsif column.name == :records %> @@ -24,7 +32,7 @@ <% if column_value == '-' column_value = 'Permissions (0)' - authorized &&= can?(:crud_permissions, record) + authorized &&= can_crud_permissions end %> <%= authorized ? render_list_column(column_value, column, record) : column_value %>