Merge branch 'simplify'

This commit is contained in:
Oliver Davies 2019-06-27 19:06:11 +01:00
commit 38492073f7
14 changed files with 83 additions and 392 deletions

View file

@ -1,9 +1,22 @@
<template> <template>
<div id="app" class="min-h-screen antialiased bg-gray-200 font-sans flex flex-col flex-1"> <div id="app" class="min-h-screen antialiased bg-gray-200 font-sans flex flex-col flex-1">
<div class="flex flex-col flex-1"> <div class="flex flex-col flex-1">
<router-view class="flex flex-col flex-1"></router-view> <router-view :applications="applications" :types="types" class="flex flex-col flex-1"/>
</div> </div>
</div> </div>
</template> </template>
<style src="./assets/css/tailwind.css"/> <style src="./assets/css/tailwind.css"/>
<script>
import { applications, types } from '@/data'
export default {
data () {
return {
applications,
types
}
}
}
</script>

View file

@ -1,40 +0,0 @@
import _ from 'lodash'
let data = require('./data').default
export default {
methods: {
setData (newData) {
data = newData
},
getData () {
return data
},
getTypes () {
return data.types
},
getApplications () {
return data.applications
},
getApplication (applicationId) {
return _(data.applications).get(applicationId)
},
getEnvironment (applicationId, environment) {
return _(this.getApplication(applicationId))
.get('environments')[environment]
},
getApplicationType (application) {
return this.getTypes()[application.type]
},
getVersion (type, environment) {
return _(environment).get(`versions.${type}`)
}
}
}

View file

@ -9,7 +9,7 @@
</div> </div>
<div class="truncate text-blue-300"> <div class="truncate text-blue-300">
<a href="#0" class="text-inherit no-underline hover:underline focus:underline focus:outline-none">{{ application.environments['prod'].url }}</a> <a href="#0" class="text-inherit no-underline hover:underline focus:underline focus:outline-none" v-text="prodUrl"/>
</div> </div>
</div> </div>
@ -27,20 +27,22 @@
<div class="flex flex-row-reverse items-center justify-between"> <div class="flex flex-row-reverse items-center justify-between">
<div class="flex flex-1 justify-between items-center -mx-2"> <div class="flex flex-1 justify-between items-center -mx-2">
<div class="flex-1 px-2"> <div class="flex-1 px-2">
<router-link :to="{name: 'environments', params: {id: id}}" class="text-blue-300 no-underline hover:underline focus:underline"><h2 class="text-base font-normal mb-1">{{ application.name }}</h2></router-link> <router-link :to="{name: 'environments', params: { id }}" class="text-blue-300 no-underline hover:underline focus:underline">
<h2 class="text-base font-normal mb-1">{{ application.name }}</h2>
</router-link>
</div> </div>
<div class="w-2/5 px-2"> <div class="w-2/5 px-2">
<a href="#0" class="text-blue-300 no-underline hover:underline focus:underline">{{ application.environments['prod'].url }}</a> <a href="#0" class="text-blue-300 no-underline hover:underline focus:underline" v-text="prodUrl"/>
</div> </div>
<div class="w-1/5 px-2"> <div class="w-1/5 px-2">
<php-version :application="application"></php-version> <php-version :application="application"/>
</div> </div>
</div> </div>
<div class="px-2"> <div class="px-2">
<star-toggle :application="application" :starred="starred" @toggle="starred = !starred"></star-toggle> <star-toggle :application="application" :starred="starred" @toggle="starred = !starred"/>
</div> </div>
</div> </div>
</div> </div>
@ -49,17 +51,11 @@
</template> </template>
<script> <script>
import ApiClient from '@/api-client.js'
import PhpVersion from '@/components/Application/PhpVersion' import PhpVersion from '@/components/Application/PhpVersion'
import StarToggle from '@/components/Application/StarToggle' import StarToggle from '@/components/Application/StarToggle'
export default { export default {
mixins: [ApiClient], components: { PhpVersion, StarToggle },
components: {
PhpVersion,
StarToggle
},
props: { props: {
application: Object, application: Object,
@ -71,6 +67,12 @@ export default {
return { return {
starred: false starred: false
} }
},
computed: {
prodUrl () {
return this.application.environments['prod'].url
}
} }
} }
</script> </script>

View file

@ -1,8 +1,8 @@
<template> <template>
<div> <div>
<ul class="list-reset flex flex-wrap -mr-2 -mb-2"> <ul class="list-reset flex flex-wrap -mr-2 -mb-2">
<li class="tag" :data-type="type.id">{{ type.name }}</li> <li class="mr-2 mb-2 py-1 px-2 text-2xs rounded uppercase border" :class="typeClasses" v-text="applicationTypeName"/>
<li class="tag">{{ level }}</li> <li class="mr-2 mb-2 py-1 px-2 text-2xs rounded uppercase border border-gray-400 bg-white">{{ application.level }}</li>
</ul> </ul>
</div> </div>
</template> </template>
@ -10,22 +10,21 @@
<script> <script>
export default { export default {
props: { props: {
level: String, application: Object
type: Object },
computed: {
applicationTypeName () {
return this.$attrs.types[this.application.type].name
},
typeClasses() {
return {
'': 'bg-white border-gray-400',
drupal: 'bg-blue-100 border-blue-100 text-white',
nodejs: 'bg-green border-green text-white'
}[this.application.type]
}
} }
} }
</script> </script>
<style scoped>
.tag {
@apply text-2xs py-1 px-2 rounded uppercase border border-gray-400 bg-white mr-2 mb-2
}
.tag[data-type="drupal"] {
@apply bg-blue-100 border-blue-100 text-white
}
.tag[data-type="nodejs"] {
@apply bg-green border-green text-white
}
</style>

View file

@ -6,11 +6,7 @@
</template> </template>
<script> <script>
import ApiClient from '@/api-client.js'
export default { export default {
mixins: [ApiClient],
props: { props: {
application: Object application: Object
}, },
@ -21,7 +17,7 @@ export default {
return null return null
} }
return this.getVersion('php', this.getEnvironment(this.application.id, 'prod')) return this.application.environments['prod'].versions['php']
} }
} }
} }

