Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ gem 'inline_svg'
gem 'countries'

# Authorization
gem "pundit"
gem 'pundit'

# These are the dummy app's dependencies
group :development, :test do
Expand Down Expand Up @@ -83,6 +83,7 @@ group :development, :test do
gem 'rubocop'
gem 'simplecov', require: false
gem 'simplecov-cobertura'
gem 'webmock'

# Release helper
gem 'bump', require: false
Expand All @@ -93,3 +94,5 @@ gem 'zeitwerk', '~> 2.3'

# Pagination
gem 'kaminari'

gem 'httparty'
16 changes: 16 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ PATH
specs:
avo (0.2.5)
countries
httparty
inline_svg
kaminari
pundit
Expand Down Expand Up @@ -92,6 +93,7 @@ GEM
i18n_data (~> 0.10.0)
sixarm_ruby_unaccent (~> 1.1)
unicode_utils (~> 1.4)
crack (0.4.4)
crass (1.0.6)
database_cleaner (1.8.5)
debase (0.2.4.1)
Expand Down Expand Up @@ -124,6 +126,10 @@ GEM
gem-release (2.1.1)
globalid (0.4.2)
activesupport (>= 4.2.0)
hashdiff (1.0.1)
httparty (0.18.1)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
i18n (1.8.5)
concurrent-ruby (~> 1.0)
i18n_data (0.10.0)
Expand Down Expand Up @@ -156,11 +162,15 @@ GEM
marcel (0.3.3)
mimemagic (~> 0.3.2)
method_source (1.0.0)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2020.0512)
mimemagic (0.3.5)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.14.2)
msgpack (1.3.3)
multi_xml (0.6.0)
nio4r (2.5.4)
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
Expand Down Expand Up @@ -297,6 +307,10 @@ GEM
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (>= 3.0, < 4.0)
webmock (3.9.3)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webpacker (4.3.0)
activesupport (>= 4.2)
rack-proxy (>= 0.6.1)
Expand Down Expand Up @@ -326,6 +340,7 @@ DEPENDENCIES
faker
fuubar
gem-release
httparty
inline_svg
jbuilder (~> 2.7)
kaminari
Expand All @@ -346,6 +361,7 @@ DEPENDENCIES
tzinfo-data
web-console (>= 3.3.0)
webdrivers
webmock
webpacker (~> 4.0)
zeitwerk (~> 2.3)

Expand Down
4 changes: 2 additions & 2 deletions app/controllers/avo/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
module Avo
class ApplicationController < ActionController::Base
include Pundit
rescue_from ActiveRecord::RecordInvalid, with: :exception_logger
protect_from_forgery with: :exception
before_action :init_app

def init_app
Avo::App.init
Avo::App.init request
@license = Avo::App.license
end

def exception_logger(exception)
Expand Down
7 changes: 6 additions & 1 deletion app/controllers/avo/resource_overview_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Avo
class ResourceOverviewController < ApplicationController
def index
resources = App.get_resources.map do |resource|
resources = App.get_resources.select { |resource| AuthorizationService::authorize session_user, resource.model, 'index?' }.map do |resource|
{
name: resource.name,
url: resource.url,
Expand All @@ -17,5 +17,10 @@ def index
hide_docs: Avo.configuration.hide_documentation_link,
}
end

private
def session_user
current_user.present? ? current_user : nil
end
end
end
24 changes: 6 additions & 18 deletions app/controllers/avo/resources_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,15 @@ def index
params[:sort_by] = params[:sort_by].present? ? params[:sort_by] : :created_at
params[:sort_direction] = params[:sort_direction].present? ? params[:sort_direction] : :desc

begin
query = policy_scope(resource_model)
rescue => exception
query = resource_model
end
query = AuthorizationService.with_policy current_user, resource_model

if params[:via_resource_name].present? and params[:via_resource_id].present? and params[:via_relationship].present?
# get the related resource (via_resource)
related_resource = App.get_resource_by_name(params[:via_resource_name])
related_model = related_resource.model

