mirror of https://github.com/nocodb/nocodb
github-actions[bot]
3 years ago
committed by
GitHub
423 changed files with 65342 additions and 6756 deletions
@ -0,0 +1,15 @@
|
||||
<component name="ProjectRunConfigurationManager"> |
||||
<configuration default="false" name="Run NocoDB Sqlite" type="js.build_tools.npm" activateToolWindowBeforeRun="false"> |
||||
<package-json value="$PROJECT_DIR$/packages/nocodb/package.json" /> |
||||
<command value="run" /> |
||||
<scripts> |
||||
<script value="watch:run" /> |
||||
</scripts> |
||||
<node-interpreter value="project" /> |
||||
<envs> |
||||
<env name="NC_DISABLE_CACHE1" value="true" /> |
||||
<env name="NC_DISABLE_TELE" value="true" /> |
||||
</envs> |
||||
<method v="2" /> |
||||
</configuration> |
||||
</component> |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,6 +0,0 @@
|
||||
# COMPONENTS |
||||
|
||||
The components directory contains your Vue.js Components. |
||||
Nuxt.js doesn't supercharge these components. |
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.** |
@ -1,86 +0,0 @@
|
||||
const authorizedRoutes = {} |
||||
|
||||
authorizedRoutes['/user/settings'] = true |
||||
authorizedRoutes['/user/settings/accounts'] = true |
||||
authorizedRoutes['/user/settings/password'] = true |
||||
authorizedRoutes['/referral'] = true |
||||
|
||||
authorizedRoutes['/realestate/profits'] = true |
||||
authorizedRoutes['/realestate/bygeo'] = true |
||||
authorizedRoutes['/payment/buy'] = true |
||||
|
||||
authorizedRoutes['/pricing'] = false |
||||
authorizedRoutes['/user'] = true |
||||
|
||||
authorizedRoutes['/user/authentication'] = true |
||||
authorizedRoutes['/user/password'] = true |
||||
|
||||
authorizedRoutes['/error/400'] = false |
||||
authorizedRoutes['/realestate/capitalgains'] = true |
||||
authorizedRoutes['/payment/train'] = true |
||||
authorizedRoutes['/user/settings'] = true |
||||
|
||||
authorizedRoutes['/info/contact'] = false |
||||
authorizedRoutes['/profits'] = false |
||||
authorizedRoutes['/user/admin'] = true |
||||
authorizedRoutes['/error/403'] = false |
||||
authorizedRoutes['/error/404'] = false |
||||
|
||||
authorizedRoutes['/info/hiring'] = false |
||||
authorizedRoutes['/user/settings/accounts'] = true |
||||
authorizedRoutes['/user/password/reset'] = false |
||||
authorizedRoutes['/user/settings/profile'] = true |
||||
authorizedRoutes['/user/settings/picture'] = true |
||||
authorizedRoutes['/user/password/forgot'] = false |
||||
authorizedRoutes['/user/authentication/signup'] = false |
||||
authorizedRoutes['/user/settings/password'] = true |
||||
authorizedRoutes['/user/admin/user-edit'] = true |
||||
authorizedRoutes['/user/authentication/signin'] = false |
||||
authorizedRoutes['/user/password/reset/success'] = true |
||||
authorizedRoutes['/user/password/reset/invalid'] = true |
||||
authorizedRoutes['/user/password/reset/form'] = true |
||||
// // authorizedRoutes['/user/admin/user/_userId'] = true;
|
||||
// // authorizedRoutes['/'] = false;
|
||||
|
||||
// authorizedRoutes['/realestate/profits'] = true;
|
||||
|
||||
// let freeRoutes = {};
|
||||
// freeRoutes['/'] = true;
|
||||
// freeRoutes['/pricing'] = true;
|
||||
// freeRoutes['user/authentication/signin'] = true;
|
||||
// freeRoutes['user/authentication/signup'] = true;
|
||||
|
||||
exports.allowed = function(store, path) { |
||||
// console.log('store.getters.GtrUser',store.getters.GtrUser);
|
||||
// console.log('path',path);
|
||||
|
||||
// && authorizedRoutes[path]
|
||||
|
||||
if (store.getters.GtrUser === null && path in authorizedRoutes && authorizedRoutes[path]) { |
||||
return false |
||||
} else { |
||||
return true |
||||
} |
||||
} |
||||
/** |
||||
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||
* |
||||
* @author Naveen MR <oof1lab@gmail.com> |
||||
* @author Pranav C Balan <pranavxc@gmail.com> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* |
||||
*/ |
@ -0,0 +1,67 @@
|
||||
<template> |
||||
<div class="nc-container" :class="{active:modal}" @click="modal=false"> |
||||
<div class="nc-content elevation-3 pa-4" @click.stop> |
||||
<slot /> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
|
||||
export default { |
||||
name: 'NcSlider', |
||||
props: { |
||||
value: Boolean |
||||
}, |
||||
computed: { |
||||
modal: { |
||||
get() { |
||||
return this.value |
||||
}, |
||||
set(v) { |
||||
this.$emit('input', v) |
||||
} |
||||
} |
||||
}, |
||||
mounted() { |
||||
(document.querySelector('[data-app]') || this.$root.$el).append(this.$el) |
||||
}, |
||||
|
||||
destroyed() { |
||||
this.$el.parentNode && this.$el.parentNode.removeChild(this.$el) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped lang="scss"> |
||||
|
||||
.nc-container { |
||||
position: fixed; |
||||
pointer-events: none; |
||||
width: 100vw; |
||||
height: 100vh; |
||||
z-index: 9999; |
||||
right: 0; |
||||
top: 0; |
||||
|
||||
.nc-content { |
||||
background-color: var(--v-backgroundColorDefault-base); |
||||
height: 100%; |
||||
width: max(50%, 700px); |
||||
position: absolute; |
||||
bottom: 0; |
||||
top: 0; |
||||
right: min(-50%, -700px); |
||||
transition: .3s right; |
||||
overflow-y: auto; |
||||
} |
||||
|
||||
&.active { |
||||
pointer-events: all; |
||||
|
||||
& > .nc-content { |
||||
right: 0 |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,315 @@
|
||||
<template> |
||||
<v-dialog v-model="airtableModal" max-width="min(600px, 90%)"> |
||||
<v-card class="nc-import-card h-100"> |
||||
<v-toolbar class="elevation-0 align-center" height="68"> |
||||
<h3 class="mt-2"> |
||||
{{ $t('title.importFromAirtable') }} |
||||
</h3> |
||||
<div v-t="['c:airtable-import:turbo-mode']" class="ml-2 mt-3 title pointer nc-btn-enable-turbo" @click="enableTurbo"> |
||||
🚀 |
||||
</div> |
||||
<v-spacer /> |
||||
</v-toolbar> |
||||
|
||||
<v-divider /> |
||||
<div class="h-100" style="width: 100%"> |
||||
<div> |
||||
<v-card |
||||
:class="{'pb-4 mt-4' : step === 2, 'py-6': step === 1}" |
||||
class=" elevation-0" |
||||
min-height="500" |
||||
> |
||||
<template v-if="step === 1"> |
||||
<div class="d-flex flex-column justify-center align-center pt-2 pb-6"> |
||||
<span class="subtitle-1 font-weight-medium" @dblclick="$set(syncSource.details,'syncViews',true)"> |
||||
Credentials |
||||
</span> |
||||
|
||||
<a href="https://docs.nocodb.com/setup-and-usages/import-airtable-to-sql-database-within-a-minute-for-free/#get-airtable-credentials" class="caption grey--text" target="_blank">Where to find this?</a> |
||||
</div> |
||||
|
||||
<v-form v-model="valid"> |
||||
<div v-if="syncSource" class="px-10 mt-1 mx-auto" style="max-width: 400px"> |
||||
<v-text-field |
||||
v-model="syncSource.details.apiKey" |
||||
outlined |
||||
dense |
||||
label="Api Key" |
||||
class="caption nc-input-api-key" |
||||
:type="isPasswordVisible ? 'text':'password'" |
||||
autocomplete="off" |
||||
:rules="[v=> !!v || 'Api Key is required']" |
||||
> |
||||
<template #append=""> |
||||
<v-icon class="mt-1" small @click="isPasswordVisible = !isPasswordVisible"> |
||||
{{ isPasswordVisible ? 'visibility_off' : 'visibility' }} |
||||
</v-icon> |
||||
</template> |
||||
</v-text-field> |
||||
<v-text-field |
||||
v-model="syncSourceUrlOrId" |
||||
outlined |
||||
dense |
||||
label="Shared Base ID / URL" |
||||
class="caption nc-input-shared-base" |
||||
:rules="[(v) => !!v || 'Shared Base ID / URL is required']" |
||||
/> |
||||
</div> |
||||
</v-form> <v-card-actions class="justify-center pb-6"> |
||||
<v-btn |
||||
v-t="['c:sync-airtable:save-and-sync']" |
||||
class="nc-btn-airtable-import" |
||||
:disabled="!valid" |
||||
large |
||||
color="primary" |
||||
@click="saveAndSync" |
||||
> |
||||
Import |
||||
</v-btn> |
||||
</v-card-actions> |
||||
</template> |
||||
<template |
||||
v-else-if="step === 2" |
||||
> |
||||
<v-card-title class=" justify-center"> |
||||
<span class="subtitle-1 font-weight-medium">Logs</span> |
||||
</v-card-title> |
||||
|
||||
<v-card |
||||
ref="log" |
||||
dark |
||||
class="mt-2 mx-4 pa-4 elevation-0 green--text" |
||||
height="500" |
||||
style="overflow-y: auto" |
||||
> |
||||
<div v-for="({msg , status}, i) in progress" :key="i"> |
||||
<v-icon v-if="status==='FAILED'" color="red" size="15"> |
||||
mdi-close-circle-outline |
||||
</v-icon> |
||||
<v-icon v-else color="green" size="15"> |
||||
mdi-currency-usd |
||||
</v-icon> |
||||
<span class="caption nc-text">{{ msg }}</span> |
||||
</div> |
||||
<div |
||||
v-if="!progress || !progress.length || progress[progress.length-1].status !== 'COMPLETED' && progress[progress.length-1].status !== 'FAILED'" |
||||
class="" |
||||
> |
||||
<v-icon color="green" size="15"> |
||||
mdi-loading mdi-spin |
||||
</v-icon> |
||||
<span class="caption nc-text">Syncing |
||||
</span> |
||||
<!-- <div class="nc-progress" />--> |
||||
</div> |
||||
</v-card> |
||||
|
||||
<div |
||||
v-if="progress && progress.length && progress[progress.length-1].status === 'COMPLETED'" |
||||
class="pa-4 pt-8 text-center" |
||||
> |
||||
<v-btn large color="primary" class="nc-btn-go-dashboard" @click="airtableModal=false"> |
||||
Go to dashboard |
||||
</v-btn> |
||||
</div> |
||||
</template> |
||||
<div class="text-center pa-4 pb-0"> |
||||
<a class="caption grey--text" href="https://github.com/nocodb/nocodb/issues/2052" target="_blank">Questions / Help - reach out here</a> |
||||
<br> |
||||
<span class="caption grey--text"> This feature is currently in beta and more information can be found <a href="https://github.com/nocodb/nocodb/discussions/2122" class="caption grey--text" target="_blank">here</a>.</span> |
||||
</div> |
||||
</v-card> |
||||
</div> |
||||
</div> |
||||
</v-card> |
||||
</v-dialog> |
||||
</template> |
||||
|
||||
<script> |
||||
import io from 'socket.io-client' |
||||
|
||||
export default { |
||||
name: 'ImportFromAirtable', |
||||
props: { |
||||
value: Boolean |
||||
}, |
||||
data: () => ({ |
||||
isPasswordVisible: false, |
||||
valid: false, |
||||
socket: null, |
||||
step: 1, |
||||
progress: [], |
||||
syncSource: null, |
||||
syncSourceUrlOrId: '' |
||||
}), |
||||
computed: { |
||||
airtableModal: { |
||||
set(v) { |
||||
this.$emit('input', v) |
||||
}, |
||||
get() { |
||||
return this.value |
||||
} |
||||
} |
||||
}, |
||||
watch: { |
||||
syncSourceUrlOrId(v) { |
||||
if (this.syncSource && this.syncSource.details) { |
||||
const m = v && v.match(/(exp|shr).{14}/g) |
||||
this.syncSource.details.shareId = m ? m[0] : null |
||||
} |
||||
} |
||||
}, |
||||
created() { |
||||
this.socket = io(new URL(this.$axios.defaults.baseURL, window.location.href.split(/[?#]/)[0]).href, { |
||||
extraHeaders: { 'xc-auth': this.$store.state.users.token } |
||||
}) |
||||
this.socket.on('connect_error', () => { |
||||
this.socket.disconnect() |
||||
this.socket = null |
||||
}) |
||||
|
||||
const socket = this.socket |
||||
socket.on('connect', function(data) { |
||||
console.log(socket.id) |
||||
console.log('socket connected', data) |
||||
}) |
||||
|
||||
socket.on('progress', (d) => { |
||||
this.progress.push(d) |
||||
|
||||
this.$nextTick(() => { |
||||
if (this.$refs.log) { |
||||
const el = this.$refs.log.$el |
||||
el.scrollTop = el.scrollHeight |
||||
} |
||||
}) |
||||
|
||||
if (d.status === 'COMPLETED') { |
||||
this.$store.dispatch('project/_loadTables', { |
||||
dbKey: '0.projectJson.envs._noco.db.0', |
||||
key: '0.projectJson.envs._noco.db.0.tables', |
||||
_nodes: { |
||||
dbAlias: 'db', |
||||
env: '_noco', |
||||
type: 'tableDir' |
||||
} |
||||
}).then(() => this.$store.dispatch('tabs/loadFirstTableTab')) |
||||
} |
||||
}) |
||||
this.loadSyncSrc() |
||||
}, |
||||
beforeDestroy() { |
||||
if (this.socket) { |
||||
this.socket.disconnect() |
||||
} |
||||
}, |
||||
methods: { |
||||
async saveAndSync() { |
||||
await this.createOrUpdate() |
||||
this.sync() |
||||
}, |
||||
sync() { |
||||
this.step = 2 |
||||
this.$axios.post(`/api/v1/db/meta/syncs/${this.syncSource.id}/trigger`, this.payload, { |
||||
params: { |
||||
id: this.socket.id |
||||
} |
||||
}) |
||||
}, |
||||
async loadSyncSrc() { |
||||
const { data: { list: srcs } } = await this.$axios.get(`/api/v1/db/meta/projects/${this.projectId}/syncs`) |
||||
if (srcs && srcs[0]) { |
||||
srcs[0].details = srcs[0].details || {} |
||||
this.syncSource = srcs[0] |
||||
this.syncSourceUrlOrId = srcs[0].details.shareId |
||||
} else { |
||||
this.syncSource = { |
||||
type: 'Airtable', |
||||
details: { |
||||
syncInterval: '15mins', |
||||
syncDirection: 'Airtable to NocoDB', |
||||
syncRetryCount: 1, |
||||
|
||||
syncViews: false, |
||||
|
||||
apiKey: '', |
||||
shareId: '' |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
async createOrUpdate() { |
||||
try { |
||||
const { id, ...payload } = this.syncSource |
||||
if (id) { |
||||
await this.$axios.patch(`/api/v1/db/meta/syncs/${id}`, payload) |
||||
} else { |
||||
this.syncSource = (await this.$axios.post(`/api/v1/db/meta/projects/${this.projectId}/syncs`, payload)).data |
||||
} |
||||
} catch (e) { |
||||
this.$toast.error(await this._extractSdkResponseErrorMsg(e)).goAway(3000) |
||||
} |
||||
}, |
||||
enableTurbo() { |
||||
this.$set(this.syncSource.details, 'syncViews', true) |
||||
this.$toast.success('🚀🚀 Ludicrous mode activated! Let\'s go! 🚀🚀').goAway(3000) |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
|
||||
.nc-progress { |
||||
margin-left: 12px; |
||||
position: relative; |
||||
width: 5px; |
||||
height: 5px; |
||||
border-radius: 5px; |
||||
background-color: #9880ff; |
||||
color: #9880ff; |
||||
animation: dotFlashing 1s infinite linear alternate; |
||||
animation-delay: .5s; |
||||
} |
||||
|
||||
.nc-progress::before, .nc-progress::after { |
||||
content: ''; |
||||
display: inline-block; |
||||
position: absolute; |
||||
top: 0; |
||||
} |
||||
|
||||
.nc-progress::before { |
||||
left: -7.5px; |
||||
width: 5px; |
||||
height: 5px; |
||||
border-radius: 5px; |
||||
background-color: #9880ff; |
||||
color: #9880ff; |
||||
animation: dotFlashing 1s infinite alternate; |
||||
animation-delay: 0s; |
||||
} |
||||
|
||||
.nc-progress::after { |
||||
left: 7.5px; |
||||
width: 5px; |
||||
height: 5px; |
||||
border-radius: 5px; |
||||
background-color: var(--v-primary-base); |
||||
color: var(--v-primary-base); |
||||
animation: dotFlashing 1s infinite alternate; |
||||
animation-delay: 1s; |
||||
} |
||||
|
||||
@keyframes dotFlashing { |
||||
0% { |
||||
background-color: var(--v-primary-base); |
||||
} |
||||
50%, |
||||
100% { |
||||
background-color: var(--v-backgroundColor-base); |
||||
} |
||||
} |
||||
|
||||
</style> |
@ -1,20 +1,22 @@
|
||||
import ExcelTemplateAdapter from '~/components/import/templateParsers/ExcelTemplateAdapter' |
||||
|
||||
export default class ExcelUrlTemplateAdapter extends ExcelTemplateAdapter { |
||||
constructor(url, $store, parserConfig) { |
||||
constructor(url, $store, parserConfig, $api) { |
||||
const name = url.split('/').pop() |
||||
super(name, null, parserConfig) |
||||
this.url = url |
||||
this.$api = $api |
||||
this.$store = $store |
||||
} |
||||
|
||||
async init() { |
||||
const res = await this.$store.dispatch('sqlMgr/ActSqlOp', [null, 'handleAxiosCall', |
||||
[{ |
||||
const data = await this.$api.utils.axiosRequestMake({ |
||||
apiMeta: { |
||||
url: this.url, |
||||
responseType: 'arraybuffer' |
||||
}]]) |
||||
this.excelData = res.data |
||||
} |
||||
}) |
||||
this.excelData = data.data |
||||
await super.init() |
||||
} |
||||
} |
||||
|
@ -1,404 +0,0 @@
|
||||
<template> |
||||
<div class="d-flex h-100"> |
||||
<v-navigation-drawer width="300" class="pa-1"> |
||||
<v-text-field |
||||
v-model="query" |
||||
outlined |
||||
dense |
||||
hide-details |
||||
placeholder="Search apps" |
||||
append-icon="mdi-magnify" |
||||
/> |
||||
|
||||
<v-list dense> |
||||
<v-list-item v-for="filter of filters" :key="filter"> |
||||
<v-checkbox |
||||
v-model="selectedTags" |
||||
class="pt-0 mt-0" |
||||
:value="filter" |
||||
hide-details |
||||
dense |
||||
:label="filter" |
||||
/> |
||||
</v-list-item> |
||||
</v-list> |
||||
</v-navigation-drawer> |
||||
<v-container class="h-100 app-container"> |
||||
<v-row> |
||||
<v-col v-for="(app,i) in filteredApps" :key="i" cols="6"> |
||||
<v-card |
||||
class="elevation-0 app-item-card" |
||||
> |
||||
<v-btn x-small outlined class="install-btn caption text-capitalize" @click="installApp"> |
||||
<v-icon x-small class="mr-1"> |
||||
mdi-plus |
||||
</v-icon> |
||||
Install |
||||
</v-btn> |
||||
|
||||
<div class="d-flex flex-no-wrap"> |
||||
<v-avatar |
||||
class="ma-3" |
||||
size="100" |
||||
tile |
||||
> |
||||
<v-img v-if="app.img" :src="app.img" contain /> |
||||
<v-img v-else src="https://cdn.vuetifyjs.com/images/cards/foster.jpg" contain /> |
||||
</v-avatar> |
||||
<div class="flex-grow-1"> |
||||
<v-card-title |
||||
class="title " |
||||
v-text="app.name" |
||||
/> |
||||
|
||||
<v-card-subtitle class="pb-1" v-text="app.description" /> |
||||
<v-card-actions> |
||||
<div class="d-flex justify-space-between d-100 align-center"> |
||||
<v-rating |
||||
full-icon="mdi-star" |
||||
readonly |
||||
length="5" |
||||
size="15" |
||||
value="5" |
||||
/> |
||||
|
||||
<span v-if="app.price && app.price !== 'Free'" class="subtitles">${{ app.price }} / mo</span> |
||||
<span v-else class="subtitles">Free</span> |
||||
</div> |
||||
</v-card-actions> |
||||
|
||||
<!-- <v-card-actions>--> |
||||
<!-- <v-btn--> |
||||
<!-- outlined--> |
||||
<!-- rounded--> |
||||
<!-- small--> |
||||
<!-- >--> |
||||
<!-- Download--> |
||||
<!-- </v-btn>--> |
||||
<!-- </v-card-actions>--> |
||||
</div> |
||||
</div> |
||||
</v-card> |
||||
</v-col> |
||||
</v-row> |
||||
</v-container> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'AppStore', |
||||
data: () => ({ |
||||
query: '', |
||||
selectedTags: [], |
||||
apps: [ |
||||
// { |
||||
// name: 'Graph', |
||||
// description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
// price: '29', |
||||
// tags: [] |
||||
// }, { |
||||
// name: 'Import / Export', |
||||
// description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
// price: '39' |
||||
// }, { |
||||
// name: 'Chart', |
||||
// description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
// price: '19' |
||||
// }, |
||||
{ |
||||
name: 'Freshworks', |
||||
img: require('~/assets/img/abcd/freshworks.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '19', |
||||
tags: ['SaaS'] |
||||
}, |
||||
{ |
||||
name: 'RazorPay', |
||||
img: require('~/assets/img/abcd/razorpay.svg'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '19', |
||||
tags: ['SaaS'] |
||||
}, |
||||
{ |
||||
name: 'Google Ads', |
||||
img: require('~/assets/img/abcd/adsense.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '19', |
||||
tags: ['SaaS'] |
||||
}, |
||||
{ |
||||
name: 'Facebook Ads', |
||||
img: require('~/assets/img/abcd/fbads.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '19', |
||||
tags: ['SaaS'] |
||||
}, |
||||
{ |
||||
name: 'Stripe', |
||||
img: require('~/assets/img/abcd/320.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '19', |
||||
tags: ['SaaS'] |
||||
}, { |
||||
name: 'Twilio', |
||||
img: require('~/assets/img/abcd/twilio.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '19', |
||||
tags: ['SaaS'] |
||||
}, { |
||||
name: 'SendGrid', |
||||
img: require('~/assets/img/abcd/sendgrid.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '19', |
||||
tags: ['SaaS'] |
||||
}, { |
||||
name: 'Basecamp', |
||||
img: require('~/assets/img/abcd/basecamp.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '19', |
||||
tags: ['SaaS'] |
||||
}, { |
||||
name: 'Github', |
||||
img: require('~/assets/img/abcd/github.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '19', |
||||
tags: ['SaaS'] |
||||
}, { |
||||
name: 'Shopify', |
||||
img: require('~/assets/img/abcd/shopify.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '19' |
||||
}, { |
||||
name: 'SAP', |
||||
img: require('~/assets/img/abcd/sap.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '49', |
||||
tags: ['ERP'] |
||||
}, { |
||||
name: 'SalesForce', |
||||
img: require('~/assets/img/abcd/salesforce.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '99', |
||||
tags: ['ERP'] |
||||
}, { |
||||
name: 'NetSuite', |
||||
img: require('~/assets/img/abcd/netsuit.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '99' |
||||
}, { |
||||
name: 'Zoho CRM', |
||||
img: require('~/assets/img/abcd/zohocrm.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '99', |
||||
tags: ['ERP'] |
||||
}, { |
||||
name: 'MySQL', |
||||
img: require('~/assets/img/abcd/mysql.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: 'Free', |
||||
tags: ['Free', 'Databases'] |
||||
}, { |
||||
name: 'PostgreSQL', |
||||
img: require('~/assets/img/abcd/pg.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: 'Free', |
||||
tags: ['Free', 'Databases'] |
||||
}, { |
||||
name: 'SQL Server', |
||||
img: require('~/assets/img/abcd/mssql.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: 'Free', |
||||
tags: ['Free', 'Databases'] |
||||
}, { |
||||
name: 'MariaDB', |
||||
img: require('~/assets/img/abcd/mariaDB.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: 'Free', |
||||
tags: ['Free', 'Databases'] |
||||
}, { |
||||
name: 'SQLite', |
||||
img: require('~/assets/img/temp/db/sqlite.svg'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: 'Free', |
||||
tags: ['Free', 'Databases'] |
||||
}, { |
||||
name: 'Oracle DB', |
||||
img: require('~/assets/img/temp/db/oracle.png.jpg'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: 'Free', |
||||
tags: ['Free', 'Databases'] |
||||
}, { |
||||
name: 'CrateDB', |
||||
img: require('~/assets/img/abcd/cratedb.jpg'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '99', |
||||
tags: ['Databases'] |
||||
}, { |
||||
name: 'Cassandra', |
||||
img: require('~/assets/img/abcd/cassandra.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '99', |
||||
tags: ['Databases'] |
||||
}, { |
||||
name: 'CouchDB', |
||||
img: require('~/assets/img/abcd/couchdb.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '99', |
||||
tags: ['Databases'] |
||||
}, { |
||||
name: 'ElasticSearch', |
||||
img: require('~/assets/img/abcd/elasticsearch.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '99', |
||||
tags: ['Databases'] |
||||
}, { |
||||
name: 'Snowflake', |
||||
img: require('~/assets/img/abcd/snowflake.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '99', |
||||
tags: ['Databases'] |
||||
}, { |
||||
name: 'MongoDB', |
||||
img: require('~/assets/img/abcd/mongodb.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '99' |
||||
}, { |
||||
name: 'BigQuery', |
||||
img: require('~/assets/img/abcd/bigquery.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: '99' |
||||
}, |
||||
|
||||
{ |
||||
name: 'REST API', |
||||
img: require('~/assets/img/abcd/rest.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: 'Free', |
||||
tags: ['Free', 'API'] |
||||
}, { |
||||
name: 'GRAPHQL API', |
||||
img: require('~/assets/img/abcd/graphql.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: 'Free', |
||||
tags: ['Free', 'API'] |
||||
}, { |
||||
name: 'gRPC API', |
||||
img: require('~/assets/img/abcd/grpc.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: 'Free', |
||||
tags: ['Free', 'API'] |
||||
}, |
||||
|
||||
{ |
||||
name: 'Swagger', |
||||
img: require('~/assets/img/abcd/swagger.png'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: 'Free', |
||||
tags: ['Free', 'API Specification'] |
||||
}, |
||||
{ |
||||
name: 'Postman', |
||||
img: require('~/assets/img/abcd/postman.jpg'), |
||||
description: 'Visualize your records on a bar, line, pie, or scatter chart', |
||||
price: 'Free', |
||||
tags: ['API Specification'] |
||||
} |
||||
|
||||
] |
||||
}), |
||||
computed: { |
||||
filters() { |
||||
return this.apps.reduce((arr, app) => arr.concat(app.tags || []), []).filter((f, i, arr) => i === arr.indexOf(f)).sort() |
||||
}, |
||||
filteredApps() { |
||||
return this.apps.filter(app => (!this.query.trim() || app.name.toLowerCase().includes(this.query.trim().toLowerCase())) && |
||||
(!this.selectedTags.length || this.selectedTags.some(t => app.tags && app.tags.includes(t))) |
||||
) |
||||
} |
||||
}, |
||||
methods: { |
||||
installApp() { |
||||
this.$toast.info('Coming soon after seed funding.').goAway(5000) |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped lang="scss"> |
||||
.title { |
||||
color: var(--v-textColor-ligten2) !important; |
||||
} |
||||
|
||||
.app-item-card { |
||||
transition: .4s background-color; |
||||
position: relative; |
||||
overflow-x: hidden; |
||||
|
||||
.install-btn { |
||||
position: absolute; |
||||
opacity: 0; |
||||
right: -100%; |
||||
top: 10px; |
||||
transition: .4s opacity, .4s right; |
||||
} |
||||
|
||||
&:hover .install-btn { |
||||
right: 10px; |
||||
opacity: 1; |
||||
} |
||||
} |
||||
|
||||
.app-item-card { |
||||
transition: .4s background-color, .4s transform; |
||||
&:hover { |
||||
background: rgba(123, 126, 136, 0.1) !important; |
||||
transform: scale(1.01); |
||||
} |
||||
} |
||||
::v-deep { |
||||
.v-rating { |
||||
margin-left:6px; |
||||
.v-icon { |
||||
padding-right: 2px; |
||||
padding-left: 2px; |
||||
} |
||||
} |
||||
.v-input__control .v-input__slot .v-input--selection-controls__input { |
||||
transform: scale(.75); |
||||
} |
||||
|
||||
.v-input--selection-controls .v-input__slot > .v-label{ |
||||
font-size: .8rem; |
||||
} |
||||
} |
||||
.app-container { |
||||
height: 100%; |
||||
overflow-y: auto; |
||||
} |
||||
|
||||
</style> |
||||
<!-- |
||||
/** |
||||
* @copyright Copyright (c) 2021, Xgene Cloud Ltd |
||||
* |
||||
* @author Naveen MR <oof1lab@gmail.com> |
||||
* @author Pranav C Balan <pranavxc@gmail.com> |
||||
* |
||||
* @license GNU AGPL version 3 or any later version |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License as |
||||
* published by the Free Software Foundation, either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
* |
||||
*/ |
||||
--> |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue