mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
feat: stored routines creation
This commit is contained in:
@ -69,75 +69,81 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.context {
|
.context {
|
||||||
|
display: flex;
|
||||||
|
color: $body-font-color;
|
||||||
|
font-size: 16px;
|
||||||
|
z-index: 400;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
position: fixed;
|
||||||
|
height: 100vh;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
|
||||||
|
.context-container {
|
||||||
|
min-width: 100px;
|
||||||
|
z-index: 10;
|
||||||
|
box-shadow: 0 0 2px 0 #000;
|
||||||
|
padding: 0;
|
||||||
|
background: #1d1d1d;
|
||||||
|
border-radius: 0.1rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
color: $body-font-color;
|
flex-direction: column;
|
||||||
font-size: 16px;
|
position: absolute;
|
||||||
z-index: 400;
|
pointer-events: initial;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
overflow: hidden;
|
|
||||||
position: fixed;
|
|
||||||
height: 100vh;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
|
|
||||||
.context-container {
|
.context-element {
|
||||||
min-width: 100px;
|
|
||||||
z-index: 10;
|
|
||||||
box-shadow: 0 0 2px 0 #000;
|
|
||||||
padding: 0;
|
|
||||||
background: #1d1d1d;
|
|
||||||
border-radius: 0.1rem;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
align-items: center;
|
||||||
position: absolute;
|
padding: 0.1rem 0.3rem;
|
||||||
pointer-events: initial;
|
cursor: pointer;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
.context-element {
|
.context-submenu {
|
||||||
display: flex;
|
opacity: 0;
|
||||||
align-items: center;
|
visibility: hidden;
|
||||||
padding: 0.1rem 0.3rem;
|
transition: opacity 0.2s;
|
||||||
cursor: pointer;
|
position: absolute;
|
||||||
justify-content: space-between;
|
left: 100%;
|
||||||
position: relative;
|
top: 0;
|
||||||
|
background: #1d1d1d;
|
||||||
|
box-shadow: 0 0 2px 0 #000;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $primary-color;
|
||||||
|
|
||||||
.context-submenu {
|
.context-submenu {
|
||||||
opacity: 0;
|
display: block;
|
||||||
visibility: hidden;
|
visibility: visible;
|
||||||
transition: opacity 0.2s;
|
opacity: 1;
|
||||||
position: absolute;
|
|
||||||
left: 100%;
|
|
||||||
top: 0;
|
|
||||||
background: #1d1d1d;
|
|
||||||
box-shadow: 0 0 2px 0 #000;
|
|
||||||
min-width: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: $primary-color;
|
|
||||||
|
|
||||||
.context-submenu {
|
|
||||||
display: block;
|
|
||||||
visibility: visible;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.context-overlay {
|
|
||||||
background: transparent;
|
|
||||||
bottom: 0;
|
|
||||||
cursor: default;
|
|
||||||
display: block;
|
|
||||||
left: 0;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.context-overlay {
|
||||||
|
background: transparent;
|
||||||
|
bottom: 0;
|
||||||
|
cursor: default;
|
||||||
|
display: block;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabled {
|
||||||
|
pointer-events: none;
|
||||||
|
filter: grayscale(100%);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
147
src/renderer/components/ModalNewRoutine.vue
Normal file
147
src/renderer/components/ModalNewRoutine.vue
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
<template>
|
||||||
|
<ConfirmModal
|
||||||
|
:confirm-text="$t('word.confirm')"
|
||||||
|
size="400"
|
||||||
|
@confirm="confirmNewRoutine"
|
||||||
|
@hide="$emit('close')"
|
||||||
|
>
|
||||||
|
<template :slot="'header'">
|
||||||
|
<div class="d-flex">
|
||||||
|
<i class="mdi mdi-24px mdi-cogs mr-1" /> {{ $t('message.createNewRoutine') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div :slot="'body'">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label col-4">
|
||||||
|
{{ $t('word.name') }}
|
||||||
|
</label>
|
||||||
|
<div class="column">
|
||||||
|
<input
|
||||||
|
ref="firstInput"
|
||||||
|
v-model="localRoutine.name"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label col-4">
|
||||||
|
{{ $t('word.definer') }}
|
||||||
|
</label>
|
||||||
|
<div class="column">
|
||||||
|
<select
|
||||||
|
v-if="workspace.users.length"
|
||||||
|
v-model="localRoutine.definer"
|
||||||
|
class="form-select"
|
||||||
|
>
|
||||||
|
<option value="">
|
||||||
|
{{ $t('message.currentUser') }}
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
v-for="user in workspace.users"
|
||||||
|
:key="`${user.name}@${user.host}`"
|
||||||
|
:value="`\`${user.name}\`@\`${user.host}\``"
|
||||||
|
>
|
||||||
|
{{ user.name }}@{{ user.host }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<select v-if="!workspace.users.length" class="form-select">
|
||||||
|
<option value="">
|
||||||
|
{{ $t('message.currentUser') }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label col-4">
|
||||||
|
{{ $t('word.comment') }}
|
||||||
|
</label>
|
||||||
|
<div class="column">
|
||||||
|
<input
|
||||||
|
v-model="localRoutine.comment"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label col-4">
|
||||||
|
{{ $t('message.sqlSecurity') }}
|
||||||
|
</label>
|
||||||
|
<div class="column">
|
||||||
|
<select v-model="localRoutine.security" class="form-select">
|
||||||
|
<option>DEFINER</option>
|
||||||
|
<option>INVOKER</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label col-4">
|
||||||
|
{{ $t('message.dataAccess') }}
|
||||||
|
</label>
|
||||||
|
<div class="column">
|
||||||
|
<select v-model="localRoutine.dataAccess" class="form-select">
|
||||||
|
<option>CONTAINS SQL</option>
|
||||||
|
<option>NO SQL</option>
|
||||||
|
<option>READS SQL DATA</option>
|
||||||
|
<option>MODIFIES SQL DATA</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4" />
|
||||||
|
<div class="column">
|
||||||
|
<label class="form-checkbox form-inline">
|
||||||
|
<input v-model="localRoutine.deterministic" type="checkbox"><i class="form-icon" /> {{ $t('word.deterministic') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</ConfirmModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ConfirmModal from '@/components/BaseConfirmModal';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ModalNewRoutine',
|
||||||
|
components: {
|
||||||
|
ConfirmModal
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
workspace: Object
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
localRoutine: {
|
||||||
|
definer: '',
|
||||||
|
sql: 'BEGIN\r\n\r\nEND',
|
||||||
|
parameters: [],
|
||||||
|
name: '',
|
||||||
|
comment: '',
|
||||||
|
security: 'DEFINER',
|
||||||
|
deterministic: false,
|
||||||
|
dataAccess: 'CONTAINS SQL'
|
||||||
|
},
|
||||||
|
isOptionsChanging: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
schema () {
|
||||||
|
return this.workspace.breadcrumbs.schema;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$refs.firstInput.focus();
|
||||||
|
}, 20);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
confirmNewRoutine () {
|
||||||
|
this.$emit('open-create-routine-editor', this.localRoutine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@ -2,7 +2,7 @@
|
|||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
:confirm-text="$t('word.confirm')"
|
:confirm-text="$t('word.confirm')"
|
||||||
size="400"
|
size="400"
|
||||||
@confirm="confirmOptionsChange"
|
@confirm="confirmNewTrigger"
|
||||||
@hide="$emit('close')"
|
@hide="$emit('close')"
|
||||||
>
|
>
|
||||||
<template :slot="'header'">
|
<template :slot="'header'">
|
||||||
@ -132,7 +132,7 @@ export default {
|
|||||||
}, 20);
|
}, 20);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
confirmOptionsChange () {
|
confirmNewTrigger () {
|
||||||
this.$emit('open-create-trigger-editor', this.localTrigger);
|
this.$emit('open-create-trigger-editor', this.localTrigger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,12 @@
|
|||||||
@close="hideCreateTriggerModal"
|
@close="hideCreateTriggerModal"
|
||||||
@open-create-trigger-editor="openCreateTriggerEditor"
|
@open-create-trigger-editor="openCreateTriggerEditor"
|
||||||
/>
|
/>
|
||||||
|
<ModalNewRoutine
|
||||||
|
v-if="isNewRoutineModal"
|
||||||
|
:workspace="workspace"
|
||||||
|
@close="hideCreateRoutineModal"
|
||||||
|
@open-create-routine-editor="openCreateRoutineEditor"
|
||||||
|
/>
|
||||||
<DatabaseContext
|
<DatabaseContext
|
||||||
v-if="isDatabaseContext"
|
v-if="isDatabaseContext"
|
||||||
:selected-database="selectedDatabase"
|
:selected-database="selectedDatabase"
|
||||||
@ -75,6 +81,7 @@
|
|||||||
@show-create-table-modal="showCreateTableModal"
|
@show-create-table-modal="showCreateTableModal"
|
||||||
@show-create-view-modal="showCreateViewModal"
|
@show-create-view-modal="showCreateViewModal"
|
||||||
@show-create-trigger-modal="showCreateTriggerModal"
|
@show-create-trigger-modal="showCreateTriggerModal"
|
||||||
|
@show-create-routine-modal="showCreateRoutineModal"
|
||||||
@reload="refresh"
|
@reload="refresh"
|
||||||
/>
|
/>
|
||||||
<TableContext
|
<TableContext
|
||||||
@ -97,9 +104,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import { mapGetters, mapActions } from 'vuex';
|
import { mapGetters, mapActions } from 'vuex';
|
||||||
import _ from 'lodash';// TODO: remove
|
import _ from 'lodash';// TODO: remove
|
||||||
|
|
||||||
import Tables from '@/ipc-api/Tables';
|
import Tables from '@/ipc-api/Tables';
|
||||||
import Views from '@/ipc-api/Views';
|
import Views from '@/ipc-api/Views';
|
||||||
import Triggers from '@/ipc-api/Triggers';
|
import Triggers from '@/ipc-api/Triggers';
|
||||||
|
import Routines from '@/ipc-api/Routines';
|
||||||
|
|
||||||
import WorkspaceConnectPanel from '@/components/WorkspaceConnectPanel';
|
import WorkspaceConnectPanel from '@/components/WorkspaceConnectPanel';
|
||||||
import WorkspaceExploreBarDatabase from '@/components/WorkspaceExploreBarDatabase';
|
import WorkspaceExploreBarDatabase from '@/components/WorkspaceExploreBarDatabase';
|
||||||
import DatabaseContext from '@/components/WorkspaceExploreBarDatabaseContext';
|
import DatabaseContext from '@/components/WorkspaceExploreBarDatabaseContext';
|
||||||
@ -109,6 +119,7 @@ import ModalNewDatabase from '@/components/ModalNewDatabase';
|
|||||||
import ModalNewTable from '@/components/ModalNewTable';
|
import ModalNewTable from '@/components/ModalNewTable';
|
||||||
import ModalNewView from '@/components/ModalNewView';
|
import ModalNewView from '@/components/ModalNewView';
|
||||||
import ModalNewTrigger from '@/components/ModalNewTrigger';
|
import ModalNewTrigger from '@/components/ModalNewTrigger';
|
||||||
|
import ModalNewRoutine from '@/components/ModalNewRoutine';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'WorkspaceExploreBar',
|
name: 'WorkspaceExploreBar',
|
||||||
@ -121,7 +132,8 @@ export default {
|
|||||||
ModalNewDatabase,
|
ModalNewDatabase,
|
||||||
ModalNewTable,
|
ModalNewTable,
|
||||||
ModalNewView,
|
ModalNewView,
|
||||||
ModalNewTrigger
|
ModalNewTrigger,
|
||||||
|
ModalNewRoutine
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
connection: Object,
|
connection: Object,
|
||||||
@ -135,6 +147,7 @@ export default {
|
|||||||
isNewTableModal: false,
|
isNewTableModal: false,
|
||||||
isNewViewModal: false,
|
isNewViewModal: false,
|
||||||
isNewTriggerModal: false,
|
isNewTriggerModal: false,
|
||||||
|
isNewRoutineModal: false,
|
||||||
|
|
||||||
localWidth: null,
|
localWidth: null,
|
||||||
isDatabaseContext: false,
|
isDatabaseContext: false,
|
||||||
@ -308,6 +321,29 @@ export default {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
this.addNotification({ status: 'error', message: response });
|
this.addNotification({ status: 'error', message: response });
|
||||||
|
},
|
||||||
|
showCreateRoutineModal () {
|
||||||
|
this.closeDatabaseContext();
|
||||||
|
this.isNewRoutineModal = true;
|
||||||
|
},
|
||||||
|
hideCreateRoutineModal () {
|
||||||
|
this.isNewRoutineModal = false;
|
||||||
|
},
|
||||||
|
async openCreateRoutineEditor (payload) {
|
||||||
|
const params = {
|
||||||
|
uid: this.connection.uid,
|
||||||
|
...payload
|
||||||
|
};
|
||||||
|
|
||||||
|
const { status, response } = await Routines.createRoutine(params);
|
||||||
|
|
||||||
|
if (status === 'success') {
|
||||||
|
await this.refresh();
|
||||||
|
this.changeBreadcrumbs({ schema: this.selectedDatabase, procedure: payload.name });
|
||||||
|
this.selectTab({ uid: this.workspace.uid, tab: 'prop' });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.addNotification({ status: 'error', message: response });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -16,13 +16,13 @@
|
|||||||
<div class="context-element" @click="showCreateTriggerModal">
|
<div class="context-element" @click="showCreateTriggerModal">
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-cog text-light pr-1" /> {{ $tc('word.trigger', 1) }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-table-cog text-light pr-1" /> {{ $tc('word.trigger', 1) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element" @click="false">
|
<div class="context-element" @click="showCreateRoutineModal">
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-sync-circle pr-1" /> {{ $tc('word.storedRoutine', 1) }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-sync-circle pr-1" /> {{ $tc('word.storedRoutine', 1) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element" @click="false">
|
<div class="context-element disabled" @click="false">
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-arrow-right-bold-box pr-1" /> {{ $tc('word.function', 1) }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-arrow-right-bold-box pr-1" /> {{ $tc('word.function', 1) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element" @click="false">
|
<div class="context-element disabled" @click="false">
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-calendar-clock text-light pr-1" /> {{ $tc('word.scheduler', 1) }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-calendar-clock text-light pr-1" /> {{ $tc('word.scheduler', 1) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -105,6 +105,9 @@ export default {
|
|||||||
showCreateTriggerModal () {
|
showCreateTriggerModal () {
|
||||||
this.$emit('show-create-trigger-modal');
|
this.$emit('show-create-trigger-modal');
|
||||||
},
|
},
|
||||||
|
showCreateRoutineModal () {
|
||||||
|
this.$emit('show-create-routine-modal');
|
||||||
|
},
|
||||||
showDeleteModal () {
|
showDeleteModal () {
|
||||||
this.isDeleteModal = true;
|
this.isDeleteModal = true;
|
||||||
},
|
},
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
@close-context="closeContext"
|
@close-context="closeContext"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="selectedMisc.type === 'table'"
|
v-if="selectedMisc.type === 'procedure'"
|
||||||
class="context-element"
|
class="context-element disabled"
|
||||||
@click="showEmptyModal"
|
@click="showRunModal"
|
||||||
>
|
>
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-off text-light pr-1" /> {{ $t('message.emptyTable') }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-play text-light pr-1" /> {{ $t('word.run') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element" @click="showDeleteModal">
|
<div class="context-element" @click="showDeleteModal">
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-remove text-light pr-1" /> {{ $t('word.delete') }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-table-remove text-light pr-1" /> {{ $t('word.delete') }}</span>
|
||||||
@ -52,7 +52,7 @@ export default {
|
|||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
isDeleteModal: false,
|
isDeleteModal: false,
|
||||||
isEmptyModal: false
|
isRunModal: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -88,11 +88,11 @@ export default {
|
|||||||
hideDeleteModal () {
|
hideDeleteModal () {
|
||||||
this.isDeleteModal = false;
|
this.isDeleteModal = false;
|
||||||
},
|
},
|
||||||
showEmptyModal () {
|
showRunModal () {
|
||||||
this.isEmptyModal = true;
|
this.isRunModal = true;
|
||||||
},
|
},
|
||||||
hideEmptyModal () {
|
hideRunModal () {
|
||||||
this.isEmptyModal = false;
|
this.isRunModal = false;
|
||||||
},
|
},
|
||||||
closeContext () {
|
closeContext () {
|
||||||
this.$emit('close-context');
|
this.$emit('close-context');
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
<div class="divider-vert py-3" />
|
<div class="divider-vert py-3" />
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn btn-dark btn-sm"
|
class="btn btn-dark btn-sm disabled"
|
||||||
:disabled="isChanged"
|
:disabled="isChanged"
|
||||||
@click="false"
|
@click="false"
|
||||||
>
|
>
|
||||||
|
@ -77,11 +77,3 @@ export default {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.disabled {
|
|
||||||
pointer-events: none;
|
|
||||||
filter: grayscale(100%);
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
@ -157,6 +157,7 @@ module.exports = {
|
|||||||
dataAccess: 'Data access',
|
dataAccess: 'Data access',
|
||||||
thereAreNoParameters: 'There are no parameters',
|
thereAreNoParameters: 'There are no parameters',
|
||||||
createNewParameter: 'Create new parameter',
|
createNewParameter: 'Create new parameter',
|
||||||
|
createNewRoutine: 'Create new stored routine',
|
||||||
deleteRoutine: 'Delete stored routine'
|
deleteRoutine: 'Delete stored routine'
|
||||||
},
|
},
|
||||||
// Date and Time
|
// Date and Time
|
||||||
|
Reference in New Issue
Block a user