# fetch the entries
query = related_model.find(params[:via_resource_id]).public_send(params[:via_relationship])

# Try and substitute the query with a scoped query if we find a scope for this related model class
begin
related_model_class = related_model._reflections[params[:via_relationship].to_s].class_name.safe_constantize
policy_scope related_model_class
query = policy_scope query
rescue => exception
end
related_model = App.get_resource_by_name(params[:via_resource_name]).model

relation = related_model.find(params[:via_resource_id]).public_send(params[:via_relationship])
query = AuthorizationService.with_policy current_user, relation

params[:per_page] = Avo.configuration.via_per_page
elsif ['has_many', 'has_and_belongs_to_many'].include? params[:for_relation]
# has_many searchable query
Expand Down
22 changes: 13 additions & 9 deletions app/frontend/js/components/ApplicationSidebar.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
<template>
<div class="application-sidebar flex h-full bg-white text-white w-56 z-50 border-r border-gray-400">
<div class="w-full">
<div class="flex flex-col w-full">
<router-link to="/" class="logo-placeholder h-16 bg-white p-2 flex justify-center" :active-class="''" exact>
<slot />
<slot name="logo"/>
</router-link>

<div class="tools py-4">
<sidebar-link to="/"
exact
>
Dashboard
</sidebar-link>
<div class="flex-1 flex flex-col justify-between">
<div class="tools py-4">
<sidebar-link to="/"
exact
>
Dashboard
</sidebar-link>

<resources-navigation :resources="resources"/>
<resources-navigation :resources="resources"/>
</div>

<slot name="licensing"/>
</div>
</div>
</div>
Expand Down
23 changes: 23 additions & 0 deletions app/frontend/js/components/LicenseWarning.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<template>
<div class="w-10/12 ml-1/12 inset-auto bottom-0 z-50 my-4 opacity-50 hover:opacity-100 transition-opacity duration-150 group">
<a href="https://avohq.io/pricing" target="_blank" class="rounded bg-teal-700 text-white py-2 px-4 text-sm block group-hover:pt-4">
<div class="h-6 inline mr-1" :is="iconElement" v-if="icon" /> <strong v-text="title" />
<div class="group-hover:block hidden py-2">
{{message}} <arrow-circle-right-icon class="h-6 inline float-right"></arrow-circle-right-icon>
</div>
</a>
</div>
</template>

<script>
export default {
props: ['title', 'message', 'icon'],
computed: {
iconElement() {
if (this.icon) return `${this.icon}-icon`

return null
},
},
}
</script>
27 changes: 27 additions & 0 deletions app/frontend/js/components/LicenseWarnings.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<template>
<div>
<license-warning v-if="license.id === 'pro' && !license.valid"
title="Trial Mode"
message="You are experiencing paid features that need to be licensed before deploying this site. Enjoy!"
icon="exclamation"
/>
<license-warning v-if="license.error"
title="Avo HQ Error"
:message="errorMessage"
icon="exclamation"
/>
</div>
</template>

