Skip to content

Commit

Permalink
Feature/add resource overview dashboard widget (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianthedev authored Aug 11, 2020
1 parent 1c84f71 commit 99537b2
Show file tree
Hide file tree
Showing 10 changed files with 252 additions and 17 deletions.
21 changes: 21 additions & 0 deletions app/controllers/avo/resource_overview_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require_dependency 'avo/application_controller'

module Avo
class ResourceOverviewController < ApplicationController
def index
resources = App.get_resources.map do |resource|
{
name: resource.name,
url: resource.url,
count: resource.model.count,
}
end

render json: {
resources: resources,
hidden: Avo.configuration.hide_resource_overview_component,
hide_docs: Avo.configuration.hide_documentation_link,
}
end
end
end
2 changes: 1 addition & 1 deletion app/frontend/js/components/LoadingOverlay.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="absolute flex items-center justify-center h-full w-full bg-white bg-opacity-75 z-20">
<div class="absolute flex items-center justify-center h-full w-full bg-white bg-opacity-75 z-20 rounded-xl">
<loading-component class="bg-white rounded bg-opacity-75"/>
</div>
</template>
5 changes: 5 additions & 0 deletions app/frontend/js/components/Pane.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<div class="relative bg-white rounded-xl shadow-xl mb-8">
<slot />
</div>
</template>
88 changes: 88 additions & 0 deletions app/frontend/js/components/ResourceOverview.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<template>
<div v-if="!hidden">
<div v-if="noResources">
<pane class="p-6">
<heading class="mb-4">
Welcome to Avo 🥑
</heading>

<p class="mb-2">
You haven't generated any Resources. <strong>Resources</strong> are the backbone of Avo.
</p>

<p class="mb-2">
To generate a resource run this command.
</p>

<div class="mb-2 mt-4">
<code class="block bg-gray-200 px-3 py-2 rounded text-gray-800">bin/rails generate avo:resource Post</code>
</div>
</pane>
</div>
<div v-else>
<div class="mb-4 text-lg font-bold">
Current resources
</div>
<div class="grid grid-cols-3 col-gap-6">
<div v-for="resource in resources" :key="resource.name">
<pane class="p-6">
<div class="font-semibold leading-tight mb-2 text-lg">
{{resource.count}} {{resource.name | pluralize(resource.count) | capitalize()}}
</div>
<div class="flex justify-end">
<router-link :to="{
name: 'index',
params: {
resourceName: resource.url,
},
}"
>view all</router-link>
</div>
</pane>
</div>
</div>
</div>
<pane class="p-6" v-if="!hideDocs">
Read the <a href="https://docs.avohq.io" target="_blank">docs</a> for options on how to customize resources.
</pane>
</div>
</template>