View file

@ -7,18 +7,18 @@
</ul> </ul>
<div class="flex flex-wrap -mx-4 -mb-4"> <div class="flex flex-wrap -mx-4 -mb-4">
<div class="wrapper" :class="[ active == 'code' ? 'block' : 'hidden' ]"> <div class="px-4 mb-4 w-full md:block md:w-1/3" :class="[ active == 'code' ? 'block' : 'hidden' ]">
<action-card title="Code" :description="`${ environment.name }: ${environment.label}`"> <action-card title="Code" :description="`${ environment.name }: ${environment.label}`">
<svg slot="icon" role="presentation"><use xlink:href="/img/icons.symbol.svg#objects__code"></use></svg> <svg slot="icon" role="presentation"><use xlink:href="/img/icons.symbol.svg#objects__code"></use></svg>
<ul slot="buttons" class="button-list"> <ul slot="buttons" class="-ml-px flex">
<li class="button-list-item"> <li class="w-1/2 flex-1 text-center border-l border-gray-400">
<action-card-button label="Deploy"> <action-card-button label="Deploy">
<svg role="presentation"><use xlink:href="/img/icons.symbol.svg#objects__fork"></use></svg> <svg role="presentation"><use xlink:href="/img/icons.symbol.svg#objects__fork"></use></svg>
</action-card-button> </action-card-button>
</li> </li>
<li class="button-list-item"> <li class="w-1/2 flex-1 text-center border-l border-gray-400">
<action-card-button label="Switch"> <action-card-button label="Switch">
<svg role="presentation"><use xlink:href="/img/icons.symbol.svg#actions__switch"></use></svg> <svg role="presentation"><use xlink:href="/img/icons.symbol.svg#actions__switch"></use></svg>
</action-card-button> </action-card-button>
@ -27,24 +27,24 @@
</action-card> </action-card>
</div> </div>
<div class="wrapper" :class="[ active == 'databases' ? 'block' : 'hidden' ]"> <div class="px-4 mb-4 w-full md:block md:w-1/3" :class="[ active == 'databases' ? 'block' : 'hidden' ]">
<action-card title="Databases" :description="environment.name"> <action-card title="Databases" :description="environment.name">
<svg slot="icon" role="presentation"><use xlink:href="/img/icons.symbol.svg#objects__database"></use></svg> <svg slot="icon" role="presentation"><use xlink:href="/img/icons.symbol.svg#objects__database"></use></svg>
<ul slot="buttons" class="button-list"> <ul slot="buttons" class="-ml-px flex">
<li class="button-list-item"> <li class="w-1/2 flex-1 text-center border-l border-gray-400">
<action-card-button label="Copy"> <action-card-button label="Copy">
<svg role="presentation"><use xlink:href="/img/icons.symbol.svg#actions__copy"></use></svg> <svg role="presentation"><use xlink:href="/img/icons.symbol.svg#actions__copy"></use></svg>
</action-card-button> </action-card-button>
</li> </li>
<li class="button-list-item"> <li class="w-1/2 flex-1 text-center border-l border-gray-400">
<action-card-button label="Back up"> <action-card-button label="Back up">
<svg role="presentation"><use xlink:href="/img/icons.symbol.svg#actions__backup"></use></svg> <svg role="presentation"><use xlink:href="/img/icons.symbol.svg#actions__backup"></use></svg>
</action-card-button> </action-card-button>
</li> </li>
<li class="button-list-item"> <li class="w-1/2 flex-1 text-center border-l border-gray-400">
<action-card-button label="Restore" :disabled="isProduction" :class="{ <action-card-button label="Restore" :disabled="isProduction" :class="{
'text-blue-300': !isProduction, 'text-blue-300': !isProduction,
'text-gray-500 cursor-not-allowed': isProduction 'text-gray-500 cursor-not-allowed': isProduction
@ -56,12 +56,12 @@
</action-card> </action-card>
</div> </div>
<div class="wrapper" :class="[ active == 'files' ? 'block' : 'hidden' ]"> <div class="px-4 mb-4 w-full md:block md:w-1/3" :class="[ active == 'files' ? 'block' : 'hidden' ]">
<action-card title="Files" :description="environment.name"> <action-card title="Files" :description="environment.name">
<svg slot="icon" class="h-8 w-8 fill-current text-teal" role="presentation"><use xlink:href="/img/icons.symbol.svg#objects__environment"></use></svg> <svg slot="icon" class="h-8 w-8 fill-current text-teal" role="presentation"><use xlink:href="/img/icons.symbol.svg#objects__environment"></use></svg>
<ul slot="buttons" class="button-list"> <ul slot="buttons" class="-ml-px flex">
<li class="button-list-item"> <li class="w-1/2 flex-1 text-center border-l border-gray-400">
<action-card-button label="Copy"> <action-card-button label="Copy">
<svg role="presentation"><use xlink:href="/img/icons.symbol.svg#actions__copy"></use></svg> <svg role="presentation"><use xlink:href="/img/icons.symbol.svg#actions__copy"></use></svg>
</action-card-button> </action-card-button>
@ -95,21 +95,3 @@ export default {
} }
} }
</script> </script>
<style scoped>
.wrapper {
@apply w-full px-4 mb-4;
@screen md {
@apply w-1/3 block
}
}
.button-list {
@apply flex -ml-px
}
.button-list-item {
@apply w-1/2 flex-1 text-center border-l border-gray-400
}
</style>