<script>
export default {
data: () => ({
license: window.license,
}),
computed: {
errorMessage() {
return `${this.license.error}. Checking back every 5 minutes.`
},
},
}
</script>
2 changes: 2 additions & 0 deletions app/frontend/js/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ Vue.component('resources-navigation', require('@/js/components/Re
Vue.component('sidebar-link', require('@/js/components/SidebarLink.vue').default)
Vue.component('application-sidebar', require('@/js/components/ApplicationSidebar.vue').default)
Vue.component('logo-component', require('@/js/components/LogoComponent.vue').default)
Vue.component('license-warnings', require('@/js/components/LicenseWarnings.vue').default)
Vue.component('license-warning', require('@/js/components/LicenseWarning.vue').default)

// Views
Vue.component('resources-index', require('@/js/views/ResourceIndex.vue').default)
Expand Down
7 changes: 6 additions & 1 deletion app/frontend/js/mixins/loads-resource.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ export default {

const { data } = await Api.get(this.resourceUrl)

const resource = this.hydrateRelatedResources(data.resource)
if (!data) return
let { resource } = data

if (!resource) return

resource = this.hydrateRelatedResources(resource)
this.resource = resource
this.isLoading = false
},
Expand Down
2 changes: 1 addition & 1 deletion app/frontend/js/views/ResourceIndex.vue
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ export default {
async getFilters() {
const { data } = await Api.get(`${Avo.rootPath}/avo-api/${this.resourcePath}/filters`)

this.filters = data.filters
if (data && data.filters) this.filters = data.filters
},
changeSortDirection(by) {
if (this.sortBy !== '' && this.sortBy !== by) {
Expand Down
15 changes: 12 additions & 3 deletions app/frontend/js/views/ResourceShow.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div v-if="resource" :resource-id="resourceId">
<div v-for="panel in resource.panels" :key="panel.name">
<div v-for="panel in panels" :key="panel.name">
<panel>
<template #heading>
{{panel.name}}
Expand All @@ -9,7 +9,9 @@
<template #tools>
<div class="flex justify-end space-x-2">
<resource-actions :resource-name="resourceName" :resource-ids="[resourceId]" :actions="actions" />
<a-button :to="cancelActionParams"><arrow-left-icon class="h-4 mr-1"/> Back</a-button>
<a-button :to="cancelActionParams">
<arrow-left-icon class="h-4 mr-1"/> Back
</a-button>
<a-button @click="openDeleteModal"
color="red"
variant="outlined"
Expand All @@ -28,7 +30,9 @@
},
}"
v-if="canEdit"
><edit-icon class="h-4 mr-1" /> Edit</a-button>
>
<edit-icon class="h-4 mr-1" /> Edit
</a-button>
</div>
</template>

Expand Down Expand Up @@ -104,6 +108,11 @@ export default {
fields() {
return this.resource.fields
},
panels() {
if (!this.resource) return []

return this.resource.panels
},
hasManyRelations() {
return this.fields.filter((field) => ['has_and_belongs_to_many', 'has_many'].indexOf(field.relationship) > -1)
},
Expand Down
1 change: 1 addition & 0 deletions app/frontend/svgs/arrow-circle-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/frontend/svgs/exclamation.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/views/layouts/avo/_javascript.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
var rootPath = '<%= Avo.configuration.root_path %>';
var timezone = '<%= Avo.configuration.timezone %>';
var defaultViewType = '<%= Avo.configuration.default_view_type %>';
var license = <%= Avo::App.license.properties.to_json.html_safe %>;
</script>
7 changes: 6 additions & 1 deletion app/views/layouts/avo/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@
>
<div>
<application-sidebar :resources='<%= Avo::App.get_resources_navigation(current_user).as_json.html_safe %>' v-if="layout !== 'blank'">
<%= render_logo %>
<template #logo>
<%= render_logo %>
</template>
<template #licensing>
<license-warnings></license-warnings>
</template>
</application-sidebar>

<div class="flex-1 h-full overflow-auto">
Expand Down
1 change: 1 addition & 0 deletions avo.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ Gem::Specification.new do |spec|
spec.add_dependency 'webpacker'
spec.add_dependency 'countries'
spec.add_dependency 'pundit'
spec.add_dependency 'httparty'
end
File renamed without changes.
3 changes: 2 additions & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ COPY Gemfile* /avo/
COPY Rakefile /avo/
COPY avo.gemspec /avo/
COPY package.json /avo/
COPY ./lib/ /avo/lib/
COPY ./lib/avo.rb /avo/lib/avo.rb
COPY ./lib/avo/version.rb /avo/lib/avo/version.rb
RUN bundle install --jobs 4 --retry 3

COPY yarn.lock /avo/
Expand Down
2 changes: 2 additions & 0 deletions lib/avo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

require_relative 'avo/app/resource'

require_relative 'avo/app/licensing/license_manager'

module Avo
ROOT_PATH = Pathname.new(File.join(__dir__, '..'))

Expand Down
Loading