mirror of
https://github.com/nocodb/nocodb.git
synced 2026-04-25 04:45:07 +00:00
Merge pull request #1950 from nocodb/feat/code-snippet
Feat/code snippet
This commit is contained in:
128
packages/nc-gui/components/monaco/CustomMonacoEditor.js
Normal file
128
packages/nc-gui/components/monaco/CustomMonacoEditor.js
Normal file
@@ -0,0 +1,128 @@
|
||||
/* eslint-disable */
|
||||
// import assign from "nano-assign";
|
||||
// import sqlAutoCompletions from "./sqlAutoCompletions";
|
||||
// import {ext} from "vee-validate/dist/rules.esm";
|
||||
|
||||
|
||||
export default {
|
||||
name: "CustomMonacoEditor",
|
||||
|
||||
props: {
|
||||
value: {
|
||||
default: "",
|
||||
type: String
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
default: "vs-dark"
|
||||
},
|
||||
lang: {type:String, default: 'typescript'},
|
||||
readOnly:Boolean,
|
||||
minimap:Boolean,
|
||||
},
|
||||
|
||||
model: {
|
||||
event: "change"
|
||||
},
|
||||
watch: {
|
||||
value(newVal) {
|
||||
if (newVal !== this.editor.getValue()) {
|
||||
if (typeof newVal === 'object') {
|
||||
this.editor.setValue(JSON.stringify(newVal, 0, 2));
|
||||
} else {
|
||||
this.editor.setValue(newVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
if (this.amdRequire) {
|
||||
this.amdRequire(["vs/editor/editor.main"], () => {
|
||||
this.initMonaco(window.monaco);
|
||||
});
|
||||
} else {
|
||||
// ESM format so it can't be resolved by commonjs `require` in eslint
|
||||
// eslint-disable import/no-unresolved
|
||||
const monaco = require("monaco-editor");
|
||||
// monaco.editor.defineTheme('monokai', require('./Cobalt.json'))
|
||||
// monaco.editor.setTheme('monokai')
|
||||
|
||||
this.monaco = monaco;
|
||||
this.initMonaco(monaco);
|
||||
}
|
||||
});
|
||||
},
|
||||
unmounted() {
|
||||
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.editor && this.editor.dispose();
|
||||
},
|
||||
|
||||
methods: {
|
||||
resizeLayout() {
|
||||
this.editor.layout();
|
||||
},
|
||||
initMonaco(monaco) {
|
||||
const code = this.value;
|
||||
const model = monaco.editor.createModel(code, this.lang ||"json");
|
||||
|
||||
this.editor = monaco.editor.create(this.$el, {
|
||||
model: model,
|
||||
theme: this.theme, minimap: {
|
||||
enabled: this.minimap
|
||||
}
|
||||
});
|
||||
|
||||
this.editor.onDidChangeModelContent(event => {
|
||||
const value = this.editor.getValue();
|
||||
if (this.value !== value) {
|
||||
this.$emit("change", value, event);
|
||||
}
|
||||
});
|
||||
this.editor.updateOptions({ readOnly: this.readOnly })
|
||||
},
|
||||
|
||||
getMonaco() {
|
||||
return this.editor;
|
||||
},
|
||||
getMonacoModule() {
|
||||
return this.monaco;
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
|
||||
render(h) {
|
||||
return h("div");
|
||||
},
|
||||
created() {
|
||||
},
|
||||
destroyed() {
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @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,272 @@
|
||||
<template>
|
||||
<div class="nc-container" :class="{active:modal}" @click="modal=false">
|
||||
<div class="nc-snippet elevation-3 pa-4" @click.stop>
|
||||
<h3 class="font-weight-medium mb-4">
|
||||
Code Snippet
|
||||
</h3>
|
||||
|
||||
<v-icon class="nc-snippet-close" @click="modal=false">
|
||||
mdi-close
|
||||
</v-icon>
|
||||
|
||||
<div v-if="modal">
|
||||
<v-tabs v-model="tab" height="30" show-arrows @change="client=null">
|
||||
<v-tab
|
||||
v-for="{lang} in langs"
|
||||
:key="lang"
|
||||
v-t="['c:snippet:tab', {lang}]"
|
||||
class="caption"
|
||||
>
|
||||
{{ lang }}
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
<div class="nc-snippet-wrapper mt-4">
|
||||
<div class="nc-snippet-actions d-flex">
|
||||
<v-btn
|
||||
v-t="['c:snippet:copy', {client: langs[tab].clients && (client || langs[tab].clients[0]), lang: langs[tab ||0].lang}]"
|
||||
color="primary"
|
||||
class="rounded caption "
|
||||
@click="copyToClipboard"
|
||||
>
|
||||
<v-icon small>
|
||||
mdi-clipboard-outline
|
||||
</v-icon>
|
||||
Copy To Clipboard
|
||||
</v-btn>
|
||||
<div
|
||||
v-if="langs[tab].clients"
|
||||
class=" ml-2 d-flex align-center"
|
||||
>
|
||||
<v-menu bottom offset-y>
|
||||
<template #activator="{on}">
|
||||
<v-btn class="caption text-uppercase" color="primary" v-on="on">
|
||||
{{ client || langs[tab].clients[0] }}
|
||||
<v-icon small>
|
||||
mdi-chevron-down
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list dense>
|
||||
<v-list-item
|
||||
v-for="c in langs[tab].clients"
|
||||
:key="c"
|
||||
dense
|
||||
@click="client = c"
|
||||
>
|
||||
<v-list-item-title class="text-uppercase">
|
||||
{{ c }}
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</div>
|
||||
</div>
|
||||
<custom-monaco-editor
|
||||
hide-line-num
|
||||
:theme="$store.state.windows.darkTheme ? 'vs-dark' : 'vs-light'"
|
||||
style="min-height:500px;max-width: 100%"
|
||||
:value="code"
|
||||
read-only
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HTTPSnippet from 'httpsnippet'
|
||||
import CustomMonacoEditor from '~/components/monaco/CustomMonacoEditor'
|
||||
import { copyTextToClipboard } from '~/helpers/xutils'
|
||||
|
||||
export default {
|
||||
name: 'CodeSnippet',
|
||||
components: { CustomMonacoEditor },
|
||||
props: {
|
||||
meta: Object,
|
||||
view: Object,
|
||||
filters: [Object, Array],
|
||||
sorts: [Object, Array],
|
||||
fileds: [Object, Array],
|
||||
queryParams: Object,
|
||||
value: Boolean
|
||||
},
|
||||
data: () => ({
|
||||
tab: 0,
|
||||
client: null,
|
||||
langs: [
|
||||
{
|
||||
lang: 'shell',
|
||||
clients: ['curl', 'wget']
|
||||
},
|
||||
{
|
||||
lang: 'javascript',
|
||||
clients: ['axios', 'fetch', 'jquery', 'xhr']
|
||||
},
|
||||
{
|
||||
lang: 'node',
|
||||
clients: ['axios', 'fetch', 'request', 'native', 'unirest']
|
||||
},
|
||||
{
|
||||
lang: 'nocodb-sdk',
|
||||
clients: ['javascript', 'node']
|
||||
},
|
||||
{
|
||||
lang: 'php'
|
||||
},
|
||||
{
|
||||
lang: 'python',
|
||||
clients: ['python3',
|
||||
'requests']
|
||||
},
|
||||
{
|
||||
lang: 'ruby'
|
||||
},
|
||||
{
|
||||
lang: 'java'
|
||||
},
|
||||
{
|
||||
lang: 'c'
|
||||
}
|
||||
]
|
||||
}),
|
||||
computed: {
|
||||
modal: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('input', v)
|
||||
}
|
||||
},
|
||||
apiUrl() {
|
||||
return new URL(`/api/v1/db/data/noco/${this.projectId}/${this.meta.title}/views/${this.view.title}`, (this.$store.state.project.projectInfo && this.$store.state.project.projectInfo.ncSiteUrl) || '/').href
|
||||
},
|
||||
snippet() {
|
||||
return new HTTPSnippet({
|
||||
method: 'GET',
|
||||
headers: [
|
||||
{ name: 'xc-auth', value: this.$store.state.users.token, comment: 'JWT Auth token' }
|
||||
],
|
||||
url: this.apiUrl,
|
||||
queryString: Object.entries(this.queryParams || {}).map(([name, value]) => {
|
||||
return {
|
||||
name, value: String(value)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
code() {
|
||||
if (this.langs[this.tab].lang === 'nocodb-sdk') {
|
||||
return `${
|
||||
this.client === 'node'
|
||||
? 'const { Api } require("nocodb-sdk");'
|
||||
: 'import { Api } from "nocodb-sdk";'
|
||||
}
|
||||
|
||||
const api = new Api({
|
||||
baseURL: ${JSON.stringify(this.apiUrl)},
|
||||
headers: {
|
||||
"xc-auth": ${JSON.stringify(this.$store.state.users.token)}
|
||||
}
|
||||
})
|
||||
|
||||
api.dbViewRow.list(
|
||||
"noco",
|
||||
${JSON.stringify(this.projectName)},
|
||||
${JSON.stringify(this.meta.title)},
|
||||
${JSON.stringify(this.view.title)}, ${JSON.stringify(this.queryParams, null, 4)}).then(function (data) {
|
||||
console.log(data);
|
||||
}).catch(function (error) {
|
||||
console.error(error);
|
||||
});`
|
||||
}
|
||||
|
||||
return this.snippet.convert(this.langs[this.tab].lang, this.client || (this.langs[this.tab].clients && this.langs[this.tab].clients[0]), {})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
(document.querySelector('[data-app]') || this.$root.$el).append(this.$el)
|
||||
},
|
||||
|
||||
destroyed() {
|
||||
this.$el.parentNode && this.$el.parentNode.removeChild(this.$el)
|
||||
},
|
||||
methods: {
|
||||
copyToClipboard() {
|
||||
copyTextToClipboard(this.code)
|
||||
this.$toast.success('Code copied to clipboard successfully.').goAway(3000)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.nc-snippet-wrapper {
|
||||
position: relative;
|
||||
border: 1px solid #7773;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.nc-snippet-actions {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.nc-container {
|
||||
position: fixed;
|
||||
pointer-events: none;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 9999;
|
||||
right: 0;
|
||||
top: 0;
|
||||
|
||||
.nc-snippet {
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
&.active {
|
||||
pointer-events: all;
|
||||
|
||||
& > .nc-snippet {
|
||||
right: 0
|
||||
}
|
||||
}
|
||||
|
||||
.nc-snippet-close {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
.v-tabs {
|
||||
height: 100%;
|
||||
|
||||
.v-tabs-items {
|
||||
height: calc(100% - 30px);
|
||||
|
||||
.v-window__container {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.v-slide-group__prev--disabled {
|
||||
display: none
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -61,7 +61,9 @@
|
||||
>
|
||||
{{ viewIcons[view.type].icon }}
|
||||
</v-icon>
|
||||
<v-icon v-else color="primary" small> mdi-table </v-icon>
|
||||
<v-icon v-else color="primary" small>
|
||||
mdi-table
|
||||
</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>
|
||||
<v-tooltip bottom>
|
||||
@@ -77,7 +79,7 @@
|
||||
@click.stop
|
||||
@keydown.enter.stop="updateViewName(view, i)"
|
||||
@blur="updateViewName(view, i)"
|
||||
/>
|
||||
>
|
||||
<template v-else>
|
||||
<span v-on="on">{{
|
||||
view.alias || view.title
|
||||
@@ -183,7 +185,9 @@
|
||||
@click="openCreateViewDlg(viewTypes.GRID)"
|
||||
>
|
||||
<v-list-item-icon class="mr-n1">
|
||||
<v-icon color="blue" x-small> mdi-grid-large </v-icon>
|
||||
<v-icon color="blue" x-small>
|
||||
mdi-grid-large
|
||||
</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>
|
||||
<span class="font-weight-regular">
|
||||
@@ -192,7 +196,9 @@
|
||||
</span>
|
||||
</v-list-item-title>
|
||||
<v-spacer />
|
||||
<v-icon class="mr-1" small> mdi-plus </v-icon>
|
||||
<v-icon class="mr-1" small>
|
||||
mdi-plus
|
||||
</v-icon>
|
||||
</v-list-item>
|
||||
</template>
|
||||
<!-- Add Grid View -->
|
||||
@@ -207,7 +213,9 @@
|
||||
@click="openCreateViewDlg(viewTypes.GALLERY)"
|
||||
>
|
||||
<v-list-item-icon class="mr-n1">
|
||||
<v-icon color="orange" x-small> mdi-camera-image </v-icon>
|
||||
<v-icon color="orange" x-small>
|
||||
mdi-camera-image
|
||||
</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>
|
||||
<span class="font-weight-regular">
|
||||
@@ -217,7 +225,9 @@
|
||||
</v-list-item-title>
|
||||
|
||||
<v-spacer />
|
||||
<v-icon class="mr-1" small> mdi-plus </v-icon>
|
||||
<v-icon class="mr-1" small>
|
||||
mdi-plus
|
||||
</v-icon>
|
||||
</v-list-item>
|
||||
</template>
|
||||
<!-- Add Gallery View -->
|
||||
@@ -251,7 +261,9 @@
|
||||
</v-list-item-title>
|
||||
|
||||
<v-spacer />
|
||||
<v-icon class="mr-1" small> mdi-plus </v-icon>
|
||||
<v-icon class="mr-1" small>
|
||||
mdi-plus
|
||||
</v-icon>
|
||||
</v-list-item>
|
||||
</template>
|
||||
<!-- Add Form View -->
|
||||
@@ -261,6 +273,20 @@
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<v-btn
|
||||
v-t="['c:snippet:open']"
|
||||
color="primary"
|
||||
class="caption d-100"
|
||||
@click="codeSnippetModal=true"
|
||||
>
|
||||
<v-icon small class="mr-2">
|
||||
mdi-xml
|
||||
</v-icon> Get API Snippet
|
||||
</v-btn>
|
||||
<code-snippet v-model="codeSnippetModal" :query-params="queryParams" :meta="meta" :view="selectedView" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="time - $store.state.windows.miniSponsorCard > 15 * 60 * 1000"
|
||||
class="pa-2 sponsor-wrapper"
|
||||
@@ -270,10 +296,10 @@
|
||||
</v-icon>
|
||||
|
||||
<!-- <extras />-->
|
||||
<v-divider/>
|
||||
<extras class="pl-1"/>
|
||||
<v-divider />
|
||||
<extras class="pl-1" />
|
||||
|
||||
<!-- <sponsor-mini nav />-->
|
||||
<!-- <sponsor-mini nav />-->
|
||||
</div>
|
||||
<!--<div class="text-center">
|
||||
<v-hover >
|
||||
@@ -490,17 +516,18 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import draggable from "vuedraggable";
|
||||
import { ViewTypes } from "nocodb-sdk";
|
||||
import CreateViewDialog from "@/components/project/spreadsheet/dialog/createViewDialog";
|
||||
import Extras from "~/components/project/spreadsheet/components/extras";
|
||||
import viewIcons from "~/helpers/viewIcons";
|
||||
import { copyTextToClipboard } from "~/helpers/xutils";
|
||||
import SponsorMini from "~/components/sponsorMini";
|
||||
import draggable from 'vuedraggable'
|
||||
import { ViewTypes } from 'nocodb-sdk'
|
||||
import CreateViewDialog from '@/components/project/spreadsheet/dialog/createViewDialog'
|
||||
import Extras from '~/components/project/spreadsheet/components/extras'
|
||||
import viewIcons from '~/helpers/viewIcons'
|
||||
import { copyTextToClipboard } from '~/helpers/xutils'
|
||||
import SponsorMini from '~/components/sponsorMini'
|
||||
import CodeSnippet from '~/components/project/spreadsheet/components/codeSnippet'
|
||||
|
||||
export default {
|
||||
name: "SpreadsheetNavDrawer",
|
||||
components: { SponsorMini, Extras, CreateViewDialog, draggable },
|
||||
name: 'SpreadsheetNavDrawer',
|
||||
components: { CodeSnippet, SponsorMini, Extras, CreateViewDialog, draggable },
|
||||
props: {
|
||||
extraViewParams: Object,
|
||||
showAdvanceOptions: Boolean,
|
||||
@@ -509,7 +536,7 @@ export default {
|
||||
primaryValueColumn: [Number, String],
|
||||
toggleDrawer: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
nodes: Object,
|
||||
table: String,
|
||||
@@ -523,7 +550,7 @@ export default {
|
||||
sortList: [Object, Array],
|
||||
load: {
|
||||
default: true,
|
||||
type: Boolean,
|
||||
type: Boolean
|
||||
},
|
||||
currentApiUrl: String,
|
||||
fieldsOrder: Array,
|
||||
@@ -533,22 +560,24 @@ export default {
|
||||
groupingField: String,
|
||||
// showSystemFields: Boolean,
|
||||
views: Array,
|
||||
queryParams: Object
|
||||
},
|
||||
data: () => ({
|
||||
codeSnippetModal: false,
|
||||
drag: false,
|
||||
dragOptions: {
|
||||
animation: 200,
|
||||
group: "description",
|
||||
group: 'description',
|
||||
disabled: false,
|
||||
ghostClass: "ghost",
|
||||
ghostClass: 'ghost'
|
||||
},
|
||||
time: Date.now(),
|
||||
sponsorMiniVisible: true,
|
||||
enableDummyFeat: false,
|
||||
searchQueryVal: "",
|
||||
searchQueryVal: '',
|
||||
showShareLinkPassword: false,
|
||||
passwordProtect: false,
|
||||
sharedViewPassword: "",
|
||||
sharedViewPassword: '',
|
||||
overAdvShieldIcon: false,
|
||||
overShieldIcon: false,
|
||||
viewIcons,
|
||||
@@ -558,120 +587,120 @@ export default {
|
||||
showCreateView: false,
|
||||
loading: false,
|
||||
viewTypeAlias: {
|
||||
[ViewTypes.GRID]: "grid",
|
||||
[ViewTypes.FORM]: "form",
|
||||
[ViewTypes.GALLERY]: "gallery",
|
||||
},
|
||||
[ViewTypes.GRID]: 'grid',
|
||||
[ViewTypes.FORM]: 'form',
|
||||
[ViewTypes.GALLERY]: 'gallery'
|
||||
}
|
||||
}),
|
||||
computed: {
|
||||
viewsList: {
|
||||
set(v) {
|
||||
this.$emit("update:views", v);
|
||||
this.$emit('update:views', v)
|
||||
},
|
||||
get() {
|
||||
return this.views;
|
||||
},
|
||||
return this.views
|
||||
}
|
||||
},
|
||||
viewTypes() {
|
||||
return ViewTypes;
|
||||
return ViewTypes
|
||||
},
|
||||
newViewParams() {
|
||||
if (!this.showFields) {
|
||||
return {};
|
||||
return {}
|
||||
}
|
||||
const showFields = { ...this.showFields };
|
||||
const showFields = { ...this.showFields }
|
||||
Object.keys(showFields).forEach((k) => {
|
||||
showFields[k] = true;
|
||||
});
|
||||
return { showFields };
|
||||
showFields[k] = true
|
||||
})
|
||||
return { showFields }
|
||||
},
|
||||
selectedViewIdLocal: {
|
||||
set(val) {
|
||||
const view = (this.views || []).find((v) => v.id === val);
|
||||
const view = (this.views || []).find(v => v.id === val)
|
||||
this.$router.push({
|
||||
query: {
|
||||
...this.$route.query,
|
||||
view: view && view.id,
|
||||
},
|
||||
});
|
||||
view: view && view.id
|
||||
}
|
||||
})
|
||||
},
|
||||
get() {
|
||||
let id;
|
||||
let id
|
||||
if (this.views) {
|
||||
const view = this.views.find((v) => v.id === this.$route.query.view);
|
||||
id = (view && view.id) || ((this.views && this.views[0]) || {}).id;
|
||||
const view = this.views.find(v => v.id === this.$route.query.view)
|
||||
id = (view && view.id) || ((this.views && this.views[0]) || {}).id
|
||||
}
|
||||
return id;
|
||||
},
|
||||
return id
|
||||
}
|
||||
},
|
||||
sharedViewUrl() {
|
||||
let viewType;
|
||||
let viewType
|
||||
|
||||
switch (this.shareLink.type) {
|
||||
case this.viewTypes.FORM:
|
||||
viewType = "form";
|
||||
break;
|
||||
viewType = 'form'
|
||||
break
|
||||
case this.viewTypes.KANBAN:
|
||||
viewType = "kanban";
|
||||
break;
|
||||
viewType = 'kanban'
|
||||
break
|
||||
default:
|
||||
viewType = "view";
|
||||
viewType = 'view'
|
||||
}
|
||||
return `${this.dashboardUrl}#/nc/${viewType}/${this.shareLink.uuid}`;
|
||||
},
|
||||
return `${this.dashboardUrl}#/nc/${viewType}/${this.shareLink.uuid}`
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
async load(v) {
|
||||
if (v) {
|
||||
await this.loadViews();
|
||||
this.onViewIdChange(this.selectedViewIdLocal);
|
||||
await this.loadViews()
|
||||
this.onViewIdChange(this.selectedViewIdLocal)
|
||||
}
|
||||
},
|
||||
selectedViewIdLocal(id) {
|
||||
this.onViewIdChange(id);
|
||||
},
|
||||
this.onViewIdChange(id)
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
if (this.load) {
|
||||
await this.loadViews();
|
||||
await this.loadViews()
|
||||
}
|
||||
this.onViewIdChange(this.selectedViewIdLocal);
|
||||
this.onViewIdChange(this.selectedViewIdLocal)
|
||||
},
|
||||
methods: {
|
||||
async onMove(event) {
|
||||
if (this.viewsList.length - 1 === event.moved.newIndex) {
|
||||
this.$set(
|
||||
this.viewsList[event.moved.newIndex],
|
||||
"order",
|
||||
'order',
|
||||
this.viewsList[event.moved.newIndex - 1].order + 1
|
||||
);
|
||||
)
|
||||
} else if (event.moved.newIndex === 0) {
|
||||
this.$set(
|
||||
this.viewsList[event.moved.newIndex],
|
||||
"order",
|
||||
'order',
|
||||
this.viewsList[1].order / 2
|
||||
);
|
||||
)
|
||||
} else {
|
||||
this.$set(
|
||||
this.viewsList[event.moved.newIndex],
|
||||
"order",
|
||||
'order',
|
||||
(this.viewsList[event.moved.newIndex - 1].order +
|
||||
this.viewsList[event.moved.newIndex + 1].order) /
|
||||
2
|
||||
);
|
||||
)
|
||||
}
|
||||
await this.$api.dbView.update(this.viewsList[event.moved.newIndex].id, {
|
||||
title: this.viewsList[event.moved.newIndex].title,
|
||||
order: this.viewsList[event.moved.newIndex].order,
|
||||
});
|
||||
order: this.viewsList[event.moved.newIndex].order
|
||||
})
|
||||
|
||||
this.$e("a:view:reorder");
|
||||
this.$e('a:view:reorder')
|
||||
},
|
||||
onViewIdChange(id) {
|
||||
const selectedView = this.views && this.views.find((v) => v.id === id);
|
||||
const selectedView = this.views && this.views.find(v => v.id === id)
|
||||
// const queryParams = {}
|
||||
this.$emit("update:selectedViewId", id);
|
||||
this.$emit("update:selectedView", selectedView);
|
||||
this.$emit('update:selectedViewId', id)
|
||||
this.$emit('update:selectedView', selectedView)
|
||||
// if (selectedView.type === 'table') {
|
||||
// return;
|
||||
// }
|
||||
@@ -694,52 +723,52 @@ export default {
|
||||
// } else {
|
||||
// this.$emit('mapFieldsAndShowFields')
|
||||
// }
|
||||
this.$emit("loadTableData");
|
||||
this.$emit('loadTableData')
|
||||
},
|
||||
hideMiniSponsorCard() {
|
||||
this.$store.commit("windows/MutMiniSponsorCard", Date.now());
|
||||
this.$store.commit('windows/MutMiniSponsorCard', Date.now())
|
||||
},
|
||||
openCreateViewDlg(type) {
|
||||
const mainView = this.viewsList.find(
|
||||
(v) => v.type === "table" || v.type === "view"
|
||||
);
|
||||
v => v.type === 'table' || v.type === 'view'
|
||||
)
|
||||
try {
|
||||
this.copyViewRef = this.copyViewRef || {
|
||||
query_params: JSON.stringify({
|
||||
...this.newViewParams,
|
||||
fieldsOrder: JSON.parse(mainView.query_params).fieldsOrder,
|
||||
}),
|
||||
};
|
||||
fieldsOrder: JSON.parse(mainView.query_params).fieldsOrder
|
||||
})
|
||||
}
|
||||
} catch {}
|
||||
this.createViewType = type;
|
||||
this.showCreateView = true;
|
||||
this.$e("c:view:create", { view: type });
|
||||
this.createViewType = type
|
||||
this.showCreateView = true
|
||||
this.$e('c:view:create', { view: type })
|
||||
},
|
||||
isCentrallyAligned(col) {
|
||||
return ![
|
||||
"SingleLineText",
|
||||
"LongText",
|
||||
"Attachment",
|
||||
"Date",
|
||||
"Time",
|
||||
"Email",
|
||||
"URL",
|
||||
"DateTime",
|
||||
"CreateTime",
|
||||
"LastModifiedTime",
|
||||
].includes(col.uidt);
|
||||
'SingleLineText',
|
||||
'LongText',
|
||||
'Attachment',
|
||||
'Date',
|
||||
'Time',
|
||||
'Email',
|
||||
'URL',
|
||||
'DateTime',
|
||||
'CreateTime',
|
||||
'LastModifiedTime'
|
||||
].includes(col.uidt)
|
||||
},
|
||||
onPasswordProtectChange() {
|
||||
if (!this.passwordProtect) {
|
||||
this.shareLink.password = null;
|
||||
this.saveShareLinkPassword();
|
||||
this.shareLink.password = null
|
||||
this.saveShareLinkPassword()
|
||||
}
|
||||
},
|
||||
async saveShareLinkPassword() {
|
||||
try {
|
||||
await this.$api.dbViewShare.update(this.shareLink.id, {
|
||||
password: this.shareLink.password,
|
||||
});
|
||||
password: this.shareLink.password
|
||||
})
|
||||
|
||||
// await this.$store.dispatch('sqlMgr/ActSqlOp', [
|
||||
// { dbAlias: this.nodes.dbAlias },
|
||||
@@ -749,14 +778,14 @@ export default {
|
||||
// password: this.shareLink.password
|
||||
// }
|
||||
// ])
|
||||
this.$toast.success("Successfully updated").goAway(3000);
|
||||
this.$toast.success('Successfully updated').goAway(3000)
|
||||
} catch (e) {
|
||||
this.$toast
|
||||
.error(await this._extractSdkResponseErrorMsg(e))
|
||||
.goAway(3000);
|
||||
.goAway(3000)
|
||||
}
|
||||
|
||||
this.$e("a:view:share:enable-pwd");
|
||||
this.$e('a:view:share:enable-pwd')
|
||||
},
|
||||
async loadViews() {
|
||||
// this.viewsList = await this.sqlOp(
|
||||
@@ -772,8 +801,8 @@ export default {
|
||||
|
||||
// this.viewsList = []
|
||||
|
||||
const views = (await this.$api.dbView.list(this.meta.id)).list;
|
||||
this.$emit("update:views", views);
|
||||
const views = (await this.$api.dbView.list(this.meta.id)).list
|
||||
this.$emit('update:views', views)
|
||||
},
|
||||
// async onViewChange() {
|
||||
// let query_params = {}
|
||||
@@ -793,27 +822,27 @@ export default {
|
||||
// this.$emit('loadTableData');
|
||||
// },
|
||||
copyapiUrlToClipboard() {
|
||||
copyTextToClipboard(this.currentApiUrl);
|
||||
this.clipboardSuccessHandler();
|
||||
copyTextToClipboard(this.currentApiUrl)
|
||||
this.clipboardSuccessHandler()
|
||||
},
|
||||
async updateViewName(view, index) {
|
||||
if (!view.edit) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// const oldTitle = view.title
|
||||
|
||||
this.$set(view, "edit", false);
|
||||
this.$set(view, 'edit', false)
|
||||
if (view.title_temp === view.title) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
if (
|
||||
this.viewsList.some(
|
||||
(v, i) => i !== index && (v.alias || v.title) === view.title_temp
|
||||
)
|
||||
) {
|
||||
this.$toast.info("View name should be unique").goAway(3000);
|
||||
return;
|
||||
this.$toast.info('View name should be unique').goAway(3000)
|
||||
return
|
||||
}
|
||||
try {
|
||||
// if (this.selectedViewIdLocal === view.id) {
|
||||
@@ -824,39 +853,39 @@ export default {
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
this.$set(view, "title", view.title_temp);
|
||||
this.$set(view, 'title', view.title_temp)
|
||||
await this.$api.dbView.update(view.id, {
|
||||
title: view.title,
|
||||
order: view.order,
|
||||
});
|
||||
this.$toast.success("View renamed successfully").goAway(3000);
|
||||
order: view.order
|
||||
})
|
||||
this.$toast.success('View renamed successfully').goAway(3000)
|
||||
} catch (e) {
|
||||
this.$toast
|
||||
.error(await this._extractSdkResponseErrorMsg(e))
|
||||
.goAway(3000);
|
||||
.goAway(3000)
|
||||
}
|
||||
},
|
||||
showRenameTextBox(view, i) {
|
||||
this.$set(view, "edit", true);
|
||||
this.$set(view, "title_temp", view.title);
|
||||
this.$set(view, 'edit', true)
|
||||
this.$set(view, 'title_temp', view.title)
|
||||
this.$nextTick(() => {
|
||||
const input = this.$refs[`input${i}`][0];
|
||||
input.focus();
|
||||
input.setSelectionRange(0, input.value.length);
|
||||
});
|
||||
this.$e("c:view:rename", { view: view.type });
|
||||
const input = this.$refs[`input${i}`][0]
|
||||
input.focus()
|
||||
input.setSelectionRange(0, input.value.length)
|
||||
})
|
||||
this.$e('c:view:rename', { view: view.type })
|
||||
},
|
||||
async deleteView(view) {
|
||||
try {
|
||||
await this.$api.dbView.delete(view.id);
|
||||
this.$toast.success("View deleted successfully").goAway(3000);
|
||||
await this.loadViews();
|
||||
await this.$api.dbView.delete(view.id)
|
||||
this.$toast.success('View deleted successfully').goAway(3000)
|
||||
await this.loadViews()
|
||||
} catch (e) {
|
||||
this.$toast
|
||||
.error(await this._extractSdkResponseErrorMsg(e))
|
||||
.goAway(3000);
|
||||
.goAway(3000)
|
||||
}
|
||||
this.$e("a:view:delete", { view: view.type });
|
||||
this.$e('a:view:delete', { view: view.type })
|
||||
},
|
||||
async genShareLink() {
|
||||
// const sharedViewUrl = await this.$store.dispatch('sqlMgr/ActSqlOp', [
|
||||
@@ -883,44 +912,44 @@ export default {
|
||||
// password: this.sharedViewPassword
|
||||
// }
|
||||
// ])
|
||||
const shared = await this.$api.dbViewShare.create(this.selectedViewId);
|
||||
const shared = await this.$api.dbViewShare.create(this.selectedViewId)
|
||||
|
||||
// todo: url
|
||||
this.shareLink = shared;
|
||||
this.showShareModel = true;
|
||||
this.shareLink = shared
|
||||
this.showShareModel = true
|
||||
},
|
||||
copyView(view, i) {
|
||||
this.createViewType = view.type;
|
||||
this.showCreateView = true;
|
||||
this.copyViewRef = view;
|
||||
this.$e("c:view:copy", { view: view.type });
|
||||
this.createViewType = view.type
|
||||
this.showCreateView = true
|
||||
this.copyViewRef = view
|
||||
this.$e('c:view:copy', { view: view.type })
|
||||
},
|
||||
async onViewCreate(viewMeta) {
|
||||
this.copyViewRef = null;
|
||||
await this.loadViews();
|
||||
this.selectedViewIdLocal = viewMeta.id;
|
||||
this.copyViewRef = null
|
||||
await this.loadViews()
|
||||
this.selectedViewIdLocal = viewMeta.id
|
||||
// await this.onViewChange();
|
||||
this.$e("a:view:create", { view: viewMeta.type });
|
||||
this.$e('a:view:create', { view: viewMeta.type })
|
||||
},
|
||||
clipboard(str) {
|
||||
const el = document.createElement("textarea");
|
||||
el.addEventListener("focusin", (e) => e.stopPropagation());
|
||||
el.value = str;
|
||||
document.body.appendChild(el);
|
||||
el.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(el);
|
||||
const el = document.createElement('textarea')
|
||||
el.addEventListener('focusin', e => e.stopPropagation())
|
||||
el.value = str
|
||||
document.body.appendChild(el)
|
||||
el.select()
|
||||
document.execCommand('copy')
|
||||
document.body.removeChild(el)
|
||||
},
|
||||
clipboardSuccessHandler() {
|
||||
this.$toast.info("Copied to clipboard").goAway(1000);
|
||||
this.$toast.info('Copied to clipboard').goAway(1000)
|
||||
},
|
||||
copyShareUrlToClipboard() {
|
||||
this.clipboard(this.sharedViewUrl);
|
||||
this.clipboardSuccessHandler();
|
||||
this.$e("c:view:share:copy-url");
|
||||
},
|
||||
},
|
||||
};
|
||||
this.clipboard(this.sharedViewUrl)
|
||||
this.clipboardSuccessHandler()
|
||||
this.$e('c:view:share:copy-url')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
17562
packages/nc-gui/package-lock.json
generated
17562
packages/nc-gui/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@
|
||||
"debounce": "^1.2.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"fix-path": "^3.0.0",
|
||||
"httpsnippet": "^2.0.0",
|
||||
"inflection": "^1.12.0",
|
||||
"jsep": "^0.4.0",
|
||||
"material-design-icons-iconfont": "^5.0.1",
|
||||
@@ -65,6 +66,7 @@
|
||||
"@intlify/eslint-plugin-vue-i18n": "^0.11.1",
|
||||
"@nuxtjs/eslint-config": "^6.0.1",
|
||||
"@nuxtjs/vuetify": "^1.11.2",
|
||||
"@types/httpsnippet": "^1.23.1",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^7.31.0",
|
||||
"monaco-editor-webpack-plugin": "^1.9.1",
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Request, Response, Router } from 'express';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import ApiToken from '../../../noco-models/ApiToken';
|
||||
import { Tele } from 'nc-help';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
export async function apiTokenList(_req: Request, res: Response) {
|
||||
res.json(await ApiToken.list());
|
||||
@@ -19,14 +20,17 @@ const router = Router({ mergeParams: true });
|
||||
|
||||
router.get(
|
||||
'/api/v1/db/meta/projects/:projectId/api-tokens',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(apiTokenList, 'apiTokenList')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/projects/:projectId/api-tokens',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(apiTokenCreate, 'apiTokenCreate')
|
||||
);
|
||||
router.delete(
|
||||
'/api/v1/db/meta/projects/:projectId/api-tokens/:token',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(apiTokenDelete, 'apiTokenDelete')
|
||||
);
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import { NcError } from '../helpers/catchError';
|
||||
import getColumnPropsFromUIDT from '../helpers/getColumnPropsFromUIDT';
|
||||
import mapDefaultPrimaryValue from '../helpers/mapDefaultPrimaryValue';
|
||||
import NcConnectionMgrv2 from '../../common/NcConnectionMgrv2';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
const randomID = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 10);
|
||||
|
||||
@@ -955,18 +956,22 @@ const deleteHmOrBtRelation = async (
|
||||
const router = Router({ mergeParams: true });
|
||||
router.post(
|
||||
'/api/v1/db/meta/tables/:tableId/columns/',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(columnAdd, 'columnAdd')
|
||||
);
|
||||
router.patch(
|
||||
'/api/v1/db/meta/columns/:columnId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(columnUpdate, 'columnUpdate')
|
||||
);
|
||||
router.delete(
|
||||
'/api/v1/db/meta/columns/:columnId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(columnDelete, 'columnDelete')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/columns/:columnId/primary',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(columnSetAsPrimary, 'columnSetAsPrimary')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -12,6 +12,7 @@ import Project from '../../../noco-models/Project';
|
||||
import Filter from '../../../noco-models/Filter';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import { Tele } from 'nc-help';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
// @ts-ignore
|
||||
export async function filterGet(req: Request, res: Response, next) {
|
||||
@@ -129,10 +130,12 @@ export async function hookFilterCreate(req: Request<any, any, TableReq>, res) {
|
||||
const router = Router({ mergeParams: true });
|
||||
router.get(
|
||||
'/api/v1/db/meta/views/:viewId/filters',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(filterList, 'filterList')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/views/:viewId/filters',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(filterCreate, 'filterCreate')
|
||||
);
|
||||
|
||||
@@ -142,23 +145,28 @@ router.get(
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/hooks/:hookId/filters',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(hookFilterCreate, 'filterCreate')
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/api/v1/db/meta/filters/:filterId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(filterGet, 'filterGet')
|
||||
);
|
||||
router.patch(
|
||||
'/api/v1/db/meta/filters/:filterId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(filterUpdate, 'filterUpdate')
|
||||
);
|
||||
router.delete(
|
||||
'/api/v1/db/meta/filters/:filterId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(filterDelete, 'filterDelete')
|
||||
);
|
||||
router.get(
|
||||
'/api/v1/db/meta/filters/:filterParentId/children',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(filterChildrenRead, 'filterChildrenRead')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -12,6 +12,7 @@ import View from '../../../noco-models/View';
|
||||
import FormView from '../../../noco-models/FormView';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import { Tele } from 'nc-help';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
// @ts-ignore
|
||||
export async function formViewGet(req: Request, res: Response<FormType>) {
|
||||
@@ -41,18 +42,22 @@ export async function formViewDelete(req: Request, res: Response, next) {}
|
||||
const router = Router({ mergeParams: true });
|
||||
router.post(
|
||||
'/api/v1/db/meta/tables/:tableId/forms',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(formViewCreate, 'formViewCreate')
|
||||
);
|
||||
router.get(
|
||||
'/api/v1/db/meta/forms/:formViewId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(formViewGet, 'formViewGet')
|
||||
);
|
||||
router.patch(
|
||||
'/api/v1/db/meta/forms/:formViewId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(formViewUpdate, 'formViewUpdate')
|
||||
);
|
||||
router.delete(
|
||||
'/api/v1/db/meta/forms/:formViewId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(formViewDelete, 'formViewDelete')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Request, Response, Router } from 'express';
|
||||
import FormViewColumn from '../../../noco-models/FormViewColumn';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import { Tele } from 'nc-help';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
export async function columnUpdate(req: Request, res: Response) {
|
||||
Tele.emit('evt', { evt_type: 'formViewColumn:updated' });
|
||||
@@ -11,6 +12,7 @@ export async function columnUpdate(req: Request, res: Response) {
|
||||
const router = Router({ mergeParams: true });
|
||||
router.patch(
|
||||
'/api/v1/db/meta/form-columns/:formViewColumnId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(columnUpdate, 'columnUpdate')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -4,6 +4,7 @@ import View from '../../../noco-models/View';
|
||||
import GalleryView from '../../../noco-models/GalleryView';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import { Tele } from 'nc-help';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
export async function galleryViewGet(req: Request, res: Response<GalleryType>) {
|
||||
res.json(await GalleryView.get(req.params.galleryViewId));
|
||||
}
|
||||
@@ -27,14 +28,17 @@ export async function galleryViewUpdate(req, res) {
|
||||
const router = Router({ mergeParams: true });
|
||||
router.post(
|
||||
'/api/v1/db/meta/tables/:tableId/galleries',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(galleryViewCreate, 'galleryViewCreate')
|
||||
);
|
||||
router.patch(
|
||||
'/api/v1/db/meta/galleries/:galleryViewId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(galleryViewUpdate, 'galleryViewUpdate')
|
||||
);
|
||||
router.get(
|
||||
'/api/v1/db/meta/galleries/:galleryViewId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(galleryViewGet, 'galleryViewGet')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -11,6 +11,7 @@ import Project from '../../../noco-models/Project';
|
||||
import View from '../../../noco-models/View';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import { Tele } from 'nc-help';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
// @ts-ignore
|
||||
export async function gridViewCreate(req: Request<any, any>, res) {
|
||||
@@ -27,6 +28,7 @@ export async function gridViewCreate(req: Request<any, any>, res) {
|
||||
const router = Router({ mergeParams: true });
|
||||
router.post(
|
||||
'/api/v1/db/meta/tables/:tableId/grids/',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(gridViewCreate, 'gridViewCreate')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Request, Response, Router } from 'express';
|
||||
import GridViewColumn from '../../../noco-models/GridViewColumn';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import { Tele } from 'nc-help';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
export async function columnList(req: Request, res: Response) {
|
||||
res.json(await GridViewColumn.list(req.params.gridViewId));
|
||||
@@ -15,10 +16,12 @@ export async function gridColumnUpdate(req: Request, res: Response) {
|
||||
const router = Router({ mergeParams: true });
|
||||
router.get(
|
||||
'/api/v1/db/meta/grids/:gridViewId/grid-columns',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(columnList, 'columnList')
|
||||
);
|
||||
router.patch(
|
||||
'/api/v1/db/meta/grid-columns/:gridViewColumnId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(gridColumnUpdate, 'gridColumnUpdate')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -8,6 +8,7 @@ import Model from '../../../noco-models/Model';
|
||||
import populateSamplePayload from '../helpers/populateSamplePayload';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import { Tele } from 'nc-help';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
export async function hookList(
|
||||
req: Request<any, any, any>,
|
||||
@@ -77,26 +78,32 @@ export async function tableSampleData(req: Request, res: Response) {
|
||||
const router = Router({ mergeParams: true });
|
||||
router.get(
|
||||
'/api/v1/db/meta/tables/:tableId/hooks',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(hookList, 'hookList')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/tables/:tableId/hooks/test',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(hookTest, 'hookTest')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/tables/:tableId/hooks',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(hookCreate, 'hookCreate')
|
||||
);
|
||||
router.delete(
|
||||
'/api/v1/db/meta/hooks/:hookId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(hookDelete, 'hookDelete')
|
||||
);
|
||||
router.patch(
|
||||
'/api/v1/db/meta/hooks/:hookId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(hookUpdate, 'hookUpdate')
|
||||
);
|
||||
router.get(
|
||||
'/api/v1/db/meta/tables/:tableId/hooks/samplePayload/:operation',
|
||||
metaApiMetrics,
|
||||
catchError(tableSampleData)
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -12,6 +12,7 @@ import Project from '../../../noco-models/Project';
|
||||
import Filter from '../../../noco-models/Filter';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import { Tele } from 'nc-help';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
// @ts-ignore
|
||||
export async function filterGet(req: Request, res: Response, next) {
|
||||
@@ -108,25 +109,34 @@ export async function filterDelete(req: Request, res: Response, next) {
|
||||
}
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
router.get('/hooks/:hookId/filters/', ncMetaAclMw(filterList, 'filterList'));
|
||||
router.get(
|
||||
'/hooks/:hookId/filters/',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(filterList, 'filterList')
|
||||
);
|
||||
router.post(
|
||||
'/hooks/:hookId/filters/',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(filterCreate, 'filterCreate')
|
||||
);
|
||||
router.get(
|
||||
'/hooks/:hookId/filters/:filterId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(filterGet, 'filterGet')
|
||||
);
|
||||
router.patch(
|
||||
'/hooks/:hookId/filters/:filterId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(filterUpdate, 'filterUpdate')
|
||||
);
|
||||
router.delete(
|
||||
'/hooks/:hookId/filters/:filterId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(filterDelete, 'filterDelete')
|
||||
);
|
||||
router.get(
|
||||
'/hooks/:hookId/filters/:filterParentId/children',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(filterChildrenRead, 'filterChildrenRead')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -16,6 +16,7 @@ import getTableNameAlias, { getColumnNameAlias } from '../helpers/getTableName';
|
||||
import mapDefaultPrimaryValue from '../helpers/mapDefaultPrimaryValue';
|
||||
import { Tele } from 'nc-help';
|
||||
import getColumnUiType from '../helpers/getColumnUiType';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
export enum MetaDiffType {
|
||||
TABLE_NEW = 'TABLE_NEW',
|
||||
@@ -849,10 +850,12 @@ export async function extractAndGenerateManyToManyRelations(
|
||||
const router = Router();
|
||||
router.get(
|
||||
'/api/v1/db/meta/projects/:projectId/meta-diff',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(metaDiff, 'metaDiff')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/projects/:projectId/meta-diff',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(metaDiffSync, 'metaDiffSync')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Router } from 'express';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import { Tele } from 'nc-help';
|
||||
import Project from '../../../noco-models/Project';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
async function xcVisibilityMetaSetAll(req, res) {
|
||||
Tele.emit('evt', { evt_type: 'uiAcl:updated' });
|
||||
for (const d of req.body) {
|
||||
@@ -108,6 +109,7 @@ export async function xcVisibilityMetaGet(
|
||||
const router = Router({ mergeParams: true });
|
||||
router.get(
|
||||
'/api/v1/db/meta/projects/:projectId/visibility-rules',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(async (req, res) => {
|
||||
res.json(
|
||||
await xcVisibilityMetaGet(
|
||||
@@ -120,6 +122,7 @@ router.get(
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/projects/:projectId/visibility-rules',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(xcVisibilityMetaSetAll, 'modelVisibilitySet')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -5,6 +5,7 @@ import { PluginType } from 'nocodb-sdk';
|
||||
import NcPluginMgrv2 from '../helpers/NcPluginMgrv2';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import { Tele } from 'nc-help';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
export async function pluginList(_req: Request, res: Response) {
|
||||
res.json(new PagedResponseImpl(await Plugin.list()));
|
||||
@@ -34,21 +35,29 @@ export async function isPluginActive(req: Request, res: Response) {
|
||||
}
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
router.get('/api/v1/db/meta/plugins', ncMetaAclMw(pluginList, 'pluginList'));
|
||||
router.get(
|
||||
'/api/v1/db/meta/plugins',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(pluginList, 'pluginList')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/plugins/test',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(pluginTest, 'pluginTest')
|
||||
);
|
||||
router.get(
|
||||
'/api/v1/db/meta/plugins/:pluginId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(pluginRead, 'pluginRead')
|
||||
);
|
||||
router.patch(
|
||||
'/api/v1/db/meta/plugins/:pluginId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(pluginUpdate, 'pluginUpdate')
|
||||
);
|
||||
router.get(
|
||||
'/api/v1/db/meta/plugins/:pluginTitle/status',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(isPluginActive, 'isPluginActive')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -22,6 +22,7 @@ import { NcError } from '../helpers/catchError';
|
||||
import getColumnUiType from '../helpers/getColumnUiType';
|
||||
import mapDefaultPrimaryValue from '../helpers/mapDefaultPrimaryValue';
|
||||
import { extractAndGenerateManyToManyRelations } from './metaDiffApis';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 4);
|
||||
|
||||
@@ -392,22 +393,27 @@ export async function projectInfoGet(req, res) {
|
||||
export default router => {
|
||||
router.get(
|
||||
'/api/v1/db/meta/projects/:projectId/info',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(projectInfoGet, 'projectInfoGet')
|
||||
);
|
||||
router.get(
|
||||
'/api/v1/db/meta/projects/:projectId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(projectGet, 'projectGet')
|
||||
);
|
||||
router.delete(
|
||||
'/api/v1/db/meta/projects/:projectId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(projectDelete, 'projectDelete')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/projects',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(projectCreate, 'projectCreate')
|
||||
);
|
||||
router.get(
|
||||
'/api/v1/db/meta/projects',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(projectList, 'projectList')
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@ import * as ejs from 'ejs';
|
||||
import NcPluginMgrv2 from '../helpers/NcPluginMgrv2';
|
||||
import Noco from '../../Noco';
|
||||
import { PluginCategory } from 'nocodb-sdk';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
async function userList(req, res) {
|
||||
res.json({
|
||||
@@ -297,22 +298,27 @@ async function sendInviteEmail(
|
||||
const router = Router({ mergeParams: true });
|
||||
router.get(
|
||||
'/api/v1/db/meta/projects/:projectId/users',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(userList, 'userList')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/projects/:projectId/users',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(userInvite, 'userInvite')
|
||||
);
|
||||
router.patch(
|
||||
'/api/v1/db/meta/projects/:projectId/users/:userId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(projectUserUpdate, 'projectUserUpdate')
|
||||
);
|
||||
router.delete(
|
||||
'/api/v1/db/meta/projects/:projectId/users/:userId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(projectUserDelete, 'projectUserDelete')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/projects/:projectId/users/:userId/resend-invite',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(projectUserInviteResend, 'projectUserInviteResend')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -11,6 +11,7 @@ import Project from '../../../noco-models/Project';
|
||||
import Sort from '../../../noco-models/Sort';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import { Tele } from 'nc-help';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
// @ts-ignore
|
||||
export async function sortGet(req: Request, res: Response<TableType>) {}
|
||||
@@ -51,19 +52,27 @@ export async function sortDelete(req: Request, res: Response) {
|
||||
const router = Router({ mergeParams: true });
|
||||
router.get(
|
||||
'/api/v1/db/meta/views/:viewId/sorts/',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(sortList, 'sortList')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/views/:viewId/sorts/',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(sortCreate, 'sortCreate')
|
||||
);
|
||||
router.get('/api/v1/db/meta/sorts/:sortId', ncMetaAclMw(sortGet, 'sortGet'));
|
||||
router.get(
|
||||
'/api/v1/db/meta/sorts/:sortId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(sortGet, 'sortGet')
|
||||
);
|
||||
router.patch(
|
||||
'/api/v1/db/meta/sorts/:sortId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(sortUpdate, 'sortUpdate')
|
||||
);
|
||||
router.delete(
|
||||
'/api/v1/db/meta/sorts/:sortId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(sortDelete, 'sortDelete')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -26,6 +26,7 @@ import Column from '../../../noco-models/Column';
|
||||
import NcConnectionMgrv2 from '../../common/NcConnectionMgrv2';
|
||||
import getColumnUiType from '../helpers/getColumnUiType';
|
||||
import LinkToAnotherRecordColumn from '../../../noco-models/LinkToAnotherRecordColumn';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
export async function tableGet(req: Request, res: Response<TableType>) {
|
||||
const table = await Model.getWithInfo({
|
||||
id: req.params.tableId
|
||||
@@ -264,26 +265,32 @@ export async function tableDelete(req: Request, res: Response) {
|
||||
const router = Router({ mergeParams: true });
|
||||
router.get(
|
||||
'/api/v1/db/meta/projects/:projectId/tables',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(tableList, 'tableList')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/projects/:projectId/tables',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(tableCreate, 'tableCreate')
|
||||
);
|
||||
router.get(
|
||||
'/api/v1/db/meta/tables/:tableId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(tableGet, 'tableGet')
|
||||
);
|
||||
router.patch(
|
||||
'/api/v1/db/meta/tables/:tableId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(tableUpdate, 'tableUpdate')
|
||||
);
|
||||
router.delete(
|
||||
'/api/v1/db/meta/tables/:tableId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(tableDelete, 'tableDelete')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/tables/:tableId/reorder',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(tableReorder, 'tableReorder')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -13,6 +13,7 @@ import View from '../../../noco-models/View';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import { xcVisibilityMetaGet } from './modelVisibilityApis';
|
||||
import { Tele } from 'nc-help';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
// @ts-ignore
|
||||
export async function viewGet(req: Request, res: Response<Table>) {}
|
||||
|
||||
@@ -103,27 +104,33 @@ async function shareViewList(req: Request<any, any>, res) {
|
||||
const router = Router({ mergeParams: true });
|
||||
router.get(
|
||||
'/api/v1/db/meta/tables/:tableId/views',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(viewList, 'viewList')
|
||||
);
|
||||
router.patch(
|
||||
'/api/v1/db/meta/views/:viewId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(viewUpdate, 'viewUpdate')
|
||||
);
|
||||
router.delete(
|
||||
'/api/v1/db/meta/views/:viewId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(viewDelete, 'viewDelete')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/views/:viewId/show-all',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(showAllColumns, 'showAllColumns')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/views/:viewId/hide-all',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(hideAllColumns, 'hideAllColumns')
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/api/v1/db/meta/tables/:tableId/share',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(shareViewList, 'shareViewList')
|
||||
);
|
||||
router.post(
|
||||
@@ -132,10 +139,12 @@ router.post(
|
||||
);
|
||||
router.patch(
|
||||
'/api/v1/db/meta/views/:viewId/share',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(shareViewPasswordUpdate, 'shareViewPasswordUpdate')
|
||||
);
|
||||
router.delete(
|
||||
'/api/v1/db/meta/views/:viewId/share',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(shareViewDelete, 'shareViewDelete')
|
||||
);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Request, Response, Router } from 'express';
|
||||
import View from '../../../noco-models/View';
|
||||
import ncMetaAclMw from '../helpers/ncMetaAclMw';
|
||||
import { Tele } from 'nc-help';
|
||||
import { metaApiMetrics } from '../helpers/apiMetrics';
|
||||
|
||||
export async function columnList(req: Request, res: Response) {
|
||||
res.json(await View.getColumns(req.params.viewId));
|
||||
@@ -33,14 +34,17 @@ export async function columnUpdate(req: Request, res: Response) {
|
||||
const router = Router({ mergeParams: true });
|
||||
router.get(
|
||||
'/api/v1/db/meta/views/:viewId/columns/',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(columnList, 'columnList')
|
||||
);
|
||||
router.post(
|
||||
'/api/v1/db/meta/views/:viewId/columns/',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(columnAdd, 'columnAdd')
|
||||
);
|
||||
router.patch(
|
||||
'/api/v1/db/meta/views/:viewId/columns/:columnId',
|
||||
metaApiMetrics,
|
||||
ncMetaAclMw(columnUpdate, 'viewColumnUpdate')
|
||||
);
|
||||
export default router;
|
||||
|
||||
@@ -3,17 +3,23 @@ import { Tele } from 'nc-help';
|
||||
|
||||
const countMap = {};
|
||||
|
||||
const metrics = async (req: Request) => {
|
||||
const metrics = async (req: Request, c = 50) => {
|
||||
if (!req?.route?.path) return;
|
||||
const event = `a:api:${req.route.path}:${req.method}`;
|
||||
countMap[event] = (countMap[event] || 0) + 1;
|
||||
if (countMap[event] >= 50) {
|
||||
if (countMap[event] >= c) {
|
||||
Tele.event({ event });
|
||||
countMap[event] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
export default async (req: Request, _res, next) => {
|
||||
const metaApiMetrics = (req: Request, _res, next) => {
|
||||
metrics(req, 10).then(() => {});
|
||||
next();
|
||||
};
|
||||
export default (req: Request, _res, next) => {
|
||||
metrics(req).then(() => {});
|
||||
next();
|
||||
};
|
||||
|
||||
export { metaApiMetrics };
|
||||
|
||||
@@ -12,7 +12,7 @@ export const genTest = (apiType, dbType) => {
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.get(".mdi-close").click({ multiple: true });
|
||||
cy.get(".mdi-close").click({ multiple: true, force: true });
|
||||
});
|
||||
|
||||
const name = "tablex";
|
||||
|
||||
@@ -162,14 +162,16 @@ Cypress.Commands.add("openTableTab", (tn, rc) => {
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(".nc-project-tree")
|
||||
.contains(tn, { timeout: 6000 })
|
||||
.contains(tn)
|
||||
.should('exist')
|
||||
.first()
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(`.project-tab`).contains(tn, { timeout: 10000 }).should("exist");
|
||||
cy.get(`.project-tab`).contains(tn).should("exist");
|
||||
|
||||
cy.get(".nc-project-tree")
|
||||
.find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
|
||||
.find(".v-list-item__title:contains(Tables)")
|
||||
.should('exist')
|
||||
.first()
|
||||
.click({ force: true });
|
||||
|
||||
@@ -221,7 +223,7 @@ Cypress.Commands.add("openOrCreateGqlProject", (_args) => {
|
||||
cy.contains("GRAPHQL APIs").closest("label").click();
|
||||
cy.get(".database-field input").click().clear().type("sakila");
|
||||
cy.contains("Test Database Connection").click();
|
||||
cy.contains("Ok & Save Project", { timeout: 3000 }).click();
|
||||
cy.contains("Ok & Save Project").should('exist').click();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -280,11 +282,13 @@ Cypress.Commands.add("createTable", (name) => {
|
||||
|
||||
Cypress.Commands.add("deleteTable", (name, dbType) => {
|
||||
cy.get(".nc-project-tree")
|
||||
.find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
|
||||
.find(".v-list-item__title:contains(Tables)")
|
||||
.should('exist')
|
||||
.first()
|
||||
.click();
|
||||
cy.get(".nc-project-tree")
|
||||
.contains(name, { timeout: 6000 })
|
||||
.contains(name)
|
||||
.should('exist')
|
||||
.first()
|
||||
.click({ force: true });
|
||||
cy.get(`.project-tab:contains(${name}):visible`).should("exist");
|
||||
@@ -301,13 +305,15 @@ Cypress.Commands.add("deleteTable", (name, dbType) => {
|
||||
Cypress.Commands.add("renameTable", (oldName, newName) => {
|
||||
// expand project tree
|
||||
cy.get(".nc-project-tree")
|
||||
.find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
|
||||
.find(".v-list-item__title:contains(Tables)")
|
||||
.should('exist')
|
||||
.first()
|
||||
.click();
|
||||
|
||||
// right click on project table name
|
||||
cy.get(".nc-project-tree")
|
||||
.contains(oldName, { timeout: 6000 })
|
||||
.contains(oldName)
|
||||
.should('exist')
|
||||
.first()
|
||||
.rightclick();
|
||||
|
||||
@@ -328,18 +334,23 @@ Cypress.Commands.add("renameTable", (oldName, newName) => {
|
||||
|
||||
// close expanded project tree
|
||||
cy.get(".nc-project-tree")
|
||||
.find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
|
||||
.find(".v-list-item__title:contains(Tables)")
|
||||
.should('exist')
|
||||
.first()
|
||||
.click();
|
||||
|
||||
cy.wait(8000)
|
||||
});
|
||||
|
||||
Cypress.Commands.add("createColumn", (table, columnName) => {
|
||||
cy.get(".nc-project-tree")
|
||||
.find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
|
||||
.find(".v-list-item__title:contains(Tables)")
|
||||
.should('exist')
|
||||
.first()
|
||||
.click();
|
||||
cy.get(".nc-project-tree")
|
||||
.contains(table, { timeout: 6000 })
|
||||
.contains(table)
|
||||
.should('exist')
|
||||
.first()
|
||||
.click({ force: true });
|
||||
cy.get(`.project-tab:contains(${table}):visible`).should("exist");
|
||||
@@ -366,7 +377,7 @@ Cypress.Commands.add("openViewsTab", (vn, rc) => {
|
||||
cy.task("log", `[openViewsTab] ${vn} ${rc}`);
|
||||
|
||||
cy.get(".nc-project-tree")
|
||||
.find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
|
||||
.find(".v-list-item__title:contains(Tables)")
|
||||
.should("exist")
|
||||
.first()
|
||||
.click({ force: true });
|
||||
@@ -376,10 +387,11 @@ Cypress.Commands.add("openViewsTab", (vn, rc) => {
|
||||
.first()
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(`.project-tab`).contains(vn, { timeout: 10000 }).should("exist");
|
||||
cy.get(`.project-tab`).contains(vn).should("exist");
|
||||
|
||||
cy.get(".nc-project-tree")
|
||||
.find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
|
||||
.find(".v-list-item__title:contains(Tables)")
|
||||
.should('exist')
|
||||
.first()
|
||||
.click({ force: true });
|
||||
|
||||
@@ -391,7 +403,7 @@ Cypress.Commands.add("openViewsTab", (vn, rc) => {
|
||||
|
||||
Cypress.Commands.add("closeViewsTab", (vn) => {
|
||||
cy.task("log", `[closeViewsTab] ${vn}`);
|
||||
cy.get(`.project-tab`).contains(vn, { timeout: 10000 }).should("exist");
|
||||
cy.get(`.project-tab`).contains(vn).should("exist");
|
||||
cy.get(`[href="#view||||${vn}"]`)
|
||||
.find("button.mdi-close")
|
||||
.click({ force: true });
|
||||
|
||||
Reference in New Issue
Block a user