<script>
import Api from '@/js/Api'
import Avo from '@/js/Avo'
import pluralize from 'pluralize'
export default {
data: () => ({
resources: [],
hidden: true,
hideDocs: false,
}),
props: [],
filters: {
pluralize(value, count) {
return pluralize(value, count)
},
capitalize(value) {
return value.charAt(0).toUpperCase() + value.slice(1)
},
},
computed: {
noResources() {
return this.resources.length === 0
},
},
methods: {
async getResources() {
const { data } = await Api.get(`${Avo.rootPath}/avo-tools/resource-overview`)
this.resources = data.resources
this.hidden = data.hidden
this.hideDocs = data.hide_docs
},
},
async mounted() {
await this.getResources()
},
}
</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 @@ -91,6 +91,8 @@ Vue.component('item-controls', require('@/js/components/In
Vue.component('view-header', require('@/js/components/ViewHeader.vue').default)
Vue.component('view-footer', require('@/js/components/ViewFooter.vue').default)
Vue.component('panel', require('@/js/components/Panel.vue').default)
Vue.component('pane', require('@/js/components/Pane.vue').default)
Vue.component('resource-overview', require('@/js/components/ResourceOverview.vue').default)
Vue.component('heading', require('@/js/components/Heading.vue').default)
Vue.component('a-button', require('@/js/components/Button.vue').default)
Vue.component('resources-search', require('@/js/components/ResourcesSearch.vue').default)
Expand Down
9 changes: 6 additions & 3 deletions app/frontend/js/views/Dashboard.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<template>
<heading>
Dashboard
</heading>
<div>
<heading class="pt-4 mb-8">
Dashboard
</heading>
<resource-overview />
</div>
</template>
4 changes: 4 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,9 @@
post '/avo-api/:resource_name/:id/attach/:attachment_name/:attachment_id', to: 'resources#attach'
post '/avo-api/:resource_name/:id/detach/:attachment_name/:attachment_id', to: 'resources#detach'

# Tools
get '/avo-tools/resource-overview', to: 'resource_overview#index'

# Catch them all
get '/:view/(:tool)/(:resource_name)/(:option)', to: 'home#index'
end
4 changes: 4 additions & 0 deletions lib/avo/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class Configuration
attr_accessor :locale
attr_accessor :currency
attr_accessor :default_view_type
attr_accessor :hide_resource_overview_component
attr_accessor :hide_documentation_link

def initialize
@root_path = '/avo'
Expand All @@ -18,6 +20,8 @@ def initialize
@locale = 'us-US'
@currency = 'USD'
@default_view_type = :table
@hide_resource_overview_component = false
@hide_documentation_link = false
end
end

Expand Down
16 changes: 3 additions & 13 deletions scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,6 @@

set -e

IMAGE_NAME=avo-dev
WORKSPACE_DIR=$1 BUMP=${1:-'patch'}
TAG=$2
OS=$(node -r os -e 'console.log(os.platform())')

cd $WORKSPACE_DIR

docker build -t $IMAGE_NAME -f docker/Dockerfile .

CID=$(docker create $IMAGE_NAME)

docker cp ${CID}:/avo/pkg/. $WORKSPACE_DIR/pkg
docker rm ${CID}
rm -rf public/avo-packs
bin/webpack
gem build avo --output pkg/avo.gem
118 changes: 118 additions & 0 deletions spec/requests/avo/resource_overview_request_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
require 'rails_helper'

RSpec.describe 'ResourceOverview', type: :request do
context 'configs' do
describe 'with false values' do
it 'returns false values' do
get '/avo/avo-tools/resource-overview'

expect(response).to have_http_status(200)

expect(parsed_response['hidden']).to be false
expect(parsed_response['hide_docs']).to be false
end
end

describe 'with true values' do
around do |spec|
Avo.configuration.hide_resource_overview_component = true
Avo.configuration.hide_documentation_link = true

spec.run

Avo.configuration.hide_resource_overview_component = false
Avo.configuration.hide_documentation_link = false
end

it 'returns true values' do
get '/avo/avo-tools/resource-overview'

expect(response).to have_http_status(200)

expect(parsed_response['hidden']).to be true
expect(parsed_response['hide_docs']).to be true
end
end
end

describe 'without any resources in the DB' do
it 'returns empty response' do
get '/avo/avo-tools/resource-overview'

expect(response).to have_http_status(200)

expect(parsed_response['hidden']).to be false
expect(parsed_response['hide_docs']).to be false
expect(parsed_response['resources']).to match_array([
{
count: 0,
name: 'Team',
url: 'teams',
},
{
count: 0,
name: 'Project',
url: 'projects',
},
{
count: 0,
name: 'Post',
url: 'posts',
},
{
count: 0,
name: 'Team Membership',
url: 'team_memberships',
},
{
count: 0,
name: 'User',
url: 'users',
},
].map(&:deep_stringify_keys))
end
end

describe 'with some resources in the DB' do
before do
create_list :user, 3
create_list :team, 2
end

it 'returns non-empty response' do
get '/avo/avo-tools/resource-overview'

expect(response).to have_http_status(200)

expect(parsed_response['hidden']).to be false
expect(parsed_response['hide_docs']).to be false
expect(parsed_response['resources']).to match_array([
{
count: 2,
name: 'Team',
url: 'teams',
},
{
count: 0,
name: 'Project',
url: 'projects',
},
{
count: 0,
name: 'Post',
url: 'posts',
},
{
count: 0,
name: 'Team Membership',
url: 'team_memberships',
},
{
count: 3,
name: 'User',
url: 'users',
},
].map(&:deep_stringify_keys))
end
end
end

0 comments on commit 99537b2

Please sign in to comment.