View file

@ -1,7 +1,7 @@
<template> <template>
<div class="mb-6"> <div class="mb-6">
<div class="flex flex-wrap -mx-4 -mb-6"> <div class="flex flex-wrap -mx-4 -mb-6">
<div v-for="(environment, key) in environments" class="w-full md:w-1/2 xl:w-1/3 px-4 mb-6" :key="key"> <div v-for="(environment, key) in application.environments" class="w-full md:w-1/2 xl:w-1/3 px-4 mb-6" :key="key">
<div class="border border-gray-400 rounded overflow-hidden shadow"> <div class="border border-gray-400 rounded overflow-hidden shadow">
<div class="bg-white"> <div class="bg-white">
<div class="border-t-4 border-teal p-3"> <div class="border-t-4 border-teal p-3">
@ -51,7 +51,7 @@
<script> <script>
export default { export default {
props: { props: {
environments: Object, application: Object,
id: String id: String
} }
} }

View file

@ -1,4 +1,4 @@
export default { module.exports = {
types: { types: {
drupal: { drupal: {
id: 'drupal', id: 'drupal',

View file

@ -59,12 +59,20 @@
<script> <script>
import sortBy from 'lodash/sortBy' import sortBy from 'lodash/sortBy'
import ApiClient from '@/api-client.js'
import ApplicationCard from '@/components/Application/ApplicationCard' import ApplicationCard from '@/components/Application/ApplicationCard'
import ApplicationDisplaySwitcher from '@/components/Application/ApplicationDisplaySwitcher' import ApplicationDisplaySwitcher from '@/components/Application/ApplicationDisplaySwitcher'
export default { export default {
mixins: [ApiClient], props: {
applications: {
type: Array,
required: true
},
types: {
type: Object,
required: true
}
},
components: { components: {
ApplicationCard, ApplicationCard,
@ -73,7 +81,6 @@ export default {
data () { data () {
return { return {
applications: this.getApplications(),
display: 'grid' display: 'grid'
} }
}, },

View file

@ -23,7 +23,7 @@
<div> <div>
<h1 class="text-4xl font-thin mb-2">Overview</h1> <h1 class="text-4xl font-thin mb-2">Overview</h1>
<application-tags :type="getApplicationType(application)" :level="application.level"></application-tags> <application-tags :application="application" :types="$attrs.types"/>
</div> </div>
<div class="my-10"> <div class="my-10">
@ -132,11 +132,13 @@
<script> <script>
import ActionCards from '@/components/Environment/ActionCards' import ActionCards from '@/components/Environment/ActionCards'
import ApiClient from '@/api-client.js'
import ApplicationTags from '@/components/Application/ApplicationTags' import ApplicationTags from '@/components/Application/ApplicationTags'
export default { export default {
mixins: [ApiClient], mounted () {
// console.log(this.$attrs)
// console.log(this.$props)
},
components: { components: {
ActionCards, ActionCards,
@ -150,11 +152,11 @@ export default {
computed: { computed: {
application: function () { application: function () {
return this.getApplication(this.id) return this.$attrs.applications[this.id]
}, },
environment: function () { environment: function () {
return this.getEnvironment(this.id, this.environmentName) return this.application.environments[this.environmentName]
}, },
gitUrl: function () { gitUrl: function () {
@ -170,7 +172,7 @@ export default {
}, },
phpVersion: function () { phpVersion: function () {
return this.getVersion('php', this.environment) return this.environment.versions.php
} }
} }
} }

View file

@ -31,7 +31,7 @@
<div class="mr-16 mb-4 lg:mb-0"> <div class="mr-16 mb-4 lg:mb-0">
<h1 class="text-4xl font-thin mb-2">Environments</h1> <h1 class="text-4xl font-thin mb-2">Environments</h1>
<application-tags :type="getApplicationType(application)" :level="application.level"></application-tags> <application-tags :application="application" :types="$attrs.types"/>
</div> </div>
<div class="lg:flex lg:flex-row-reverse flex-1 justify-between _bg-blue items-baseline"> <div class="lg:flex lg:flex-row-reverse flex-1 justify-between _bg-blue items-baseline">
@ -49,7 +49,7 @@
</div> </div>
<quick-help :hidden="help.hidden"></quick-help> <quick-help :hidden="help.hidden"></quick-help>
<environment-cards :environments="application.environments" :id="id"></environment-cards> <environment-cards :application="application" :id="id"/>
<task-log :tasks="application.tasks" v-if="application.tasks[0]"></task-log> <task-log :tasks="application.tasks" v-if="application.tasks[0]"></task-log>
</div> </div>
@ -65,7 +65,6 @@
</template> </template>
<script> <script>
import ApiClient from '@/api-client.js'
import ApplicationTags from '@/components/Application/ApplicationTags' import ApplicationTags from '@/components/Application/ApplicationTags'
import EnvironmentCards from '@/components/Environment/EnvironmentCards' import EnvironmentCards from '@/components/Environment/EnvironmentCards'
import QuickHelp from '@/components/Environment/QuickHelp' import QuickHelp from '@/components/Environment/QuickHelp'
@ -73,8 +72,6 @@ import TaskLog from '@/components/Environment/TaskLog/TaskLog'
import ToggleHelp from '@/components/Environment/ToggleHelp' import ToggleHelp from '@/components/Environment/ToggleHelp'
export default { export default {
mixins: [ApiClient],
components: { components: {
ApplicationTags, ApplicationTags,
EnvironmentCards, EnvironmentCards,
@ -96,8 +93,8 @@ export default {
}, },
computed: { computed: {
application: function () { application () {
return this.getApplication(this.id) return this.$attrs.applications[this.id]
} }
} }
} }

View file

@ -1,5 +0,0 @@
module.exports = {
env: {
jest: true
}
}

View file

@ -1,215 +0,0 @@
import _ from 'lodash'
const apiClient = require('../../src/api-client')
const methods = apiClient.default.methods
test('it can get the application types', () => {
const data = {
types: {
drupal: {
id: 'drupal',
name: 'Drupal'
},
symfony: {
id: 'symfony',
name: 'Symfony'
}
}
}
methods.setData(data)
expect(methods.getTypes()).toBe(data.types)
})
test('it can get the applications', () => {
const data = {
applications: {
1: {
id: 1,
name: 'Rebuilding Acquia',
machineName: 'rebuildingacquia',
type: 'drupal',
level: 'Enterprise',
environments: {},
tasks: {}
},
2: {
id: 2,
name: 'Oliver Davies',
machineName: 'oliverdavies',
type: 'drupal',
level: 'Professional',
environments: {},
tasks: {}
}
}
}
methods.setData(data)
expect(methods.getApplications()).toBe(data.applications)
})
test('it can get a single application', () => {
const data = {
applications: {
1: {
id: 1,
name: 'Rebuilding Acquia',
machineName: 'rebuildingacquia',
type: 'drupal',
level: 'Enterprise',
environments: {},
tasks: {}
},
2: {
id: 2,
name: 'Oliver Davies',
machineName: 'oliverdavies',
type: 'drupal',
level: 'Professional',
environments: {},
tasks: {}
}
}
}
methods.setData(data)
_.forEach([1, 2], (applicationId) => {
expect(methods.getApplication(applicationId))
.toBe(data.applications[applicationId])
})
})
test('it can get an environment for an application', () => {
const data = {
applications: {
1: {
id: 1,
name: 'Rebuilding Acquia',
machineName: 'rebuildingacquia',
type: 'drupal',
level: 'Enterprise',
environments: {
dev: {
name: 'Dev',
url: 'dev.oliverdavies.uk',
label: 'develop',
versions: {
php: '7.2'
}
},
stage: {
name: 'Stage',
url: 'stg.oliverdavies.uk',
label: 'master',
versions: {
php: '7.2'
}
},
prod: {
name: 'Prod',
url: 'oliverdavies.uk',
label: 'tags/2018-12-21',
versions: {
php: '7.2'
}
},
tasks: {}
}
}
}
}
methods.setData(data)
_.forEach(['dev', 'stage', 'prod'], (environmentName) => {
expect(methods.getEnvironment(1, environmentName))
.toBe(data.applications[1].environments[environmentName])
})
})
test('it can get the type of an application', () => {
const data = {
types: {
drupal: {
id: 'drupal',
name: 'Drupal'
},
symfony: {
id: 'symfony',
name: 'Symfony'
}
}
}
methods.setData(data)
const applications = {
drupal: {
type: 'drupal'
},
symfony: {
type: 'symfony'
}
}
_.forEach(applications, (application, expected) => {
expect(methods.getApplicationType(application)).toBe(data.types[expected])
})
})
test('it can get a version from an environment', () => {
const data = {
applications: {
1: {
id: 1,
name: 'Rebuilding Acquia',
machineName: 'rebuildingacquia',
type: 'drupal',
level: 'Enterprise',
environments: {
dev: {
name: 'Dev',
url: 'dev.rebuilding-acquia.com',
label: 'develop',
versions: {
php: '5.6'
}
},
stage: {
name: 'Stage',
url: 'stg.rebuilding-acquia.com',
label: 'master',
versions: {
php: '7.1'
}
},
prod: {
name: 'Prod',
url: 'rebuilding-acquia.com',
label: 'tags/2018-12-21',
versions: {
php: '7.2'
}
}
}
}
}
}
methods.setData(data)
const expected = {
dev: '5.6',
stage: '7.1',
prod: '7.2'
}
_.forEach(expected, (version, environment) => {
expect(methods.getVersion('php', data.applications[1].environments[environment]))
.toBe(version)
})
})

View file

@ -1,47 +0,0 @@
import AppBreadcrumb from '@/components/AppBreadcrumb.vue'
import { RouterLinkStub, shallowMount } from '@vue/test-utils'
const stubs = {
RouterLink: RouterLinkStub
}
test('it returns default values', () => {
const wrapper = shallowMount(AppBreadcrumb, { stubs })
expect(wrapper.vm.selectedOrganisation).toBe(null)
expect(wrapper.vm.selectedApplication).toBe(null)
expect(wrapper.vm.selectedEnvironment).toBe(null)
})
test('it returns the organisation and application names', () => {
const wrapper = shallowMount(AppBreadcrumb, {
propsData: {
application: {
name: 'Oliver Davies'
}
},
stubs
})
expect(wrapper.vm.selectedOrganisation).toBe('Rebuilding Acquia')
expect(wrapper.vm.selectedApplication).toBe('Oliver Davies')
expect(wrapper.vm.selectedEnvironment).toBe(null)
})
test('it returns the environment name', () => {
const wrapper = shallowMount(AppBreadcrumb, {
propsData: {
application: {
name: 'Oliver Davies'
},
environment: {
name: 'Dev'
}
},
stubs
})
expect(wrapper.vm.selectedOrganisation).toBe('Rebuilding Acquia')
expect(wrapper.vm.selectedApplication).toBe('Oliver Davies')
expect(wrapper.vm.selectedEnvironment).toBe('Dev')
})