-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7f5df92
commit f45468b
Showing
11 changed files
with
12,628 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
.DS_Store | ||
node_modules | ||
/dist | ||
|
||
# local env files | ||
.env.local | ||
.env.*.local | ||
|
||
# Log files | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# Editor directories and files | ||
.idea | ||
.vscode | ||
*.suo | ||
*.ntvs* | ||
*.njsproj | ||
*.sln | ||
*.sw* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# cubejs-vue | ||
|
||
## Project setup | ||
``` | ||
yarn install | ||
``` | ||
|
||
### Compiles and hot-reloads for development | ||
``` | ||
yarn run serve | ||
``` | ||
|
||
### Compiles and minifies for production | ||
``` | ||
yarn run build | ||
``` | ||
|
||
### Run your tests | ||
``` | ||
yarn run test | ||
``` | ||
|
||
### Lints and fixes files | ||
``` | ||
yarn run lint | ||
``` | ||
|
||
### Customize configuration | ||
See [Configuration Reference](https://cli.vuejs.org/config/). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module.exports = { | ||
presets: [ | ||
'@vue/app' | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
{ | ||
"name": "@cubejs-client/vue", | ||
"version": "0.1.0", | ||
"description": "Vue.js components for cube.js", | ||
"author": "Ricardo Tapia", | ||
"license": "MIT", | ||
"private": true, | ||
"scripts": { | ||
"serve": "vue-cli-service serve", | ||
"build": "vue-cli-service build", | ||
"lint": "vue-cli-service lint" | ||
}, | ||
"dependencies": { | ||
"core-js": "^2.6.5", | ||
"ramda": "^0.26.1", | ||
"vue": "^2.6.6" | ||
}, | ||
"devDependencies": { | ||
"@vue/cli-plugin-babel": "^3.5.0", | ||
"@vue/cli-plugin-eslint": "^3.5.0", | ||
"@vue/cli-service": "^3.5.0", | ||
"babel-eslint": "^10.0.1", | ||
"eslint": "^5.8.0", | ||
"eslint-plugin-vue": "^5.0.0", | ||
"vue-template-compiler": "^2.5.21" | ||
}, | ||
"eslintConfig": { | ||
"root": true, | ||
"env": { | ||
"node": true | ||
}, | ||
"extends": [ | ||
"plugin:vue/essential", | ||
"eslint:recommended" | ||
], | ||
"rules": {}, | ||
"parserOptions": { | ||
"parser": "babel-eslint" | ||
} | ||
}, | ||
"postcss": { | ||
"plugins": { | ||
"autoprefixer": {} | ||
} | ||
}, | ||
"main": "dist/cubejs-vue.js", | ||
"module": "dist/cubejs-vue.esm.js", | ||
"files": [ | ||
"dist", | ||
"src" | ||
], | ||
"browserslist": [ | ||
"> 1%", | ||
"last 2 versions", | ||
"not ie <= 8" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import Vue from 'vue'; | ||
import QueryRenderer from './QueryRenderer'; | ||
|
||
export default Vue.component('QueryBuilder', { | ||
components: { | ||
QueryRenderer, | ||
}, | ||
props: { | ||
query: { | ||
type: Object, | ||
}, | ||
cubejsApi: { | ||
type: Object, | ||
required: true, | ||
}, | ||
}, | ||
async mounted() { | ||
this.meta = await this.cubejsApi.meta(); | ||
}, | ||
render(createElement) { | ||
const { cubejsApi } = this; | ||
|
||
return createElement(QueryRenderer, { | ||
props: { | ||
query: this.validatedQuery(), | ||
cubejsApi, | ||
}, | ||
// TODO: check passable props | ||
}, this.$scopedSlots.default(this.prepareRenderProps())); | ||
}, | ||
methods: { | ||
isQueryPresent() { | ||
const { query } = this; | ||
|
||
return query.measures && query.measures.length || | ||
query.dimensions && query.dimensions.length || | ||
query.timeDimensions && query.timeDimensions.length; | ||
}, | ||
validatedQuery() { | ||
const { query } = this; | ||
|
||
return { | ||
...query, | ||
filters: (query.filters || []).filter(f => f.operator), | ||
}; | ||
}, | ||
prepareRenderProps(queryRendererProps) { | ||
const getName = member => member.name; | ||
const toTimeDimension = member => ({ | ||
dimension: member.dimension.name, | ||
granularity: member.granularity, | ||
dateRange: member.dateRange, | ||
}); | ||
const toFilter = member => ({ | ||
dimension: member.dimension.name, | ||
operator: member.operator, | ||
values: member.values, | ||
}); | ||
|
||
const updateMethods = (memberType, toQuery = getName) => ({ | ||
add(member) { | ||
this.query = { | ||
...this.query, | ||
[memberType]: (this.query[memberType] || []).concat(toQuery(member)), | ||
}; | ||
}, | ||
remove(member) { | ||
const members = (this.query[memberType] || []).concat([]); | ||
members.splice(member.index, 1); | ||
|
||
// TODO: check return state | ||
this.query = { | ||
...this.query, | ||
[memberType]: members, | ||
}; | ||
}, | ||
update(member, updateWith) { | ||
const members = (this.query[memberType] || []).concat([]); | ||
members.splice(member.index, 1, toQuery(updateWith)); | ||
|
||
// TODO: check return state | ||
this.query = { | ||
...this.query, | ||
[memberType]: members, | ||
}; | ||
}, | ||
}); | ||
|
||
const granularities = [ | ||
{ name: 'hour', title: 'Hour' }, | ||
{ name: 'day', title: 'Day' }, | ||
{ name: 'week', title: 'Week' }, | ||
{ name: 'month', title: 'Month' }, | ||
{ name: 'year', title: 'Year' }, | ||
]; | ||
|
||
return { | ||
meta: this.meta, | ||
query: this.query, | ||
validatedQuery: this.validatedQuery(), | ||
isQueryPresent: this.isQueryPresent(), | ||
chartType: this.chartType, | ||
measures: (this.meta && this.query.measures || []) | ||
.map((m, i) => ({ index: i, ...this.meta.resolveMember(m, 'measures') })), | ||
dimensions: (this.meta && this.query.dimensions || []) | ||
.map((m, i) => ({ index: i, ...this.meta.resolveMember(m, 'dimensions') })), | ||
segments: (this.meta && this.query.segments || []) | ||
.map((m, i) => ({ index: i, ...this.meta.resolveMember(m, 'segments') })), | ||
timeDimensions: (this.meta && this.query.timeDimensions || []) | ||
.map((m, i) => ({ | ||
...m, | ||
dimension: { ...this.meta.resolveMember(m.dimension, 'dimensions'), granularities }, | ||
index: i | ||
})), | ||
filters: (this.meta && this.query.filters || []) | ||
.map((m, i) => ({ | ||
...m, | ||
dimension: this.meta.resolveMember(m.dimension, ['dimensions', 'measures']), | ||
operators: this.meta.filterOperatorsForMember(m.dimension, ['dimensions', 'measures']), | ||
index: i | ||
})), | ||
availableMeasures: this.meta && this.meta.membersForQuery(this.query, 'measures') || [], | ||
availableDimensions: this.meta && this.meta.membersForQuery(this.query, 'dimensions') || [], | ||
availableTimeDimensions: ( | ||
this.meta && this.meta.membersForQuery(this.query, 'dimensions') || [] | ||
).filter(m => m.type === 'time'), | ||
availableSegments: this.meta && this.meta.membersForQuery(this.query, 'segments') || [], | ||
|
||
updateMeasures: updateMethods('measures'), | ||
updateDimensions: updateMethods('dimensions'), | ||
updateSegments: updateMethods('segments'), | ||
updateTimeDimensions: updateMethods('timeDimensions', toTimeDimension), | ||
updateFilters: updateMethods('filters', toFilter), | ||
updateChartType: (chartType) => { this.chartType = chartType; }, | ||
...queryRendererProps, | ||
}; | ||
}, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import Vue from 'vue'; | ||
import { toPairs, fromPairs } from 'ramda'; | ||
|
||
export default Vue.component('QueryRenderer', { | ||
props: { | ||
query: { | ||
type: Object, | ||
default: () => ({}), | ||
}, | ||
queries: { | ||
type: Object, | ||
}, | ||
cubejsApi: { | ||
type: Object, | ||
required: true, | ||
}, | ||
}, | ||
data() { | ||
return { | ||
mutexObj: {}, | ||
error: undefined, | ||
resultSet: undefined, | ||
loadingState: false, | ||
sqlQuery: undefined, | ||
}; | ||
}, | ||
async mounted() { | ||
const { query, queries } = this; | ||
|
||
if (query) { | ||
await this.load(query); | ||
} | ||
|
||
if (queries) { | ||
await this.loadQueries(queries); | ||
} | ||
}, | ||
// TODO: handle update | ||
render(createElement) { | ||
const { resultSet, error, loading, sqlQuery } = this; | ||
|
||
if (this.$slots.default) { | ||
return createElement( | ||
'div', | ||
this.$scopedSlots.default({ | ||
resultSet: this.queries ? (resultSet || {}) : resultSet, | ||
error, | ||
loadingState: { isLoading: loading, }, | ||
sqlQuery, | ||
}), | ||
); | ||
} else { | ||
return null; | ||
} | ||
}, | ||
methods: { | ||
async load(query) { | ||
try { | ||
this.loading = true; | ||
|
||
if (query && Object.keys(query).length) { | ||
if (this.loadSql === 'only') { | ||
this.sqlQuery = await this.cubejsApi.sql(query, { mutexObj: this.mutexObj, mutexKey: 'sql' }); | ||
} else if (this.loadSql) { | ||
this.sqlQuery = await this.cubejsApi.sql(query, { mutexObj: this.mutexObj, mutexKey: 'sql' }); | ||
this.resultSet = await this.cubejsApi.load(query, { mutexObj: this.mutexObj, mutexKey: 'query' }); | ||
} else { | ||
this.resultSet = await this.cubejsApi.load(query, { mutexObj: this.mutexObj, mutexKey: 'query' }); | ||
} | ||
} | ||
|
||
this.loading = false; | ||
} catch (exc) { | ||
this.error = exc; | ||
this.resultSet = undefined; | ||
this.loading = false; | ||
} | ||
}, | ||
async loadQueries(queries) { | ||
try { | ||
this.loading = true; | ||
|
||
const resultPromises = Promise.all(toPairs(queries).map( | ||
([name, query]) => | ||
this.cubejsApi.load(query, { mutexObj: this.mutexObj, mutexKey: name }).then(r => [name, r]) | ||
)); | ||
|
||
this.resultSet = fromPairs(await resultPromises); | ||
this.loading = false; | ||
} catch (exc) { | ||
this.error = exc; | ||
this.loading = false; | ||
} | ||
}, | ||
}, | ||
}); |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import QueryRenderer from './QueryRenderer'; | ||
// import QueryRendererWithTotals from './QueryRendererWithTotals.vue'; | ||
import QueryBuilder from './QueryBuilder'; | ||
|
||
export { QueryRenderer, QueryBuilder }; | ||
|
||
export default {}; |
Oops, something went wrong.