mirror of
https://github.com/nocodb/nocodb.git
synced 2026-04-30 21:56:57 +00:00
Xmysql is now NocoDB (An Open Source Airtable alternative)
This commit is contained in:
808
packages/nc-gui/components/project/apiClientOld.vue
Normal file
808
packages/nc-gui/components/project/apiClientOld.vue
Normal file
@@ -0,0 +1,808 @@
|
||||
<template>
|
||||
<v-container fluid class="api-client grid-list-xs pa-0 " style="height: 100%;">
|
||||
<splitpanes style="height:100%;" class="xc-theme">
|
||||
<pane min-size="20" max-size="50" size="30" style="overflow: auto">
|
||||
|
||||
|
||||
<v-tabs height="32">
|
||||
<v-tab>History</v-tab>
|
||||
<v-tab>Collection</v-tab>
|
||||
|
||||
|
||||
<v-tab-item style="border-top: 1px solid grey">
|
||||
<div class="apis-list">
|
||||
<div v-for="(api,i) in $store.state.apiClient.list" :key="i" class="pa-0 ma-0 ">
|
||||
<v-list-item dense two-line @click="apiClickedOnList(api)">
|
||||
|
||||
<v-hover v-slot:default="{ hover }">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title class="grey--text">
|
||||
<v-btn class="pl-0 ml-0" small text :tooltip="api.url" :color="apiMeta[api.type].color"
|
||||
>
|
||||
<b>
|
||||
<v-icon class="mx-0 ml-n2"
|
||||
:class="{'white--text': !api.response || !api.response.status,'red--text': api.response && api.response.status >= 400, 'green--text':api.response && api.response.status < 400}">
|
||||
mdi-circle-small
|
||||
</v-icon>
|
||||
{{api.type}} </b>
|
||||
</v-btn>
|
||||
|
||||
|
||||
{{api.url}}
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle v-show="!i || hover" class="text-right">
|
||||
<span v-show="!i && !hover" class="grey--text text--darken-1 caption">(Last invoked API)</span>
|
||||
<v-btn small text v-show="hover" class=" " @click="apiDeleteFromList(i)">
|
||||
<v-icon small>mdi-delete</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-hover>
|
||||
</v-list-item>
|
||||
<v-divider></v-divider>
|
||||
</div>
|
||||
</div>
|
||||
</v-tab-item>
|
||||
<v-tab-item style="border-top: 1px solid grey">
|
||||
<v-row class="pa-0 ma-0 pa-2 pl-2">
|
||||
<div class="primary--text cursor-pointer" @click="openApiFileCollection">
|
||||
<x-icon class="mr-1 cursor-pointer" @click="openNewCollection('/')" color="primary"
|
||||
tooltip="Create New API Collection">mdi-folder-plus-outline
|
||||
</x-icon>
|
||||
|
||||
<x-icon class="mr-1" color="primary" tooltip="Open API Collection">mdi-folder-open-outline</x-icon>
|
||||
|
||||
</div>
|
||||
</v-row>
|
||||
<v-divider></v-divider>
|
||||
<v-expansion-panels accordion focusable v-model="curApiCollectionPanel">
|
||||
<v-expansion-panel
|
||||
v-for="(apiTv,i) in apiTvs"
|
||||
:key="i">
|
||||
<v-expansion-panel-header hide-actions>
|
||||
<template v-slot:default="{open}">
|
||||
<div class="d-flex">
|
||||
|
||||
<v-icon color="">{{open ? 'mdi-menu-down' : 'mdi-menu-right' }}</v-icon>
|
||||
<v-icon small color="grey" class="ml-1 mr-2">mdi-folder</v-icon>
|
||||
<span class="body-2 flex-grow-1">{{$store.getters['apiClient/GtrCurrentApiFilePaths'][i].fileName}}</span>
|
||||
|
||||
<x-icon color="white grey" class="float-right mr-3" small
|
||||
@click="showCtxMenu[i]=true,x = $event.clientX,y = $event.clientY;"
|
||||
@click.stop="">
|
||||
mdi-dots-horizontal
|
||||
</x-icon>
|
||||
|
||||
<recursive-menu v-model="showCtxMenu[i]"
|
||||
:position-x="x"
|
||||
:position-y="y"
|
||||
:items="{
|
||||
'Add Folder':'add-folder',
|
||||
'Reveal in Folder':'reveal-in-folder',
|
||||
'Delete Collection':'delete-collection',
|
||||
'Refresh Collection' : 'refresh-collection'
|
||||
}"
|
||||
@click="ctxMenuClickHandler($event,i)">
|
||||
</recursive-menu>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
</v-expansion-panel-header>
|
||||
<v-expansion-panel-content class="expansion-wrap-0">
|
||||
<vue-tree-list
|
||||
style="cursor: pointer"
|
||||
v-if="apiTvs[i]"
|
||||
class="body-2 sql-query-treeview px-1 pt-2 api-treeview"
|
||||
@click="tvNodeOnClick"
|
||||
@change-name="tvNodeRename"
|
||||
@delete-node="tvNodeDelete"
|
||||
@add-node="onAddNode"
|
||||
:model="apiTv"
|
||||
default-tree-node-name="new node"
|
||||
default-leaf-node-name="new leaf"
|
||||
v-bind:default-expanded="false"><span slot="leafNodeIcon"></span>
|
||||
<v-icon slot="treeNodeIcon" small color="grey" class="mr-1">mdi-folder-star</v-icon>
|
||||
|
||||
<v-icon slot="addTreeNode" small>mdi-folder-plus</v-icon>
|
||||
<v-icon slot="addLeafNode" small>mdi-file-plus</v-icon>
|
||||
<v-icon slot="editNode" small class="mt-n1">mdi-file-edit</v-icon>
|
||||
<v-icon slot="delNode" small>mdi-delete</v-icon>
|
||||
<template v-slot:label="{item:api}">
|
||||
<div v-if="api.isLeaf" class="d-flex" style="width: 100%">
|
||||
<!-- <v-icon class="mx-0"-->
|
||||
<!-- :class="`${apiMeta[api.type].color}--text`"-->
|
||||
<!-- small>-->
|
||||
<!-- mdi-bookmark-outline-->
|
||||
<!-- </v-icon>-->
|
||||
<b style="display: inline-block;min-width: 45px;" :class="`${apiMeta[api.type].color}--text`">
|
||||
{{api.type === 'DELETE' ? 'DEL' : api.type}} </b>
|
||||
|
||||
<span class="grey--text d-block" style="text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;">{{api.name}}</span>
|
||||
</div>
|
||||
<div v-else style="width: 100%;text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;">{{api.name}}
|
||||
</div>
|
||||
</template>
|
||||
</vue-tree-list>
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
</v-tab-item>
|
||||
</v-tabs>
|
||||
</pane>
|
||||
<pane min-size="10" size="75" style="overflow: auto">
|
||||
|
||||
<v-toolbar class=" toolbar-border-bottom elevation-0 d-flex req-inputs" height="55"
|
||||
style="position: relative;z-index:2;width: 100%">
|
||||
|
||||
<v-select
|
||||
:items="Object.keys(apiMeta)"
|
||||
v-model="api.type"
|
||||
dense
|
||||
solo
|
||||
hide-details
|
||||
outlined
|
||||
class="body-2"
|
||||
style="max-width:130px;border-bottom-right-radius: 0;border-top-right-radius: 0;border-right: 1px solid grey"
|
||||
></v-select>
|
||||
|
||||
|
||||
<xAutoComplete
|
||||
outlined
|
||||
class="flex-grow-1"
|
||||
:env="selectedEnv"
|
||||
placeholder="Enter HTTP URL"
|
||||
solo
|
||||
dense
|
||||
hide-details
|
||||
autofocus
|
||||
styles="border-bottom-left-radius: 0;border-top-left-radius:0 "
|
||||
v-model="api.url"></xAutoComplete>
|
||||
|
||||
|
||||
<x-btn btn.class="primary" dense @click.prevent="apiSend()" tooltip="Send Request">
|
||||
<v-icon small class="ml-n3" v-if="isPerfFilled">mdi-truck-fast</v-icon>
|
||||
<v-icon small class="ml-n3" v-else>mdi-send</v-icon>
|
||||
SEND
|
||||
</x-btn>
|
||||
<x-btn btn.class="outlined" dense @click.prevent="bookmarkApi()" icon="save"
|
||||
tooltip="Save API">
|
||||
</x-btn>
|
||||
<x-btn icon="mdi-eye-outline" v-if="$store.getters['project/GtrProjectJson']"
|
||||
@click="environmentDialog = true" tooltip="Environments">
|
||||
|
||||
</x-btn>
|
||||
|
||||
</v-toolbar>
|
||||
|
||||
|
||||
<splitpanes horizontal style="height:calc(100% - 64px)" class="xc-theme">
|
||||
<pane min-size="25" size="50" style="overflow: auto;" class="pa-1">
|
||||
|
||||
<v-tabs
|
||||
class="req-tabs"
|
||||
height="24"
|
||||
>
|
||||
<v-tab class="caption">Params <b v-if="paramsCount" class="green--text">({{paramsCount}})</b>
|
||||
</v-tab>
|
||||
<v-tab class="caption">Headers <b v-if="headersCount" class="green--text">({{headersCount }})</b>
|
||||
</v-tab>
|
||||
<v-tab class="caption">Body</v-tab>
|
||||
<v-tab class="caption">Auth</v-tab>
|
||||
<v-tab class="caption">Perf Test</v-tab>
|
||||
<div class="flex-grow-1 d-flex text-right pr-4 justify-end ">
|
||||
<div class="flex-shrink-1 ">
|
||||
<v-select
|
||||
v-model="selectedEnv"
|
||||
height="19"
|
||||
class="caption envs"
|
||||
dense
|
||||
:items="environmentList"
|
||||
placeholder="Environment"
|
||||
single-line
|
||||
>
|
||||
<template v-slot:selection="{item}">
|
||||
<span
|
||||
style="text-transform: uppercase">{{item}}</span> <span class="grey--text">(env)</span>
|
||||
</template>
|
||||
|
||||
</v-select>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="flex-grow-1 text-right pr-4 caption" v-if="api.response">-->
|
||||
<!-- <!– <x-icon iconClass="mr-4" v-if="$store.getters['project/GtrProjectJson']" @click="environmentDialog = true" tooltip="Environments">–>-->
|
||||
<!-- <!– mdi-eye-outline–>-->
|
||||
<!-- <!– </x-icon>–>-->
|
||||
<!-- </div>-->
|
||||
<v-tab-item>
|
||||
|
||||
<params v-model="api.params"
|
||||
:env.sync="selectedEnv"
|
||||
></params>
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<headers v-model="api.headers"
|
||||
:env.sync="selectedEnv"
|
||||
></headers>
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<monaco-json-editor
|
||||
style="height: 250px"
|
||||
class="editor card"
|
||||
theme="vs-dark"
|
||||
v-model="api.body"
|
||||
language="json"
|
||||
:options="{validate:true,documentFormattingEdits:true,foldingRanges:true}"
|
||||
>
|
||||
</monaco-json-editor>
|
||||
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<!-- <monaco-editor-->
|
||||
<!-- :code.sync="api.auth"-->
|
||||
<!-- cssStyle="height:250px"></monaco-editor>-->
|
||||
</v-tab-item>
|
||||
|
||||
<v-tab-item>
|
||||
<perf-test v-model="api.perf"></perf-test>
|
||||
</v-tab-item>
|
||||
|
||||
</v-tabs>
|
||||
</pane>
|
||||
<pane min-size="25" size="50" style="overflow: auto" class="pa-1">
|
||||
<!-- <h3 class="mb-2 grey--text lighten-1">-->
|
||||
<!-- Response Body :-->
|
||||
<!-- <div v-if="api.response">-->
|
||||
<!-- <span v-if="api.response.status === 200" class="green--text">{{api.response.status}}</span>-->
|
||||
<!-- <span v-if="api.response.status !== 200" class="red--text">{{api.response.status}}</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- </h3>-->
|
||||
|
||||
|
||||
<v-tabs
|
||||
v-if="api.response"
|
||||
height="24"
|
||||
>
|
||||
<v-tab class="caption">Body</v-tab>
|
||||
<v-tab class="caption">Headers<span class="green--text" v-if="api.response.headers">( {{Object.keys(api.response.headers).length}} )</span>
|
||||
</v-tab>
|
||||
<div class="flex-grow-1 text-right pr-4 caption" v-if="api.response">
|
||||
<template v-if="api.response.status"><span class="grey--text">Status:</span><span :class="{
|
||||
'green--text' : api.response.status === 200 ,
|
||||
'red--text' : api.response.status !== 200
|
||||
}"><b>{{api.response.status}}</b></span></template>
|
||||
|
||||
|
||||
<template v-if="api.timeTaken"><span class="grey--text">Time:</span><span class="green--text"><b>{{api.timeTaken}}ms</b></span>
|
||||
</template>
|
||||
|
||||
|
||||
</div>
|
||||
<v-tab-item>
|
||||
<code v-if="api.response" class="black pa-1 grey--text "
|
||||
style="overflow-x: auto;min-height:50px;overflow-y:auto;min-width: 100%">{{api.response.data}}</code>
|
||||
|
||||
<!-- <pre v-if="api.response" class="black pa-1" style="overflow-x: auto;min-height:50px;overflow-y:auto">{{api.response.data}}</pre>-->
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<code v-if="api.response" class="black pa-1 grey--text "
|
||||
style="overflow-x: auto;min-height:50px;overflow-y:auto;min-width: 100%">{{api.response.headers}}</code>
|
||||
</v-tab-item>
|
||||
</v-tabs>
|
||||
</pane>
|
||||
</splitpanes>
|
||||
|
||||
</pane>
|
||||
</splitpanes>
|
||||
<environment v-if="$store.getters['project/GtrProjectJson']" env="dev" v-model="environmentDialog"></environment>
|
||||
|
||||
</v-container>
|
||||
</template>
|
||||
<script>
|
||||
import {mapGetters, mapActions} from "vuex";
|
||||
|
||||
import Vue from 'vue';
|
||||
|
||||
|
||||
import {VueTreeList, Tree, TreeNode} from 'vue-tree-list'
|
||||
import {Splitpanes, Pane} from 'splitpanes'
|
||||
import params from "../apiClient/params";
|
||||
import headers from "../apiClient/headers";
|
||||
|
||||
import {MonacoJsonEditor} from "../monaco/index";
|
||||
|
||||
import environment from "../environment";
|
||||
import PerfTest from "../apiClient/perfTest";
|
||||
|
||||
// const {app, dialog, path, fs, shell, FileCollection} = require("electron").remote.require(
|
||||
// "./libs"
|
||||
// );
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PerfTest,
|
||||
MonacoJsonEditor,
|
||||
VueTreeList,
|
||||
Splitpanes, Pane,
|
||||
params,
|
||||
headers,
|
||||
environment
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
environmentDialog: false,
|
||||
showCtxMenu: {},
|
||||
apiTvs: [],
|
||||
apiFilePaths: [],
|
||||
apiFileCollections: [],
|
||||
curApiCollectionPanel: null,
|
||||
|
||||
x: 0,
|
||||
y: 0,
|
||||
|
||||
apiMeta: {
|
||||
GET: {
|
||||
color: 'success'
|
||||
},
|
||||
POST: {
|
||||
color: 'warning'
|
||||
},
|
||||
DELETE: {
|
||||
color: 'error'
|
||||
},
|
||||
PUT: {
|
||||
color: 'info'
|
||||
},
|
||||
HEAD: {
|
||||
color: 'info'
|
||||
},
|
||||
PATCH: {
|
||||
color: 'info'
|
||||
},
|
||||
},
|
||||
|
||||
// current api
|
||||
api: {
|
||||
type: 'GET',
|
||||
url: '',
|
||||
body: '',
|
||||
params: [],
|
||||
auth: '',
|
||||
headers: [],
|
||||
response: {},
|
||||
perf: {}
|
||||
},
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isPerfFilled() {
|
||||
return this.api.perf && Object.values(this.api.perf).some(v => v)
|
||||
},
|
||||
...mapGetters({
|
||||
sqlMgr: "sqlMgr/sqlMgr",
|
||||
currentProjectFolder: "project/currentProjectFolder",
|
||||
projectApisFolder: "project/projectApisFolder"
|
||||
}),
|
||||
paramsCount() {
|
||||
return this.api.params && this.api.params.filter(p => p.name && p.enabled).length;
|
||||
},
|
||||
headersCount() {
|
||||
|
||||
return this.api.headers && this.api.headers.filter(h => h.name && h.enabled).length;
|
||||
},
|
||||
environmentList() {
|
||||
return Object.keys(this.$store.getters['project/GtrApiEnvironment']);
|
||||
},
|
||||
selectedEnv: {
|
||||
get() {
|
||||
return this.$store.state.apiClient.activeEnvironment[this.$route.params.project] || this.environmentList[0];
|
||||
}, set(env) {
|
||||
this.$store.commit('apiClient/MutActiveEnvironment', {env, projectId: this.$route.params.project});
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async handleKeyDown({metaKey, key, altKey, shiftKey, ctrlKey}) {
|
||||
console.log(metaKey, key, altKey, shiftKey, ctrlKey)
|
||||
// cmd + s -> save
|
||||
// cmd + l -> reload
|
||||
// cmd + n -> new
|
||||
// cmd + d -> delete
|
||||
// cmd + enter -> send api
|
||||
|
||||
switch ([metaKey, key].join('_')) {
|
||||
case 'true_s' :
|
||||
await this.bookmarkApi();
|
||||
break;
|
||||
case 'true_e' :
|
||||
this.environmentDialog = true
|
||||
break;
|
||||
// case 'true_n' :
|
||||
// this.addColumn();
|
||||
// break;
|
||||
case 'true_d' :
|
||||
await this.deleteProcedure('showDialog');
|
||||
break;
|
||||
case 'true_Enter' :
|
||||
await this.apiSend();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
async openCollectionFolder(pathString) {
|
||||
shell.showItemInFolder(pathString);
|
||||
},
|
||||
async openNewCollection() {
|
||||
try {
|
||||
var toLocalPath = path.join(this.currentProjectFolder, 'server', 'tool', this.projectApisFolder);
|
||||
|
||||
var userChosenPath = dialog.showSaveDialog({
|
||||
defaultPath: toLocalPath,
|
||||
filters: [{name: 'JSON', extensions: ['json']}]
|
||||
});
|
||||
|
||||
if (userChosenPath) {
|
||||
console.log(userChosenPath)
|
||||
fs.writeFileSync(userChosenPath, "[]", 'utf-8');
|
||||
let pathObj = {
|
||||
path: userChosenPath,
|
||||
fileName: path.basename(userChosenPath)
|
||||
};
|
||||
this.$store.commit('apiClient/MutApiFilePathsAdd', pathObj)
|
||||
await this.loadFileCollection(pathObj);
|
||||
}
|
||||
this.$toast.success('New API collection loaded successfully').goAway(5000);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
},
|
||||
async ctxMenuClickHandler(actionEvent, index) {
|
||||
console.log(actionEvent, index);
|
||||
switch (actionEvent.value) {
|
||||
case 'add-folder':
|
||||
this.tvNodeFolderAdd(index);
|
||||
break;
|
||||
case 'reveal-in-folder':
|
||||
await this.openCollectionFolder(this.$store.getters['apiClient/GtrCurrentApiFilePaths'][index].path)
|
||||
break;
|
||||
case 'delete-collection':
|
||||
this.$store.commit('apiClient/MutApiFilePathsRemove', index);
|
||||
this.apiFileCollections.splice(index, 1);
|
||||
this.apiTvs.splice(index, 1);
|
||||
break;
|
||||
case 'refresh-collection':
|
||||
await this.refreshFileCollection(index);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//this.deleteQueryByPath(this.apiTvs, this.menuItem.path);
|
||||
},
|
||||
openUrl(url) {
|
||||
shell.openExternal(url);
|
||||
},
|
||||
|
||||
apiClickedOnList(api) {
|
||||
this.api = {
|
||||
...api,
|
||||
params: api.params && api.params.map(param => ({...param})),
|
||||
headers: api.headers && api.headers.map(header => ({...header}))
|
||||
};
|
||||
},
|
||||
|
||||
apiDeleteFromList(index) {
|
||||
this.$store.commit('apiClient/MutListRemove', index);
|
||||
},
|
||||
|
||||
async apiSend() {
|
||||
|
||||
console.log('apiSend')
|
||||
|
||||
if (!this.api.url.trim()) {
|
||||
this.$toast.info('Please enter http url').goAway(3000);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const envs = this.$store.getters['project/GtrApiEnvironment'][this.selectedEnv];
|
||||
|
||||
let apiDecoded = JSON.parse(
|
||||
JSON.stringify(this.api).replace(/{{\s*(\w+)\s*}}/g, (m, m1) => {
|
||||
if (m1 in envs) {
|
||||
return envs[m1];
|
||||
} else {
|
||||
this.$toast.info('Environment variable is not found : ' + m1).goAway(3000);
|
||||
return m;
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
let result = await this.$store.dispatch('apiClient/send', {api: this.api, apiDecoded});
|
||||
this.api.response = result;
|
||||
if (result) {
|
||||
if (result.status === 200) {
|
||||
//this.$toast.success('API invoked successfully',{duration:1000});
|
||||
} else {
|
||||
this.$toast.error(`Error:${result.status}`, {duration: 1000});
|
||||
}
|
||||
} else {
|
||||
this.$toast.error(`Some internal error occurred`, {duration: 1000});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
async fileCollectionReload() {
|
||||
let data = new Tree(await this.apiFileCollection.read());
|
||||
console.log(data);
|
||||
|
||||
this.apiTv = data;
|
||||
// this.$set(this, 'apiCollections', data);
|
||||
},
|
||||
|
||||
async tvNodeDelete(node) {
|
||||
console.log(node, this.curApiCollectionPanel)
|
||||
node.remove()
|
||||
await this.savefileCollections(this.curApiCollectionPanel);
|
||||
},
|
||||
|
||||
async tvNodeRename(params) {
|
||||
console.log(params)
|
||||
await this.savefileCollections(this.curApiCollectionPanel);
|
||||
},
|
||||
|
||||
async onAddNode(params) {
|
||||
console.log(params)
|
||||
await this.savefileCollections(this.curApiCollectionPanel);
|
||||
},
|
||||
|
||||
async tvNodeOnClick({parent, children, ...params}) {
|
||||
console.log(params)
|
||||
this.apiClickedOnList(params);
|
||||
// if (params.query) ;
|
||||
// this.selectQuery(params)
|
||||
},
|
||||
|
||||
async savefileCollections(index = 0) {
|
||||
await this.apiFileCollections[index].write({data: this.tvToObject(index)});
|
||||
// this.apiTvs = await this.fileCollections.read();
|
||||
//this.$set(this.apiTvs, index, this.apiTvs);
|
||||
},
|
||||
|
||||
tvToObject(index) {
|
||||
var vm = this
|
||||
|
||||
function _dfs(oldNode) {
|
||||
var newNode = {}
|
||||
|
||||
for (var k in oldNode) {
|
||||
if (k !== 'children' && k !== 'parent') {
|
||||
newNode[k] = oldNode[k]
|
||||
}
|
||||
}
|
||||
|
||||
if (oldNode.children && oldNode.children.length > 0) {
|
||||
newNode.children = []
|
||||
for (var i = 0, len = oldNode.children.length; i < len; i++) {
|
||||
newNode.children.push(_dfs(oldNode.children[i]))
|
||||
}
|
||||
}
|
||||
return newNode
|
||||
}
|
||||
|
||||
return _dfs(vm.apiTvs[index]).children
|
||||
},
|
||||
|
||||
async tvNodeFolderAdd(index) {
|
||||
var node = new TreeNode({name: 'New Folder', isLeaf: false, children: []})
|
||||
if (!this.apiTvs[index].children) this.apiTvs[index].children = []
|
||||
this.apiTvs[index].addChildren(node);
|
||||
|
||||
await this.saveFileCollection(index);
|
||||
|
||||
},
|
||||
|
||||
openApiFileCollection() {
|
||||
const vm = this;
|
||||
// console.log(obj, key);
|
||||
const file = dialog.showOpenDialog({
|
||||
properties: ["openFile"]
|
||||
});
|
||||
|
||||
if (file && file[0]) {
|
||||
let fileName = path.basename(file[0]);
|
||||
const pathObj = {
|
||||
path: file[0] + '',
|
||||
fileName: fileName
|
||||
};
|
||||
|
||||
if (this.$store.getters['apiClient/GtrCurrentApiFilePaths'].every(({path: p}) => p !== pathObj.path)) {
|
||||
this.$store.commit('apiClient/MutApiFilePathsAdd', pathObj)
|
||||
this.loadFileCollection(pathObj);
|
||||
} else {
|
||||
this.$toast.info('File already exist in collection').goAway(4000);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async saveFileCollection(index = 0) {
|
||||
await this.apiFileCollections[index].write({data: this.tvToObject(index)});
|
||||
},
|
||||
|
||||
async loadFileCollection(path, index = 0) {
|
||||
|
||||
try {
|
||||
const fileCollection = new FileCollection(path);
|
||||
await fileCollection.init();
|
||||
|
||||
this.apiFileCollections.push(fileCollection);
|
||||
|
||||
let data = new Tree(await fileCollection.read());
|
||||
this.apiTvs.push(data);
|
||||
} catch (e) {
|
||||
console.log('Error in loadFileCollection:', e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
},
|
||||
async refreshFileCollection(index = 0) {
|
||||
try {
|
||||
const path = this.$store.getters['apiClient/GtrCurrentApiFilePaths'][index];
|
||||
const fileCollection = new FileCollection(path);
|
||||
await fileCollection.init();
|
||||
this.apiFileCollections[index] = fileCollection;
|
||||
const data = new Tree(await fileCollection.read());
|
||||
this.$set(this.apiTvs, index, data);
|
||||
} catch (e) {
|
||||
console.log('Error in loadFileCollection:', e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
async bookmarkApi() {
|
||||
let q = this.api;
|
||||
var node = new TreeNode({
|
||||
"id": Date.now(),
|
||||
"label": "Latest Api",
|
||||
"name": "Last Saved Api",
|
||||
"pid": 0,
|
||||
isLeaf: true,
|
||||
...q
|
||||
})
|
||||
|
||||
let expandedPanelIndex = this.curApiCollectionPanel;
|
||||
if (typeof expandedPanelIndex !== 'number' || expandedPanelIndex === -1) {
|
||||
expandedPanelIndex = this.$store.getters['apiClient/GtrCurrentApiFilePaths'].findIndex(
|
||||
file => file.path === path.join(this.currentProjectFolder, 'server', 'tool', this.projectApisFolder, 'apis.xc.json')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (!this.apiTvs[expandedPanelIndex].children) this.apiTvs[expandedPanelIndex].children = []
|
||||
this.apiTvs[expandedPanelIndex].addChildren(node)
|
||||
await this.savefileCollections(expandedPanelIndex);
|
||||
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
|
||||
beforeCreated() {
|
||||
},
|
||||
async created() {
|
||||
|
||||
console.log('ApisList', this.$store.state.apiClient.list);
|
||||
|
||||
this.$store.dispatch('apiClient/loadApiCollectionForProject', {
|
||||
projectId: this.$route.params.project,
|
||||
projectName: this.$store.getters['project/GtrProjectName']
|
||||
})
|
||||
|
||||
|
||||
try {
|
||||
|
||||
/* load all files that are were previously opened */
|
||||
if (!this.$store.getters['apiClient/GtrCurrentApiFilePaths'].length) {
|
||||
const defaultPath = path.join(this.currentProjectFolder, 'server', 'tool', this.projectApisFolder, 'apis.xc.json');
|
||||
this.$store.commit('apiClient/MutApiFilePathsAdd', {
|
||||
path: defaultPath,
|
||||
fileName: path.basename(defaultPath)
|
||||
})
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.$store.getters['apiClient/GtrCurrentApiFilePaths'].length; ++i) {
|
||||
await this.loadFileCollection(this.$store.getters['apiClient/GtrCurrentApiFilePaths'][i]);
|
||||
}
|
||||
|
||||
|
||||
} catch (e) {
|
||||
console.log('Failed to load previously opened query collections', e);
|
||||
}
|
||||
|
||||
|
||||
if (this.nodes.url) {
|
||||
Vue.set(this.api, 'type', 'GET');
|
||||
this.api.url = this.nodes.url
|
||||
}
|
||||
console.log(this.nodes);
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
beforeDestroy() {
|
||||
},
|
||||
destroy() {
|
||||
},
|
||||
validate({params}) {
|
||||
return true;
|
||||
},
|
||||
head() {
|
||||
return {};
|
||||
},
|
||||
props: ["nodes"],
|
||||
watch: {},
|
||||
directives: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.apis-list {
|
||||
height: calc(100%);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.apis-request {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/deep/ > .req-inputs .v-toolbar__content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
/deep/ .req-tabs > .v-tabs-items {
|
||||
border-top: 1px solid #7F828B33;
|
||||
}
|
||||
|
||||
.envs /deep/ .v-select__selections {
|
||||
color: var(--v-accent-base)
|
||||
}
|
||||
|
||||
/*.envs /deep/ .v-select__selections input { display: none}*/
|
||||
|
||||
</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/>.
|
||||
*
|
||||
*/
|
||||
-->
|
||||
Reference in New Issue
Block a user