mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-03-17 22:12:43 +00:00
Resolve "Plugins stack - comms issue"
This commit is contained in:
parent
e78e01cfe8
commit
527ed3f625
37 changed files with 4037 additions and 3826 deletions
changelog.md
docs
plugin-boilerplate/{{ cookiecutter.project_slug }}
web-frontend
.eslintignore.eslintrc.js.stylelintignorejest.config.jsjest.setup.js
modules
package.jsontest/pages
yarn.lock
|
@ -2,6 +2,7 @@
|
|||
|
||||
## Unreleased
|
||||
|
||||
* Upgraded web-frontend dependencies.
|
||||
* Fixed bug where you could not convert an existing field to a single select field
|
||||
without select options.
|
||||
* Fixed bug where is was not possible to create a relation to a table that has a single
|
||||
|
|
|
@ -65,9 +65,10 @@ $ docker network create baserow_default
|
|||
$ docker-compose up -d
|
||||
Building backend
|
||||
...
|
||||
Starting baserow_db_1 ... done
|
||||
Starting baserow_mjml_1 ... done
|
||||
Starting backend ... done
|
||||
Starting db ... done
|
||||
Starting mjml ... done
|
||||
Starting redis ... done
|
||||
Starting backend ... done
|
||||
Starting web-frontend ... done
|
||||
```
|
||||
|
||||
|
@ -91,6 +92,18 @@ http://localhost:8000/api/groups/ in your browser you should see the response
|
|||
"Authentication credentials were not provided." If you want to see the API spec,
|
||||
you can visit http://localhost:8000/api/redoc/.
|
||||
|
||||
## Starting the worker
|
||||
|
||||
In order to process asynchronous tasks you also need to start a Celery worker this is
|
||||
mainly used for the real time collaboration. Open a new tab or window and execute the
|
||||
following commands. The `watchmedo` command makes sure the worker is restarted whenever
|
||||
you make a change.
|
||||
|
||||
```
|
||||
$ docker exec -it backend bash
|
||||
$ watchmedo auto-restart --directory=./ --pattern=*.py --recursive -- celery -A baserow worker -l INFO
|
||||
```
|
||||
|
||||
## Starting web frontend development server
|
||||
|
||||
Now that the backend server is up and running you can start the web-frontend
|
||||
|
|
|
@ -44,12 +44,13 @@ the created directory and start your development environment.
|
|||
> plugin directory.
|
||||
|
||||
```
|
||||
$ cd my-plugin-boilerplate
|
||||
$ cd my-baserow-plugin
|
||||
$ docker network create baserow_plugin_default
|
||||
$ docker-compose up -d
|
||||
...
|
||||
Starting my-baserow-plugin-mjml ... done
|
||||
Starting my-baserow-plugin-db ... done
|
||||
Starting my-baserow-plugin-redis ... done
|
||||
Starting my-baserow-plugin-backend ... done
|
||||
Starting my-baserow-plugin-web-frontend ... done
|
||||
```
|
||||
|
@ -70,12 +71,26 @@ containing "Authentication credentials were not provided.". This means that ever
|
|||
is working! Second we can install the node dependencies and start the Nuxt development
|
||||
server. Open a new tab/window of your terminal and execute the following commands.
|
||||
|
||||
> You might need to restart the Celery worker when you have made changes.
|
||||
|
||||
Celery is used to broadcast real time changes asynchronous to other users. If you want
|
||||
to use real time collaboration you also need to start the Celery worker. Open a new tab
|
||||
or window in your terminal and execute the following commands.
|
||||
|
||||
```
|
||||
$ docker exec -it my-baserow-plugin-backend bash
|
||||
$ celery -A baserow worker -l INFO
|
||||
```
|
||||
|
||||
> It could happen that you get a module not found error when are trying to start the
|
||||
> Nuxt development server. This will most likely be because Baserow has been installed
|
||||
> as a link dependency and this means that Baserow needs its own node_modules in order
|
||||
> to work. Execute the following command inside the web-frontend container to resolve
|
||||
> the issue: `(cd /baserow/web-frontend && yarn install)`.
|
||||
|
||||
Finally you need to start the web-frontend server. Open a new tab or window in your
|
||||
terminal and execute to following commands.
|
||||
|
||||
```
|
||||
$ docker exec -it my-baserow-plugin-web-frontend bash
|
||||
$ yarn install
|
||||
|
|
|
@ -11,6 +11,12 @@ services:
|
|||
ports:
|
||||
- 5432:5432
|
||||
|
||||
redis:
|
||||
container_name: {{ cookiecutter.project_slug }}-redis
|
||||
image: redis:6.0
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
mjml:
|
||||
container_name: {{ cookiecutter.project_slug }}-mjml
|
||||
image: liminspace/mjml-tcpserver:latest
|
||||
|
@ -29,6 +35,7 @@ services:
|
|||
- 8001:8000
|
||||
depends_on:
|
||||
- db
|
||||
- redis
|
||||
- mjml
|
||||
environment:
|
||||
- PUBLIC_BACKEND_URL=http://localhost:8001
|
||||
|
|
|
@ -14,15 +14,15 @@
|
|||
"{{ cookiecutter.project_slug }}": "link:/{{ cookiecutter.project_slug }}/plugins/{{ cookiecutter.project_module }}/web-frontend"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxtjs/eslint-config": "^2.0.2",
|
||||
"@nuxtjs/eslint-config": "^5.0.0",
|
||||
"@vue/test-utils": "^1.0.0-beta.27",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-jest": "^25.2.4",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.10.1",
|
||||
"babel-jest": "^26.6.3",
|
||||
"eslint": "^7.19.0",
|
||||
"eslint-config-prettier": "^7.2.0",
|
||||
"eslint-config-standard": ">=12.0.0",
|
||||
"eslint-loader": "^3.0.3",
|
||||
"eslint-loader": "^4.0.2",
|
||||
"eslint-plugin-import": ">=2.16.0",
|
||||
"eslint-plugin-jest": ">=22.3.0",
|
||||
"eslint-plugin-node": ">=8.0.1",
|
||||
|
@ -30,12 +30,12 @@
|
|||
"eslint-plugin-prettier": "^3.0.1",
|
||||
"eslint-plugin-promise": ">=4.0.1",
|
||||
"eslint-plugin-standard": ">=4.0.0",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"eslint-plugin-vue": "^7.5.0",
|
||||
"nodemon": "^2.0.2",
|
||||
"prettier": "^2.0.2",
|
||||
"stylelint": "^13.2.1",
|
||||
"stylelint-config-standard": "^20.0.0",
|
||||
"stylelint-webpack-plugin": "^1.2.3",
|
||||
"stylelint-webpack-plugin": "^2.1.1",
|
||||
"vue-jest": "^3.0.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
.nuxt/*
|
||||
node_modules/*
|
||||
**/node_modules/*
|
||||
coverage/**
|
||||
|
|
|
@ -2,23 +2,22 @@ module.exports = {
|
|||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
node: true
|
||||
node: true,
|
||||
},
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint'
|
||||
parser: 'babel-eslint',
|
||||
},
|
||||
extends: [
|
||||
'@nuxtjs',
|
||||
'plugin:nuxt/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
'prettier',
|
||||
'prettier/vue'
|
||||
],
|
||||
plugins: [
|
||||
'prettier'
|
||||
'prettier/vue',
|
||||
],
|
||||
plugins: ['prettier'],
|
||||
// add your custom rules here
|
||||
rules: {
|
||||
'no-console': 0
|
||||
}
|
||||
'no-console': 0,
|
||||
'vue/no-mutating-props': 0,
|
||||
},
|
||||
}
|
||||
|
|
4
web-frontend/.stylelintignore
Normal file
4
web-frontend/.stylelintignore
Normal file
|
@ -0,0 +1,4 @@
|
|||
.nuxt/*
|
||||
node_modules/*
|
||||
**/node_modules/*
|
||||
coverage/**
|
|
@ -17,4 +17,5 @@ module.exports = {
|
|||
'<rootDir>/components/**/*.vue',
|
||||
'<rootDir>/pages/**/*.vue',
|
||||
],
|
||||
setupFilesAfterEnv: ['./jest.setup.js'],
|
||||
}
|
||||
|
|
1
web-frontend/jest.setup.js
Normal file
1
web-frontend/jest.setup.js
Normal file
|
@ -0,0 +1 @@
|
|||
jest.setTimeout(120000)
|
|
@ -9,9 +9,7 @@
|
|||
></i>
|
||||
{{ selectedName }}
|
||||
</template>
|
||||
<template v-if="!hasValue()">
|
||||
Make a choice
|
||||
</template>
|
||||
<template v-if="!hasValue()"> Make a choice </template>
|
||||
<i class="dropdown__toggle-icon fas fa-caret-down"></i>
|
||||
</a>
|
||||
<div class="dropdown__items" :class="{ hidden: !open }">
|
||||
|
|
|
@ -20,12 +20,8 @@
|
|||
<div class="upload-files__dropzone-content">
|
||||
<i class="upload-files__dropzone-icon fas fa-cloud-upload-alt"></i>
|
||||
<div class="upload-files__dropzone-text">
|
||||
<template v-if="dragging">
|
||||
Drop here
|
||||
</template>
|
||||
<template v-else>
|
||||
Click or drop your files here
|
||||
</template>
|
||||
<template v-if="dragging"> Drop here </template>
|
||||
<template v-else> Click or drop your files here </template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Modal :sidebar="true" @hidden="$emit('hidden')">
|
||||
<template v-slot:sidebar>
|
||||
<template #sidebar>
|
||||
<div class="modal-sidebar__head">
|
||||
<div class="modal-sidebar__head-name">Upload from</div>
|
||||
</div>
|
||||
|
@ -20,7 +20,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<template v-slot:content>
|
||||
<template #content>
|
||||
<component
|
||||
:is="userFileUploadComponent"
|
||||
@uploaded="$emit('uploaded', $event)"
|
||||
|
|
|
@ -80,8 +80,8 @@ import error from '@baserow/modules/core/mixins/error'
|
|||
import AuthService from '@baserow/modules/core/services/auth'
|
||||
|
||||
export default {
|
||||
layout: 'login',
|
||||
mixins: [error],
|
||||
layout: 'login',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Modal :sidebar="true">
|
||||
<template v-slot:sidebar>
|
||||
<template #sidebar>
|
||||
<div class="modal-sidebar__head">
|
||||
<div class="modal-sidebar__head-icon">{{ nameAbbreviation }}</div>
|
||||
<div class="modal-sidebar__head-name">Settings</div>
|
||||
|
@ -21,7 +21,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<template v-slot:content>
|
||||
<template #content>
|
||||
<component :is="settingPageComponent"></component>
|
||||
</template>
|
||||
</Modal>
|
||||
|
|
|
@ -97,17 +97,17 @@ import GroupsContext from '@baserow/modules/core/components/group/GroupsContext'
|
|||
import Sidebar from '@baserow/modules/core/components/sidebar/Sidebar'
|
||||
|
||||
export default {
|
||||
// Application pages are pages that have the edit sidebar on the left side which
|
||||
// contains the groups and applications. In order to be able to fetch them the user
|
||||
// must be authenticated. And in order to show them we must fetch all the groups and
|
||||
// applications.
|
||||
middleware: ['authenticated', 'groupsAndApplications'],
|
||||
components: {
|
||||
SettingsModal,
|
||||
GroupsContext,
|
||||
Notifications,
|
||||
Sidebar,
|
||||
},
|
||||
// Application pages are pages that have the edit sidebar on the left side which
|
||||
// contains the groups and applications. In order to be able to fetch them the user
|
||||
// must be authenticated. And in order to show them we must fetch all the groups and
|
||||
// applications.
|
||||
middleware: ['authenticated', 'groupsAndApplications'],
|
||||
computed: {
|
||||
...mapGetters({
|
||||
isCollapsed: 'sidebar/isCollapsed',
|
||||
|
|
|
@ -45,6 +45,11 @@ export default {
|
|||
required: true,
|
||||
},
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.message,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
statusCode() {
|
||||
return (this.error && this.error.statusCode) || 500
|
||||
|
@ -56,10 +61,5 @@ export default {
|
|||
isAuthenticated: 'auth/isAuthenticated',
|
||||
}),
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.message,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -62,8 +62,13 @@ import CreateGroupModal from '@baserow/modules/core/components/group/CreateGroup
|
|||
import DashboardGroup from '@baserow/modules/core/components/group/DashboardGroup'
|
||||
|
||||
export default {
|
||||
layout: 'app',
|
||||
components: { CreateGroupModal, DashboardGroup },
|
||||
layout: 'app',
|
||||
head() {
|
||||
return {
|
||||
title: 'Dashboard',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
user: (state) => state.auth.user,
|
||||
|
@ -71,10 +76,5 @@ export default {
|
|||
applications: (state) => state.application.items,
|
||||
}),
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: 'Dashboard',
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -68,8 +68,8 @@ import error from '@baserow/modules/core/mixins/error'
|
|||
import AuthService from '@baserow/modules/core/services/auth'
|
||||
|
||||
export default {
|
||||
layout: 'login',
|
||||
mixins: [error],
|
||||
layout: 'login',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
|
@ -79,6 +79,11 @@ export default {
|
|||
},
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: 'Forgot password',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async sendLink() {
|
||||
this.$v.$touch()
|
||||
|
@ -103,11 +108,6 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: 'Forgot password',
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
account: {
|
||||
email: { required, email },
|
||||
|
|
|
@ -42,9 +42,7 @@
|
|||
<div class="actions">
|
||||
<ul class="action__links">
|
||||
<li>
|
||||
<nuxt-link :to="{ name: 'signup' }">
|
||||
Sign up
|
||||
</nuxt-link>
|
||||
<nuxt-link :to="{ name: 'signup' }"> Sign up </nuxt-link>
|
||||
</li>
|
||||
<li>
|
||||
<nuxt-link :to="{ name: 'forgot-password' }">
|
||||
|
@ -70,8 +68,8 @@ import { required, email } from 'vuelidate/lib/validators'
|
|||
import error from '@baserow/modules/core/mixins/error'
|
||||
|
||||
export default {
|
||||
layout: 'login',
|
||||
mixins: [error],
|
||||
layout: 'login',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
|
@ -81,6 +79,17 @@ export default {
|
|||
},
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: 'Login',
|
||||
link: [
|
||||
{
|
||||
rel: 'canonical',
|
||||
href: this.$env.PUBLIC_WEB_FRONTEND_URL + this.$route.path,
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async login() {
|
||||
this.$v.$touch()
|
||||
|
@ -128,17 +137,6 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: 'Login',
|
||||
link: [
|
||||
{
|
||||
rel: 'canonical',
|
||||
href: this.$env.PUBLIC_WEB_FRONTEND_URL + this.$route.path,
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
credentials: {
|
||||
email: { required, email },
|
||||
|
|
|
@ -75,8 +75,8 @@ import error from '@baserow/modules/core/mixins/error'
|
|||
import AuthService from '@baserow/modules/core/services/auth'
|
||||
|
||||
export default {
|
||||
layout: 'login',
|
||||
mixins: [error],
|
||||
layout: 'login',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
|
@ -87,6 +87,11 @@ export default {
|
|||
},
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: 'Reset password',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async resetPassword() {
|
||||
this.$v.$touch()
|
||||
|
@ -120,11 +125,6 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: 'Reset password',
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
account: {
|
||||
password: { required },
|
||||
|
|
|
@ -110,8 +110,8 @@ import { ResponseErrorMessage } from '@baserow/modules/core/plugins/clientHandle
|
|||
import error from '@baserow/modules/core/mixins/error'
|
||||
|
||||
export default {
|
||||
layout: 'login',
|
||||
mixins: [error],
|
||||
layout: 'login',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
|
@ -123,6 +123,11 @@ export default {
|
|||
},
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: 'Create new account',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async register() {
|
||||
this.$v.$touch()
|
||||
|
@ -154,11 +159,6 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: 'Create new account',
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
account: {
|
||||
email: { required, email },
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
value: {{ dropdown }}
|
||||
<br />
|
||||
<br />
|
||||
<div style="width: 200px;">
|
||||
<div style="width: 200px">
|
||||
<Dropdown v-model="dropdown">
|
||||
<DropdownItem name="Choice 1" value="choice-1"></DropdownItem>
|
||||
<DropdownItem
|
||||
|
@ -157,7 +157,7 @@
|
|||
value: {{ dropdown }}
|
||||
<br />
|
||||
<br />
|
||||
<div style="width: 200px;">
|
||||
<div style="width: 200px">
|
||||
<Dropdown v-model="dropdown" :show-search="false">
|
||||
<DropdownItem name="Choice 1" value="choice-1"></DropdownItem>
|
||||
<DropdownItem
|
||||
|
@ -183,7 +183,7 @@
|
|||
<div class="control">
|
||||
<label class="control__label">Very long dropdown</label>
|
||||
<div class="control__elements">
|
||||
<div style="width: 200px;">
|
||||
<div style="width: 200px">
|
||||
<Dropdown v-model="longDropdown">
|
||||
<DropdownItem
|
||||
:key="'some-2'"
|
||||
|
@ -238,7 +238,7 @@
|
|||
Dropdown by link {{ dropdown }}
|
||||
</label>
|
||||
<div class="control__elements">
|
||||
<div style="width: 200px;">
|
||||
<div style="width: 200px">
|
||||
<a
|
||||
ref="dropdownLink"
|
||||
@click="$refs.dropdown1.toggle($refs.dropdownLink)"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Vue from 'vue'
|
||||
import Datepicker from 'vuejs-datepicker'
|
||||
|
||||
Vue.component('date-picker', Datepicker)
|
||||
Vue.component('DatePicker', Datepicker)
|
||||
|
|
|
@ -38,10 +38,10 @@ export const slugify = (string) => {
|
|||
export const isValidURL = (str) => {
|
||||
const pattern = new RegExp(
|
||||
'^((https?|ftps?):\\/\\/)?' + // protocol
|
||||
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
|
||||
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
|
||||
'(\\:\\d+)?(\\/[-a-z\\d\\*%_.~+]*)*' + // port and path
|
||||
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
|
||||
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
|
||||
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
|
||||
'(\\:\\d+)?(\\/[-a-z\\d\\*%_.~+]*)*' + // port and path
|
||||
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
|
||||
'(\\#[-a-z\\d_]*)?$',
|
||||
'i'
|
||||
) // fragment locator
|
||||
|
@ -49,7 +49,7 @@ export const isValidURL = (str) => {
|
|||
}
|
||||
|
||||
export const isValidEmail = (str) => {
|
||||
const pattern = new RegExp('[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}', 'i') // check email format
|
||||
const pattern = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i
|
||||
return !!pattern.test(str)
|
||||
}
|
||||
|
||||
|
|
|
@ -41,9 +41,7 @@
|
|||
></FieldSingleSelectDropdownItem>
|
||||
</ul>
|
||||
<template v-if="canCreateOption">
|
||||
<div class="select__description">
|
||||
Option not found
|
||||
</div>
|
||||
<div class="select__description">Option not found</div>
|
||||
<div class="select__footer">
|
||||
<a
|
||||
class="select__footer-button"
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
<template>
|
||||
<form @submit.prevent="submit">
|
||||
<div class="control">
|
||||
<label class="control__label">
|
||||
Name
|
||||
</label>
|
||||
<label class="control__label"> Name </label>
|
||||
<div class="control__elements">
|
||||
<input
|
||||
ref="name"
|
||||
|
@ -19,9 +17,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="control">
|
||||
<label class="control__label">
|
||||
Group
|
||||
</label>
|
||||
<label class="control__label"> Group </label>
|
||||
<Dropdown
|
||||
v-model="values.group"
|
||||
class="col-4"
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="control">
|
||||
<label class="control__label">
|
||||
Choose CSV file
|
||||
</label>
|
||||
<label class="control__label"> Choose CSV file </label>
|
||||
<div class="control__description">
|
||||
You can import an existing CSV by uploading the .CSV file with tabular
|
||||
data. Most spreadsheet applications will allow you to export your
|
||||
|
@ -35,9 +33,7 @@
|
|||
<div v-if="filename !== ''" class="row">
|
||||
<div class="col col-6">
|
||||
<div class="control">
|
||||
<label class="control__label">
|
||||
First row is header
|
||||
</label>
|
||||
<label class="control__label"> First row is header </label>
|
||||
<div class="control__elements">
|
||||
<Checkbox v-model="values.firstRowHeader" @input="reload()"
|
||||
>yes</Checkbox
|
||||
|
@ -47,9 +43,7 @@
|
|||
</div>
|
||||
<div class="col col-6">
|
||||
<div class="control">
|
||||
<label class="control__label">
|
||||
Column separator
|
||||
</label>
|
||||
<label class="control__label"> Column separator </label>
|
||||
<div class="control__elements">
|
||||
<Dropdown v-model="columnSeparator" @input="reload()">
|
||||
<DropdownItem name="auto detect" value="auto"></DropdownItem>
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="control">
|
||||
<label class="control__label">
|
||||
Paste the table data
|
||||
</label>
|
||||
<label class="control__label"> Paste the table data </label>
|
||||
<div class="control__description">
|
||||
You can copy the cells from a spreadsheet and paste them below.
|
||||
</div>
|
||||
|
@ -19,9 +17,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="control">
|
||||
<label class="control__label">
|
||||
First row is header
|
||||
</label>
|
||||
<label class="control__label"> First row is header </label>
|
||||
<div class="control__elements">
|
||||
<Checkbox v-model="values.firstRowHeader" @input="reload()"
|
||||
>yes</Checkbox
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<template>
|
||||
<Checkbox :value="copy" @input="input($event)">
|
||||
Selected
|
||||
</Checkbox>
|
||||
<Checkbox :value="copy" @input="input($event)"> Selected </Checkbox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
|
||||
import context from '@baserow/modules/core/mixins/context'
|
||||
import { notifyIf } from '@/modules/core/utils/error'
|
||||
import { notifyIf } from '@baserow/modules/core/utils/error'
|
||||
import { clone } from '@baserow/modules/core/utils/object'
|
||||
|
||||
export default {
|
||||
|
|
|
@ -42,18 +42,18 @@ import APIDocsSelectDatabase from '@baserow/modules/database/components/docs/API
|
|||
|
||||
export default {
|
||||
name: 'APIDocs',
|
||||
layout: 'login',
|
||||
components: { SettingsModal, APIDocsSelectDatabase },
|
||||
layout: 'login',
|
||||
middleware: ['groupsAndApplications'],
|
||||
computed: {
|
||||
...mapGetters({
|
||||
isAuthenticated: 'auth/isAuthenticated',
|
||||
}),
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: 'REST API documentation',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
isAuthenticated: 'auth/isAuthenticated',
|
||||
}),
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -540,9 +540,7 @@
|
|||
</div>
|
||||
<div class="api-docs__item">
|
||||
<div class="api-docs__left">
|
||||
<h2 id="section-filters" class="api-docs__heading-2">
|
||||
Filters
|
||||
</h2>
|
||||
<h2 id="section-filters" class="api-docs__heading-2">Filters</h2>
|
||||
<table class="api-docs__table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -568,9 +566,7 @@
|
|||
</div>
|
||||
<div class="api-docs__item">
|
||||
<div class="api-docs__left">
|
||||
<h2 id="section-errors" class="api-docs__heading-2">
|
||||
HTTP Errors
|
||||
</h2>
|
||||
<h2 id="section-errors" class="api-docs__heading-2">HTTP Errors</h2>
|
||||
<table class="api-docs__table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -596,9 +592,7 @@
|
|||
<tr>
|
||||
<td>401</td>
|
||||
<td>Unauthorized</td>
|
||||
<td>
|
||||
When you try to access an endpoint without valid token.
|
||||
</td>
|
||||
<td>When you try to access an endpoint without valid token.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>404</td>
|
||||
|
@ -608,9 +602,7 @@
|
|||
<tr>
|
||||
<td>413</td>
|
||||
<td>Request Entity Too Large</td>
|
||||
<td>
|
||||
The request exceeded the maximum allowed payload size.
|
||||
</td>
|
||||
<td>The request exceeded the maximum allowed payload size.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>500</td>
|
||||
|
@ -706,6 +698,11 @@ export default {
|
|||
databasesOpen: false,
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: `API Documentation ${this.database.name}`,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
viewFilterTypes() {
|
||||
return Object.values(this.$registry.getAll('viewFilter'))
|
||||
|
@ -796,10 +793,5 @@ export default {
|
|||
)
|
||||
},
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: `API Documentation ${this.database.name}`,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -98,12 +98,20 @@ import ViewSort from '@baserow/modules/database/components/view/ViewSort'
|
|||
* will load the correct components into the header and body.
|
||||
*/
|
||||
export default {
|
||||
layout: 'app',
|
||||
components: {
|
||||
ViewsContext,
|
||||
ViewFilter,
|
||||
ViewSort,
|
||||
},
|
||||
/**
|
||||
* When the user leaves to another page we want to unselect the selected table. This
|
||||
* way it will not be highlighted the left sidebar.
|
||||
*/
|
||||
beforeRouteLeave(to, from, next) {
|
||||
this.$store.dispatch('table/unselect')
|
||||
next()
|
||||
},
|
||||
layout: 'app',
|
||||
/**
|
||||
* Because there is no hook that is called before the route changes, we need the
|
||||
* tableLoading middleware to change the table loading state. This change will get
|
||||
|
@ -174,6 +182,11 @@ export default {
|
|||
viewLoading: false,
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: (this.view ? this.view.name + ' - ' : '') + this.table.name,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
/**
|
||||
* Indicates if there is a selected view by checking if the view object has been
|
||||
|
@ -203,14 +216,6 @@ export default {
|
|||
beforeCreate() {
|
||||
this.$store.dispatch('table/setLoading', false)
|
||||
},
|
||||
/**
|
||||
* When the user leaves to another page we want to unselect the selected table. This
|
||||
* way it will not be highlighted the left sidebar.
|
||||
*/
|
||||
beforeRouteLeave(to, from, next) {
|
||||
this.$store.dispatch('table/unselect')
|
||||
next()
|
||||
},
|
||||
beforeMount() {
|
||||
this.$bus.$on('table-refresh', this.refresh)
|
||||
},
|
||||
|
@ -256,10 +261,5 @@ export default {
|
|||
})
|
||||
},
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: (this.view ? this.view.name + ' - ' : '') + this.table.name,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -15,35 +15,36 @@
|
|||
"jest": "jest -i --verbose false test/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.13.0",
|
||||
"@nuxtjs/axios": "5.8.0",
|
||||
"axios": "0.19.0",
|
||||
"@fortawesome/fontawesome-free": "^5.15.0",
|
||||
"@nuxtjs/axios": "^5.8.0",
|
||||
"axios": "^0.21.0",
|
||||
"bignumber.js": "^9.0.1",
|
||||
"cookie-universal-nuxt": "2.1.3",
|
||||
"cross-env": "7.0.2",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lodash": "4.17.15",
|
||||
"cookie-universal-nuxt": "^2.1.3",
|
||||
"cross-env": "^7.0.2",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"lodash": "^4.17.15",
|
||||
"moment": "^2.26.0",
|
||||
"node-sass": "4.13.1",
|
||||
"normalize-scss": "7.0.1",
|
||||
"nuxt": "2.12.1",
|
||||
"node-sass": "^5.0.0",
|
||||
"normalize-scss": "^7.0.1",
|
||||
"nuxt": "^2.14.12",
|
||||
"nuxt-env": "^0.1.0",
|
||||
"papaparse": "^5.3.0",
|
||||
"sass-loader": "8.0.2",
|
||||
"sass-loader": "^10.1.1",
|
||||
"thenby": "^1.3.4",
|
||||
"vuejs-datepicker": "^1.6.2",
|
||||
"vuelidate": "0.7.5"
|
||||
"vuelidate": "^0.7.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxtjs/eslint-config": "^2.0.2",
|
||||
"@nuxtjs/eslint-config": "^5.0.0",
|
||||
"@vue/test-utils": "^1.0.0-beta.27",
|
||||
"axios-mock-adapter": "^1.19.0",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-jest": "^25.2.4",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.10.1",
|
||||
"babel-jest": "^26.6.3",
|
||||
"eslint": "^7.11.0",
|
||||
"eslint-config-prettier": "^7.2.0",
|
||||
"eslint-config-standard": ">=12.0.0",
|
||||
"eslint-loader": "^3.0.3",
|
||||
"eslint-loader": "^4.0.2",
|
||||
"eslint-plugin-import": ">=2.16.0",
|
||||
"eslint-plugin-jest": ">=22.3.0",
|
||||
"eslint-plugin-node": ">=8.0.1",
|
||||
|
@ -51,17 +52,16 @@
|
|||
"eslint-plugin-prettier": "^3.0.1",
|
||||
"eslint-plugin-promise": ">=4.0.1",
|
||||
"eslint-plugin-standard": ">=4.0.0",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"jest": "^25.2.4",
|
||||
"eslint-plugin-vue": "^7.5.0",
|
||||
"jest": "^26.6.3",
|
||||
"jsdom": "^16.2.2",
|
||||
"jsdom-global": "^3.0.2",
|
||||
"moxios": "^0.4.0",
|
||||
"node-mocks-http": "^1.7.6",
|
||||
"nodemon": "^2.0.2",
|
||||
"prettier": "^2.0.2",
|
||||
"stylelint": "^13.2.1",
|
||||
"stylelint-config-standard": "^20.0.0",
|
||||
"stylelint-webpack-plugin": "^1.2.3",
|
||||
"stylelint-webpack-plugin": "^2.1.1",
|
||||
"vue-jest": "^3.0.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +1,34 @@
|
|||
import moxios from 'moxios'
|
||||
import axios from 'axios'
|
||||
import MockAdapter from 'axios-mock-adapter'
|
||||
import httpMocks from 'node-mocks-http'
|
||||
|
||||
import createNuxt from '@/test/helpers/create-nuxt'
|
||||
|
||||
let nuxt = null
|
||||
let mock = null
|
||||
|
||||
describe('index redirect', () => {
|
||||
beforeAll(async (done) => {
|
||||
moxios.install()
|
||||
mock = new MockAdapter(axios)
|
||||
|
||||
// Because the token 'test1' exists it will be refreshed immediately, the
|
||||
// refresh endpoint is stubbed so that it will always provide a valid
|
||||
// unexpired token.
|
||||
moxios.stubRequest('http://localhost/api/user/token-refresh/', {
|
||||
status: 200,
|
||||
response: {
|
||||
token:
|
||||
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2' +
|
||||
'VybmFtZSI6InRlc3RAdGVzdCIsImV4cCI6MTk5OTk5OTk5OSwiZW1haWwiO' +
|
||||
'iJ0ZXN0QHRlc3QubmwiLCJvcmlnX2lhdCI6MTU2Mjc3MzQxNH0.2i0gqrcH' +
|
||||
'5uy7mk4kf3LoLpZYXoyMrOfi0fDQneVcaFE',
|
||||
user: {
|
||||
first_name: 'Test',
|
||||
username: 'test@test.nl',
|
||||
},
|
||||
mock.onPost('http://localhost/api/user/token-refresh/').reply(200, {
|
||||
token:
|
||||
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2' +
|
||||
'VybmFtZSI6InRlc3RAdGVzdCIsImV4cCI6MTk5OTk5OTk5OSwiZW1haWwiO' +
|
||||
'iJ0ZXN0QHRlc3QubmwiLCJvcmlnX2lhdCI6MTU2Mjc3MzQxNH0.2i0gqrcH' +
|
||||
'5uy7mk4kf3LoLpZYXoyMrOfi0fDQneVcaFE',
|
||||
user: {
|
||||
first_name: 'Test',
|
||||
username: 'test@test.nl',
|
||||
},
|
||||
})
|
||||
|
||||
nuxt = await createNuxt(true)
|
||||
done()
|
||||
}, 120000)
|
||||
})
|
||||
|
||||
test('if not authenticated', async () => {
|
||||
const { redirected } = await nuxt.server.renderRoute('/')
|
||||
|
@ -51,6 +50,5 @@ describe('index redirect', () => {
|
|||
|
||||
afterAll(async () => {
|
||||
await nuxt.close()
|
||||
moxios.uninstall()
|
||||
})
|
||||
})
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue