feat(UI): select tab replace with BaseSelect component

This commit is contained in:
Giulio Ganci 2022-05-11 23:30:31 +02:00
parent f7e04d6333
commit 42bc9196ff
29 changed files with 588 additions and 851 deletions

View File

@ -1,38 +1,26 @@
<template> <template>
<fieldset class="input-group mb-0"> <fieldset class="input-group mb-0">
<select <BaseSelect
v-model="selectedGroup" v-model="selectedGroup"
class="form-select" class="form-select"
:options="[{name: 'manual'}, ...fakerGroups]"
:option-label="(opt) => opt.name === 'manual' ? $t('message.manualValue') : $t(`faker.${opt.name}`)"
option-track-by="name"
:disabled="!isChecked" :disabled="!isChecked"
style="flex-grow: 0;" style="flex-grow: 0;"
@change="onChange" @change="onChange"
> />
<option value="manual">
{{ $t('message.manualValue') }} <BaseSelect
</option>
<option
v-for="group in fakerGroups"
:key="group.name"
:value="group.name"
>
{{ $t(`faker.${group.name}`) }}
</option>
</select>
<select
v-if="selectedGroup !== 'manual'" v-if="selectedGroup !== 'manual'"
v-model="selectedMethod" v-model="selectedMethod"
:options="fakerMethods"
:option-label="(opt) => $t(`faker.${opt.name}`)"
option-track-by="name"
class="form-select" class="form-select"
:disabled="!isChecked" :disabled="!isChecked"
@change="onChange" @change="onChange"
> />
<option
v-for="method in fakerMethods"
:key="method.name"
:value="method.name"
>
{{ $t(`faker.${method.name}`) }}
</option>
</select>
<ForeignKeySelect <ForeignKeySelect
v-else-if="foreignKeys.includes(field.name)" v-else-if="foreignKeys.includes(field.name)"
ref="formInput" ref="formInput"
@ -66,21 +54,14 @@
:type="inputProps().type" :type="inputProps().type"
:disabled="!isChecked" :disabled="!isChecked"
> >
<select <BaseSelect
v-else-if="enumArray" v-else-if="enumArray"
v-model="selectedValue" v-model="selectedValue"
:options="enumArray"
class="form-select" class="form-select"
:disabled="!isChecked" :disabled="!isChecked"
@change="onChange" @change="onChange"
> />
<option
v-for="val in enumArray"
:key="val"
:value="val"
>
{{ val }}
</option>
</select>
<input <input
v-else v-else
ref="formInput" ref="formInput"
@ -109,12 +90,14 @@ import { TEXT, LONG_TEXT, NUMBER, FLOAT, DATE, TIME, DATETIME, BLOB, BIT } from
import BaseUploadInput from '@/components/BaseUploadInput'; import BaseUploadInput from '@/components/BaseUploadInput';
import ForeignKeySelect from '@/components/ForeignKeySelect'; import ForeignKeySelect from '@/components/ForeignKeySelect';
import FakerMethods from 'common/FakerMethods'; import FakerMethods from 'common/FakerMethods';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'FakerSelect', name: 'FakerSelect',
components: { components: {
ForeignKeySelect, ForeignKeySelect,
BaseUploadInput BaseUploadInput,
BaseSelect
}, },
props: { props: {
type: String, type: String,

View File

@ -21,6 +21,7 @@
</div> </div>
<div class="col-9"> <div class="col-9">
<input <input
ref="firstInput"
v-model="database.name" v-model="database.name"
class="form-input" class="form-input"
type="text" type="text"
@ -35,19 +36,13 @@
<label class="form-label">{{ $t('word.collation') }}</label> <label class="form-label">{{ $t('word.collation') }}</label>
</div> </div>
<div class="col-9"> <div class="col-9">
<select <BaseSelect
ref="firstInput"
v-model="database.collation" v-model="database.collation"
class="form-select" class="form-select"
> :options="collations"
<option option-label="collation"
v-for="collation in collations" option-track-by="collation"
:key="collation.id" />
:value="collation.collation"
>
{{ collation.collation }}
</option>
</select>
<small>{{ $t('message.serverDefault') }}: {{ defaultCollation }}</small> <small>{{ $t('message.serverDefault') }}: {{ defaultCollation }}</small>
</div> </div>
</div> </div>
@ -72,9 +67,13 @@ import { storeToRefs } from 'pinia';
import { useNotificationsStore } from '@/stores/notifications'; import { useNotificationsStore } from '@/stores/notifications';
import { useWorkspacesStore } from '@/stores/workspaces'; import { useWorkspacesStore } from '@/stores/workspaces';
import Schema from '@/ipc-api/Schema'; import Schema from '@/ipc-api/Schema';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'ModalEditSchema', name: 'ModalEditSchema',
components: {
BaseSelect
},
props: { props: {
selectedSchema: String selectedSchema: String
}, },

View File

@ -206,14 +206,11 @@
> >
</div> </div>
<div class="column col-6"> <div class="column col-6">
<select v-model="options.sqlInsertDivider" class="form-select"> <BaseSelect
<option value="bytes"> v-model="options.sqlInsertDivider"
KiB class="form-select"
</option> :options="[{value: 'bytes', label: 'KiB'}, {value: 'rows', label: $tc('word.row', 2)}]"
<option value="rows"> />
{{ $tc('word.row', 2) }}
</option>
</select>
</div> </div>
</div> </div>
</div> </div>
@ -223,14 +220,11 @@
</div> </div>
<div class="columns"> <div class="columns">
<div class="column h5 mb-4"> <div class="column h5 mb-4">
<select v-model="options.outputFormat" class="form-select"> <BaseSelect
<option value="sql"> v-model="options.outputFormat"
{{ $t('message.singleFile', {ext: '.sql'}) }} class="form-select"
</option> :options="[{value: 'sql', label: $t('message.singleFile', {ext: '.sql'})}, {value: 'sql.zip', label: $t('message.zipCompressedFile', {ext: '.sql'})}]"
<option value="sql.zip"> />
{{ $t('message.zipCompressedFile', {ext: '.sql'}) }}
</option>
</select>
</div> </div>
</div> </div>
</div> </div>
@ -278,9 +272,13 @@ import { useWorkspacesStore } from '@/stores/workspaces';
import customizations from 'common/customizations'; import customizations from 'common/customizations';
import Application from '@/ipc-api/Application'; import Application from '@/ipc-api/Application';
import Schema from '@/ipc-api/Schema'; import Schema from '@/ipc-api/Schema';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'ModalExportSchema', name: 'ModalExportSchema',
components: {
BaseSelect
},
props: { props: {
selectedSchema: String selectedSchema: String
}, },

View File

@ -72,99 +72,11 @@
class="tooltip tooltip-right ml-2" class="tooltip tooltip-right ml-2"
:data-tooltip="$t('message.fakeDataLanguage')" :data-tooltip="$t('message.fakeDataLanguage')"
> >
<select v-model="fakerLocale" class="form-select"> <BaseSelect
<option value="ar"> v-model="fakerLocale"
Arabic :options="locales"
</option><option value="az"> class="form-select"
Azerbaijani />
</option><option value="zh_CN">
Chinese
</option><option value="zh_TW">
Chinese (Taiwan)
</option><option value="cz">
Czech
</option><option value="nl">
Dutch
</option><option value="nl_BE">
Dutch (Belgium)
</option><option value="en">
English
</option><option value="en_AU_ocker">
English (Australia Ocker)
</option><option value="en_AU">
English (Australia)
</option><option value="en_BORK">
English (Bork)
</option><option value="en_CA">
English (Canada)
</option><option value="en_GB">
English (Great Britain)
</option><option value="en_IND">
English (India)
</option><option value="en_IE">
English (Ireland)
</option><option value="en_ZA">
English (South Africa)
</option><option value="en_US">
English (United States)
</option><option value="fa">
Farsi
</option><option value="fi">
Finnish
</option><option value="fr">
French
</option><option value="fr_CA">
French (Canada)
</option><option value="fr_CH">
French (Switzerland)
</option><option value="ge">
Georgian
</option><option value="de">
German
</option><option value="de_AT">
German (Austria)
</option><option value="de_CH">
German (Switzerland)
</option><option value="hr">
Hrvatski
</option><option value="id_ID">
Indonesia
</option><option value="it">
Italian
</option><option value="ja">
Japanese
</option><option value="ko">
Korean
</option><option value="nep">
Nepalese
</option><option value="nb_NO">
Norwegian
</option><option value="pl">
Polish
</option><option value="pt_BR">
Portuguese (Brazil)
</option><option value="pt_PT">
Portuguese (Portugal)
</option><option value="ro">
Romanian
</option><option value="ru">
Russian
</option><option value="sk">
Slovakian
</option><option value="es">
Spanish
</option><option value="es_MX">
Spanish (Mexico)
</option><option value="sv">
Swedish
</option><option value="tr">
Turkish
</option><option value="uk">
Ukrainian
</option><option value="vi">
Vietnamese
</option>
</select>
</div> </div>
</div> </div>
<div class="column col-auto"> <div class="column col-auto">
@ -193,11 +105,13 @@ import { useNotificationsStore } from '@/stores/notifications';
import { useWorkspacesStore } from '@/stores/workspaces'; import { useWorkspacesStore } from '@/stores/workspaces';
import Tables from '@/ipc-api/Tables'; import Tables from '@/ipc-api/Tables';
import FakerSelect from '@/components/FakerSelect'; import FakerSelect from '@/components/FakerSelect';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'ModalFakerRows', name: 'ModalFakerRows',
components: { components: {
FakerSelect FakerSelect,
BaseSelect
}, },
props: { props: {
tabUid: [String, Number], tabUid: [String, Number],
@ -210,14 +124,62 @@ export default {
const workspacesStore = useWorkspacesStore(); const workspacesStore = useWorkspacesStore();
const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore); const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
const { getWorkspace, getWorkspaceTab } = workspacesStore; const { getWorkspace, getWorkspaceTab } = workspacesStore;
const locales = [
{ value: 'ar', label: 'Arabic' },
{ value: 'az', label: 'Azerbaijani' },
{ value: 'zh_CN', label: 'Chinese' },
{ value: 'zh_TW', label: 'Chinese (Taiwan)' },
{ value: 'cz', label: 'Czech' },
{ value: 'nl', label: 'Dutch' },
{ value: 'nl_BE', label: 'Dutch (Belgium)' },
{ value: 'en', label: 'English' },
{ value: 'en_AU_ocker', label: 'English (Australia Ocker)' },
{ value: 'en_AU', label: 'English (Australia)' },
{ value: 'en_BORK', label: 'English (Bork)' },
{ value: 'en_CA', label: 'English (Canada)' },
{ value: 'en_GB', label: 'English (Great Britain)' },
{ value: 'en_IND', label: 'English (India)' },
{ value: 'en_IE', label: 'English (Ireland)' },
{ value: 'en_ZA', label: 'English (South Africa)' },
{ value: 'en_US', label: 'English (United States)' },
{ value: 'fa', label: 'Farsi' },
{ value: 'fi', label: 'Finnish' },
{ value: 'fr', label: 'French' },
{ value: 'fr_CA', label: 'French (Canada)' },
{ value: 'fr_CH', label: 'French (Switzerland)' },
{ value: 'ge', label: 'Georgian' },
{ value: 'de', label: 'German' },
{ value: 'de_AT', label: 'German (Austria)' },
{ value: 'de_CH', label: 'German (Switzerland)' },
{ value: 'hr', label: 'Hrvatski' },
{ value: 'id_ID', label: 'Indonesia' },
{ value: 'it', label: 'Italian' },
{ value: 'ja', label: 'Japanese' },
{ value: 'ko', label: 'Korean' },
{ value: 'nep', label: 'Nepalese' },
{ value: 'nb_NO', label: 'Norwegian' },
{ value: 'pl', label: 'Polish' },
{ value: 'pt_BR', label: 'Portuguese (Brazil)' },
{ value: 'pt_PT', label: 'Portuguese (Portugal)' },
{ value: 'ro', label: 'Romanian' },
{ value: 'ru', label: 'Russian' },
{ value: 'sk', label: 'Slovakian' },
{ value: 'es', label: 'Spanish' },
{ value: 'es_MX', label: 'Spanish (Mexico)' },
{ value: 'sv', label: 'Swedish' },
{ value: 'tr', label: 'Turkish' },
{ value: 'uk', label: 'Ukrainian' },
{ value: 'vi', label: 'Vietnamese' }
];
return { return {
addNotification, addNotification,
selectedWorkspace, selectedWorkspace,
getWorkspace, getWorkspace,
getWorkspaceTab getWorkspaceTab,
locales
}; };
}, },
data () { data () {

View File

@ -35,15 +35,13 @@
<label class="form-label">{{ $t('word.collation') }}</label> <label class="form-label">{{ $t('word.collation') }}</label>
</div> </div>
<div class="col-9"> <div class="col-9">
<select v-model="database.collation" class="form-select"> <BaseSelect
<option v-model="database.collation"
v-for="collation in collations" class="form-select"
:key="collation.id" :options="collations"
:value="collation.collation" option-label="collation"
> option-track-by="collation"
{{ collation.collation }} />
</option>
</select>
<small>{{ $t('message.serverDefault') }}: {{ defaultCollation }}</small> <small>{{ $t('message.serverDefault') }}: {{ defaultCollation }}</small>
</div> </div>
</div> </div>
@ -72,9 +70,11 @@ import { useNotificationsStore } from '@/stores/notifications';
import { useWorkspacesStore } from '@/stores/workspaces'; import { useWorkspacesStore } from '@/stores/workspaces';
import Schema from '@/ipc-api/Schema'; import Schema from '@/ipc-api/Schema';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'ModalNewSchema', name: 'ModalNewSchema',
components: { BaseSelect },
emits: ['reload', 'close'], emits: ['reload', 'close'],
setup () { setup () {
const { addNotification } = useNotificationsStore(); const { addNotification } = useNotificationsStore();

View File

@ -69,19 +69,14 @@
</label> </label>
</div> </div>
<div class="col-3 col-sm-12"> <div class="col-3 col-sm-12">
<select <BaseSelect
v-model="localLocale" v-model="localLocale"
class="form-select" class="form-select"
:options="locales"
option-track-by="code"
option-label="name"
@change="changeLocale(localLocale)" @change="changeLocale(localLocale)"
> />
<option
v-for="(locale, key) in locales"
:key="key"
:value="locale.code"
>
{{ locale.name }}
</option>
</select>
</div> </div>
<div class="col-4 col-sm-12 px-2 p-vcentered"> <div class="col-4 col-sm-12 px-2 p-vcentered">
<small class="d-block" style="line-height:1.1; font-size:70%;"> <small class="d-block" style="line-height:1.1; font-size:70%;">
@ -97,18 +92,12 @@
</label> </label>
</div> </div>
<div class="col-3 col-sm-12"> <div class="col-3 col-sm-12">
<select <BaseSelect
v-model="localPageSize" v-model="localPageSize"
class="form-select" class="form-select"
:options="pageSizes"
@change="changePageSize(+localPageSize)" @change="changePageSize(+localPageSize)"
> />
<option
v-for="size in pageSizes"
:key="size"
>
{{ size }}
</option>
</select>
</div> </div>
</div> </div>
<div class="form-group column col-12 mb-0"> <div class="form-group column col-12 mb-0">
@ -231,26 +220,16 @@
{{ $t('message.editorTheme') }} {{ $t('message.editorTheme') }}
</div> </div>
<div class="column col-6 h5 mb-4"> <div class="column col-6 h5 mb-4">
<select <BaseSelect
v-model="localEditorTheme" v-model="localEditorTheme"
class="form-select" class="form-select"
:options="editorThemes"
option-label="name"
option-track-by="code"
group-label="group"
group-values="themes"
@change="changeEditorTheme(localEditorTheme)" @change="changeEditorTheme(localEditorTheme)"
> />
<optgroup
v-for="group in editorThemes"
:key="group.group"
:label="group.group"
>
<option
v-for="theme in group.themes"
:key="theme.name"
:value="theme.code"
:selected="editorTheme === theme.code"
>
{{ theme.name }}
</option>
</optgroup>
</select>
</div> </div>
<div class="column col-6 mb-4"> <div class="column col-6 mb-4">
<div class="btn-group btn-group-block"> <div class="btn-group btn-group-block">
@ -332,13 +311,15 @@ import localesNames from '@/i18n/supported-locales';
import ModalSettingsUpdate from '@/components/ModalSettingsUpdate'; import ModalSettingsUpdate from '@/components/ModalSettingsUpdate';
import ModalSettingsChangelog from '@/components/ModalSettingsChangelog'; import ModalSettingsChangelog from '@/components/ModalSettingsChangelog';
import BaseTextEditor from '@/components/BaseTextEditor'; import BaseTextEditor from '@/components/BaseTextEditor';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'ModalSettings', name: 'ModalSettings',
components: { components: {
ModalSettingsUpdate, ModalSettingsUpdate,
ModalSettingsChangelog, ModalSettingsChangelog,
BaseTextEditor BaseTextEditor,
BaseSelect
}, },
setup () { setup () {
const applicationStore = useApplicationStore(); const applicationStore = useApplicationStore();

View File

@ -57,11 +57,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.language') }} {{ $t('word.language') }}
</label> </label>
<select v-model="localFunction.language" class="form-select"> <BaseSelect
<option v-for="language in customizations.languages" :key="language"> v-model="localFunction.language"
{{ language }} :options="customizations.languages"
</option> class="form-select"
</select> />
</div> </div>
</div> </div>
<div v-if="customizations.definer" class="column col-auto"> <div v-if="customizations.definer" class="column col-auto">
@ -69,27 +69,13 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.definer') }} {{ $t('word.definer') }}
</label> </label>
<select <BaseSelect
v-if="workspace.users.length"
v-model="localFunction.definer" v-model="localFunction.definer"
:options="[{value: '', name:$t('message.currentUser')}, ...workspace.users]"
:option-label="(user) => user.value === '' ? user.name : `${user.name}@${user.host}`"
:option-track-by="(user) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
class="form-select" 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> </div>
<div class="column col-auto"> <div class="column col-auto">
@ -98,29 +84,16 @@
{{ $t('word.returns') }} {{ $t('word.returns') }}
</label> </label>
<div class="input-group"> <div class="input-group">
<select <BaseSelect
v-model="localFunction.returns" v-model="localFunction.returns"
class="form-select text-uppercase" class="form-select text-uppercase"
:options="[{ name: 'VOID' }, ...workspace.dataTypes]"
group-label="group"
group-values="types"
option-label="name"
option-track-by="name"
style="max-width: 150px;" style="max-width: 150px;"
> />
<option v-if="localFunction.returns === 'VOID'">
VOID
</option>
<optgroup
v-for="group in workspace.dataTypes"
:key="group.group"
:label="group.group"
>
<option
v-for="type in group.types"
:key="type.name"
:selected="localFunction.returns === type.name"
:value="type.name"
>
{{ type.name }}
</option>
</optgroup>
</select>
<input <input
v-if="customizations.parametersLength" v-if="customizations.parametersLength"
v-model="localFunction.returnsLength" v-model="localFunction.returnsLength"
@ -150,10 +123,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('message.sqlSecurity') }} {{ $t('message.sqlSecurity') }}
</label> </label>
<select v-model="localFunction.security" class="form-select"> <BaseSelect
<option>DEFINER</option> v-model="localFunction.security"
<option>INVOKER</option> :options="['DEFINER', 'INVOKER']"
</select> class="form-select"
/>
</div> </div>
</div> </div>
<div v-if="customizations.functionDataAccess" class="column col-auto"> <div v-if="customizations.functionDataAccess" class="column col-auto">
@ -161,12 +135,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('message.dataAccess') }} {{ $t('message.dataAccess') }}
</label> </label>
<select v-model="localFunction.dataAccess" class="form-select"> <BaseSelect
<option>CONTAINS SQL</option> v-model="localFunction.dataAccess"
<option>NO SQL</option> :options="['CONTAINS SQL', 'NO SQL', 'READS SQL DATA', 'MODIFIES SQL DATA']"
<option>READS SQL DATA</option> class="form-select"
<option>MODIFIES SQL DATA</option> />
</select>
</div> </div>
</div> </div>
<div v-if="customizations.functionDeterministic" class="column col-auto"> <div v-if="customizations.functionDeterministic" class="column col-auto">
@ -210,13 +183,15 @@ import QueryEditor from '@/components/QueryEditor';
import WorkspaceTabPropsFunctionParamsModal from '@/components/WorkspaceTabPropsFunctionParamsModal'; import WorkspaceTabPropsFunctionParamsModal from '@/components/WorkspaceTabPropsFunctionParamsModal';
import Functions from '@/ipc-api/Functions'; import Functions from '@/ipc-api/Functions';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabNewFunction', name: 'WorkspaceTabNewFunction',
components: { components: {
BaseLoader, BaseLoader,
QueryEditor, QueryEditor,
WorkspaceTabPropsFunctionParamsModal WorkspaceTabPropsFunctionParamsModal,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,

View File

@ -57,11 +57,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.language') }} {{ $t('word.language') }}
</label> </label>
<select v-model="localRoutine.language" class="form-select"> <BaseSelect
<option v-for="language in customizations.languages" :key="language"> v-model="localRoutine.language"
{{ language }} :options="customizations.languages"
</option> class="form-select"
</select> />
</div> </div>
</div> </div>
<div v-if="customizations.definer" class="column col-auto"> <div v-if="customizations.definer" class="column col-auto">
@ -69,27 +69,13 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.definer') }} {{ $t('word.definer') }}
</label> </label>
<select <BaseSelect
v-if="workspace.users.length"
v-model="localRoutine.definer" v-model="localRoutine.definer"
:options="[{value: '', name:$t('message.currentUser')}, ...workspace.users]"
:option-label="(user) => user.value === '' ? user.name : `${user.name}@${user.host}`"
:option-track-by="(user) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
class="form-select" 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> </div>
<div v-if="customizations.comment" class="column"> <div v-if="customizations.comment" class="column">
@ -109,10 +95,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('message.sqlSecurity') }} {{ $t('message.sqlSecurity') }}
</label> </label>
<select v-model="localRoutine.security" class="form-select"> <BaseSelect
<option>DEFINER</option> v-model="localRoutine.security"
<option>INVOKER</option> :options="['DEFINER', 'INVOKER']"
</select> class="form-select"
/>
</div> </div>
</div> </div>
<div v-if="customizations.procedureDataAccess" class="column col-auto"> <div v-if="customizations.procedureDataAccess" class="column col-auto">
@ -120,12 +107,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('message.dataAccess') }} {{ $t('message.dataAccess') }}
</label> </label>
<select v-model="localRoutine.dataAccess" class="form-select"> <BaseSelect
<option>CONTAINS SQL</option> v-model="localRoutine.dataAccess"
<option>NO SQL</option> :options="['CONTAINS SQL', 'NO SQL', 'READS SQL DATA', 'MODIFIES SQL DATA']"
<option>READS SQL DATA</option> class="form-select"
<option>MODIFIES SQL DATA</option> />
</select>
</div> </div>
</div> </div>
<div v-if="customizations.procedureDeterministic" class="column col-auto"> <div v-if="customizations.procedureDeterministic" class="column col-auto">
@ -170,13 +156,15 @@ import BaseLoader from '@/components/BaseLoader';
import WorkspaceTabPropsRoutineParamsModal from '@/components/WorkspaceTabPropsRoutineParamsModal'; import WorkspaceTabPropsRoutineParamsModal from '@/components/WorkspaceTabPropsRoutineParamsModal';
import Routines from '@/ipc-api/Routines'; import Routines from '@/ipc-api/Routines';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabNewRoutine', name: 'WorkspaceTabNewRoutine',
components: { components: {
QueryEditor, QueryEditor,
BaseLoader, BaseLoader,
WorkspaceTabPropsRoutineParamsModal WorkspaceTabPropsRoutineParamsModal,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,

View File

@ -52,30 +52,13 @@
<div class="column col-auto"> <div class="column col-auto">
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('word.definer') }}</label> <label class="form-label">{{ $t('word.definer') }}</label>
<select <BaseSelect
v-if="workspace.users.length"
v-model="localScheduler.definer" v-model="localScheduler.definer"
:options="users"
:option-label="(user) => user.value === '' ? $t('message.currentUser') : `${user.name}@${user.host}`"
:option-track-by="(user) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
class="form-select" class="form-select"
> />
<option value="">
{{ $t('message.currentUser') }}
</option>
<option v-if="!isDefinerInUsers" :value="originalScheduler.definer">
{{ originalScheduler.definer.replaceAll('`', '') }}
</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> </div>
<div class="column"> <div class="column">
@ -149,13 +132,15 @@ import BaseLoader from '@/components/BaseLoader';
import QueryEditor from '@/components/QueryEditor'; import QueryEditor from '@/components/QueryEditor';
import WorkspaceTabPropsSchedulerTimingModal from '@/components/WorkspaceTabPropsSchedulerTimingModal'; import WorkspaceTabPropsSchedulerTimingModal from '@/components/WorkspaceTabPropsSchedulerTimingModal';
import Schedulers from '@/ipc-api/Schedulers'; import Schedulers from '@/ipc-api/Schedulers';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabNewScheduler', name: 'WorkspaceTabNewScheduler',
components: { components: {
BaseLoader, BaseLoader,
QueryEditor, QueryEditor,
WorkspaceTabPropsSchedulerTimingModal WorkspaceTabPropsSchedulerTimingModal,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,
@ -220,6 +205,15 @@ export default {
.map(schema => schema.tables); .map(schema => schema.tables);
return schemaTables.length ? schemaTables[0].filter(table => table.type === 'table') : []; return schemaTables.length ? schemaTables[0].filter(table => table.type === 'table') : [];
},
users () {
const users = [{ value: '' }, ...this.workspace.users];
if (!this.isDefinerInUsers) {
const [name, host] = this.originalScheduler.definer.replaceAll('`', '').split('@');
users.unshift({ name, host });
}
return users;
} }
}, },
watch: { watch: {

View File

@ -88,15 +88,13 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.collation') }} {{ $t('word.collation') }}
</label> </label>
<select v-model="localOptions.collation" class="form-select"> <BaseSelect
<option v-model="localOptions.collation"
v-for="collation in workspace.collations" :options="workspace.collations"
:key="collation.id" option-label="collation"
:value="collation.collation" option-track-by="collation"
> class="form-select"
{{ collation.collation }} />
</option>
</select>
</div> </div>
</div> </div>
<div v-if="workspace.customizations.engines" class="column col-auto"> <div v-if="workspace.customizations.engines" class="column col-auto">
@ -104,15 +102,13 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.engine') }} {{ $t('word.engine') }}
</label> </label>
<select v-model="localOptions.engine" class="form-select"> <BaseSelect
<option v-model="localOptions.engine"
v-for="engine in workspace.engines" class="form-select"
:key="engine.name" :options="workspace.engines"
:value="engine.name" option-label="name"
> option-track-by="name"
{{ engine.name }} />
</option>
</select>
</div> </div>
</div> </div>
</div> </div>
@ -175,6 +171,7 @@ import WorkspaceTabPropsTableFields from '@/components/WorkspaceTabPropsTableFie
import WorkspaceTabPropsTableIndexesModal from '@/components/WorkspaceTabPropsTableIndexesModal'; import WorkspaceTabPropsTableIndexesModal from '@/components/WorkspaceTabPropsTableIndexesModal';
import WorkspaceTabPropsTableForeignModal from '@/components/WorkspaceTabPropsTableForeignModal'; import WorkspaceTabPropsTableForeignModal from '@/components/WorkspaceTabPropsTableForeignModal';
import WorkspaceTabNewTableEmptyState from '@/components/WorkspaceTabNewTableEmptyState'; import WorkspaceTabNewTableEmptyState from '@/components/WorkspaceTabNewTableEmptyState';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabNewTable', name: 'WorkspaceTabNewTable',
@ -183,7 +180,8 @@ export default {
WorkspaceTabPropsTableFields, WorkspaceTabPropsTableFields,
WorkspaceTabPropsTableIndexesModal, WorkspaceTabPropsTableIndexesModal,
WorkspaceTabPropsTableForeignModal, WorkspaceTabPropsTableForeignModal,
WorkspaceTabNewTableEmptyState WorkspaceTabNewTableEmptyState,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,
@ -247,12 +245,12 @@ export default {
}, },
defaultCollation () { defaultCollation () {
if (this.workspace.customizations.collations) if (this.workspace.customizations.collations)
return this.getDatabaseVariable(this.selectedWorkspace, 'collation_server').value || ''; return this.getDatabaseVariable(this.selectedWorkspace, 'collation_server')?.value || '';
return ''; return '';
}, },
defaultEngine () { defaultEngine () {
if (this.workspace.customizations.engines) if (this.workspace.customizations.engines)
return this.workspace.engines.find(engine => engine.isDefault).name; return this.workspace.engines?.find(engine => engine.isDefault)?.name || '';
return ''; return '';
}, },
schemaTables () { schemaTables () {

View File

@ -46,60 +46,43 @@
<div v-if="customizations.definer" class="column col-auto"> <div v-if="customizations.definer" class="column col-auto">
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('word.definer') }}</label> <label class="form-label">{{ $t('word.definer') }}</label>
<select <BaseSelect
v-if="workspace.users.length"
v-model="localTrigger.definer" v-model="localTrigger.definer"
:options="users"
:option-label="(user) => user.value === '' ? $t('message.currentUser') : `${user.name}@${user.host}`"
:option-track-by="(user) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
class="form-select" class="form-select"
> />
<option value="">
{{ $t('message.currentUser') }}
</option>
<option v-if="!isDefinerInUsers" :value="originalTrigger.definer">
{{ originalTrigger.definer.replaceAll('`', '') }}
</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> </div>
<fieldset class="column columns mb-0" :disabled="customizations.triggerOnlyRename"> <fieldset class="column columns mb-0" :disabled="customizations.triggerOnlyRename">
<div class="column col-auto"> <div class="column col-auto">
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('word.table') }}</label> <label class="form-label">{{ $t('word.table') }}</label>
<select v-model="localTrigger.table" class="form-select"> <BaseSelect
<option v-for="table in schemaTables" :key="table.name"> v-model="localTrigger.table"
{{ table.name }} :options="schemaTables"
</option> option-label="name"
</select> option-track-by="name"
class="form-select"
/>
</div> </div>
</div> </div>
<div class="column col-auto"> <div class="column col-auto">
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('word.event') }}</label> <label class="form-label">{{ $t('word.event') }}</label>
<div class="input-group"> <div class="input-group">
<select v-model="localTrigger.activation" class="form-select"> <BaseSelect
<option>BEFORE</option> v-model="localTrigger.activation"
<option>AFTER</option> :options="['BEFORE', 'AFTER']"
</select> class="form-select"
<select />
<BaseSelect
v-if="!customizations.triggerMultipleEvents" v-if="!customizations.triggerMultipleEvents"
v-model="localTrigger.event" v-model="localTrigger.event"
:options="Object.keys(localEvents)"
class="form-select" class="form-select"
> />
<option v-for="event in Object.keys(localEvents)" :key="event">
{{ event }}
</option>
</select>
<div v-if="customizations.triggerMultipleEvents" class="px-4"> <div v-if="customizations.triggerMultipleEvents" class="px-4">
<label <label
v-for="event in Object.keys(localEvents)" v-for="event in Object.keys(localEvents)"
@ -138,12 +121,14 @@ import { useWorkspacesStore } from '@/stores/workspaces';
import QueryEditor from '@/components/QueryEditor'; import QueryEditor from '@/components/QueryEditor';
import BaseLoader from '@/components/BaseLoader'; import BaseLoader from '@/components/BaseLoader';
import Triggers from '@/ipc-api/Triggers'; import Triggers from '@/ipc-api/Triggers';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabNewTrigger', name: 'WorkspaceTabNewTrigger',
components: { components: {
BaseLoader, BaseLoader,
QueryEditor QueryEditor,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,
@ -211,6 +196,15 @@ export default {
.map(schema => schema.tables); .map(schema => schema.tables);
return schemaTables.length ? schemaTables[0].filter(table => table.type === 'table') : []; return schemaTables.length ? schemaTables[0].filter(table => table.type === 'table') : [];
},
users () {
const users = [{ value: '' }, ...this.workspace.users];
if (!this.isDefinerInUsers) {
const [name, host] = this.originalTrigger.definer.replaceAll('`', '').split('@');
users.unshift({ name, host });
}
return users;
} }
}, },
watch: { watch: {

View File

@ -45,11 +45,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.language') }} {{ $t('word.language') }}
</label> </label>
<select v-model="localFunction.language" class="form-select"> <BaseSelect
<option v-for="language in customizations.triggerFunctionlanguages" :key="language"> v-model="localFunction.language"
{{ language }} :options="customizations.triggerFunctionlanguages"
</option> class="form-select"
</select> />
</div> </div>
</div> </div>
<div v-if="customizations.definer" class="column col-auto"> <div v-if="customizations.definer" class="column col-auto">
@ -57,27 +57,13 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.definer') }} {{ $t('word.definer') }}
</label> </label>
<select <BaseSelect
v-if="workspace.users.length"
v-model="localFunction.definer" v-model="localFunction.definer"
:options="workspace.users"
:option-label="(user) => user.value === '' ? $t('message.currentUser') : `${user.name}@${user.host}`"
:option-track-by="(user) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
class="form-select" 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> </div>
<div v-if="customizations.comment" class="form-group"> <div v-if="customizations.comment" class="form-group">
@ -114,12 +100,14 @@ import { useWorkspacesStore } from '@/stores/workspaces';
import BaseLoader from '@/components/BaseLoader'; import BaseLoader from '@/components/BaseLoader';
import QueryEditor from '@/components/QueryEditor'; import QueryEditor from '@/components/QueryEditor';
import Functions from '@/ipc-api/Functions'; import Functions from '@/ipc-api/Functions';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabNewTriggerFunction', name: 'WorkspaceTabNewTriggerFunction',
components: { components: {
BaseLoader, BaseLoader,
QueryEditor QueryEditor,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,

View File

@ -46,61 +46,44 @@
<div class="column col-auto"> <div class="column col-auto">
<div v-if="workspace.customizations.definer" class="form-group"> <div v-if="workspace.customizations.definer" class="form-group">
<label class="form-label">{{ $t('word.definer') }}</label> <label class="form-label">{{ $t('word.definer') }}</label>
<select <BaseSelect
v-if="workspace.users.length"
v-model="localView.definer" v-model="localView.definer"
:options="users"
:option-label="(user) => user.value === '' ? $t('message.currentUser') : `${user.name}@${user.host}`"
:option-track-by="(user) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
class="form-select" class="form-select"
> />
<option value="">
{{ $t('message.currentUser') }}
</option>
<option v-if="!isDefinerInUsers" :value="originalView.definer">
{{ originalView.definer.replaceAll('`', '') }}
</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> </div>
<div class="column col-auto mr-2"> <div class="column col-auto mr-2">
<div v-if="workspace.customizations.viewSqlSecurity" class="form-group"> <div v-if="workspace.customizations.viewSqlSecurity" class="form-group">
<label class="form-label">{{ $t('message.sqlSecurity') }}</label> <label class="form-label">{{ $t('message.sqlSecurity') }}</label>
<select v-model="localView.security" class="form-select"> <BaseSelect
<option>DEFINER</option> v-model="localView.security"
<option>INVOKER</option> :options="['DEFINER', 'INVOKER']"
</select> class="form-select"
/>
</div> </div>
</div> </div>
<div class="column col-auto mr-2"> <div class="column col-auto mr-2">
<div v-if="workspace.customizations.viewAlgorithm" class="form-group"> <div v-if="workspace.customizations.viewAlgorithm" class="form-group">
<label class="form-label">{{ $t('word.algorithm') }}</label> <label class="form-label">{{ $t('word.algorithm') }}</label>
<select v-model="localView.algorithm" class="form-select"> <BaseSelect
<option>UNDEFINED</option> v-model="localView.algorithm"
<option>MERGE</option> :options="['UNDEFINED', 'MERGE', 'TEMPTABLE']"
<option>TEMPTABLE</option> class="form-select"
</select> />
</div> </div>
</div> </div>
<div v-if="workspace.customizations.viewUpdateOption" class="column col-auto mr-2"> <div v-if="workspace.customizations.viewUpdateOption" class="column col-auto mr-2">
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('message.updateOption') }}</label> <label class="form-label">{{ $t('message.updateOption') }}</label>
<select v-model="localView.updateOption" class="form-select"> <BaseSelect
<option value=""> v-model="localView.updateOption"
None :option-track-by="(user) => user.value"
</option> :options="[{label: 'None', value: ''}, {label: 'CASCADED', value: 'CASCADED'}, {label: 'LOCAL', value: 'LOCAL'}]"
<option>CASCADED</option> class="form-select"
<option>LOCAL</option> />
</select>
</div> </div>
</div> </div>
</div> </div>
@ -127,12 +110,14 @@ import { useWorkspacesStore } from '@/stores/workspaces';
import BaseLoader from '@/components/BaseLoader'; import BaseLoader from '@/components/BaseLoader';
import QueryEditor from '@/components/QueryEditor'; import QueryEditor from '@/components/QueryEditor';
import Views from '@/ipc-api/Views'; import Views from '@/ipc-api/Views';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabNewView', name: 'WorkspaceTabNewView',
components: { components: {
BaseLoader, BaseLoader,
QueryEditor QueryEditor,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,
@ -189,6 +174,15 @@ export default {
}, },
isDefinerInUsers () { isDefinerInUsers () {
return this.originalView ? this.workspace.users.some(user => this.originalView.definer === `\`${user.name}\`@\`${user.host}\``) : true; return this.originalView ? this.workspace.users.some(user => this.originalView.definer === `\`${user.name}\`@\`${user.host}\``) : true;
},
users () {
const users = [{ value: '' }, ...this.workspace.users];
if (!this.isDefinerInUsers) {
const [name, host] = this.originalView.definer.replaceAll('`', '').split('@');
users.unshift({ name, host });
}
return users;
} }
}, },
watch: { watch: {

View File

@ -66,11 +66,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.language') }} {{ $t('word.language') }}
</label> </label>
<select v-model="localFunction.language" class="form-select"> <BaseSelect
<option v-for="language in customizations.languages" :key="language"> v-model="localFunction.language"
{{ language }} :options="customizations.languages"
</option> class="form-select"
</select> />
</div> </div>
</div> </div>
<div v-if="customizations.definer" class="column col-auto"> <div v-if="customizations.definer" class="column col-auto">
@ -78,27 +78,13 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.definer') }} {{ $t('word.definer') }}
</label> </label>
<select <BaseSelect
v-if="workspace.users.length"
v-model="localFunction.definer" v-model="localFunction.definer"
:options="[{value: '', name:$t('message.currentUser')}, ...workspace.users]"
:option-label="(user) => user.value === '' ? user.name : `${user.name}@${user.host}`"
:option-track-by="(user) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
class="form-select" 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> </div>
<div class="column col-auto"> <div class="column col-auto">
@ -107,32 +93,16 @@
{{ $t('word.returns') }} {{ $t('word.returns') }}
</label> </label>
<div class="input-group"> <div class="input-group">
<select <BaseSelect
v-model="localFunction.returns" v-model="localFunction.returns"
class="form-select text-uppercase" class="form-select text-uppercase"
:options="[{ name: 'VOID' }, ...workspace.dataTypes]"
group-label="group"
group-values="types"
option-label="name"
option-track-by="name"
style="max-width: 150px;" style="max-width: 150px;"
> />
<option v-if="localFunction.returns === 'VOID'">
VOID
</option>
<option v-if="!isInDataTypes">
{{ localFunction.returns }}
</option>
<optgroup
v-for="group in workspace.dataTypes"
:key="group.group"
:label="group.group"
>
<option
v-for="type in group.types"
:key="type.name"
:selected="localFunction.returns === type.name"
:value="type.name"
>
{{ type.name }}
</option>
</optgroup>
</select>
<input <input
v-if="customizations.parametersLength" v-if="customizations.parametersLength"
v-model="localFunction.returnsLength" v-model="localFunction.returnsLength"
@ -162,10 +132,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('message.sqlSecurity') }} {{ $t('message.sqlSecurity') }}
</label> </label>
<select v-model="localFunction.security" class="form-select"> <BaseSelect
<option>DEFINER</option> v-model="localFunction.security"
<option>INVOKER</option> :options="['DEFINER', 'INVOKER']"
</select> class="form-select"
/>
</div> </div>
</div> </div>
<div v-if="customizations.functionDataAccess" class="column col-auto"> <div v-if="customizations.functionDataAccess" class="column col-auto">
@ -173,12 +144,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('message.dataAccess') }} {{ $t('message.dataAccess') }}
</label> </label>
<select v-model="localFunction.dataAccess" class="form-select"> <BaseSelect
<option>CONTAINS SQL</option> v-model="localFunction.dataAccess"
<option>NO SQL</option> :options="['CONTAINS SQL', 'NO SQL', 'READS SQL DATA', 'MODIFIES SQL DATA']"
<option>READS SQL DATA</option> class="form-select"
<option>MODIFIES SQL DATA</option> />
</select>
</div> </div>
</div> </div>
<div v-if="customizations.functionDeterministic" class="column col-auto"> <div v-if="customizations.functionDeterministic" class="column col-auto">
@ -231,6 +201,7 @@ import QueryEditor from '@/components/QueryEditor';
import WorkspaceTabPropsFunctionParamsModal from '@/components/WorkspaceTabPropsFunctionParamsModal'; import WorkspaceTabPropsFunctionParamsModal from '@/components/WorkspaceTabPropsFunctionParamsModal';
import ModalAskParameters from '@/components/ModalAskParameters'; import ModalAskParameters from '@/components/ModalAskParameters';
import Functions from '@/ipc-api/Functions'; import Functions from '@/ipc-api/Functions';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabPropsFunction', name: 'WorkspaceTabPropsFunction',
@ -238,7 +209,8 @@ export default {
BaseLoader, BaseLoader,
QueryEditor, QueryEditor,
WorkspaceTabPropsFunctionParamsModal, WorkspaceTabPropsFunctionParamsModal,
ModalAskParameters ModalAskParameters,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,

View File

@ -89,22 +89,15 @@
{{ $t('word.type') }} {{ $t('word.type') }}
</label> </label>
<div class="column"> <div class="column">
<select v-model="selectedParamObj.type" class="form-select text-uppercase"> <BaseSelect
<optgroup v-model="selectedParamObj.type"
v-for="group in workspace.dataTypes" class="form-select text-uppercase"
:key="group.group" :options="workspace.dataTypes"
:label="group.group" group-label="group"
> group-values="types"
<option option-label="name"
v-for="type in group.types" option-track-by="name"
:key="type.name" />
:selected="selectedParamObj.type.toUpperCase() === type.name"
:value="type.name"
>
{{ type.name }}
</option>
</optgroup>
</select>
</div> </div>
</div> </div>
<div v-if="customizations.parametersLength" class="form-group"> <div v-if="customizations.parametersLength" class="form-group">
@ -174,11 +167,13 @@
<script> <script>
import { uidGen } from 'common/libs/uidGen'; import { uidGen } from 'common/libs/uidGen';
import ConfirmModal from '@/components/BaseConfirmModal'; import ConfirmModal from '@/components/BaseConfirmModal';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabPropsFunctionParamsModal', name: 'WorkspaceTabPropsFunctionParamsModal',
components: { components: {
ConfirmModal ConfirmModal,
BaseSelect
}, },
props: { props: {
localParameters: { localParameters: {

View File

@ -66,11 +66,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.language') }} {{ $t('word.language') }}
</label> </label>
<select v-model="localRoutine.language" class="form-select"> <BaseSelect
<option v-for="language in customizations.languages" :key="language"> v-model="localRoutine.language"
{{ language }} :options="customizations.languages"
</option> class="form-select"
</select> />
</div> </div>
</div> </div>
<div v-if="customizations.definer" class="column col-auto"> <div v-if="customizations.definer" class="column col-auto">
@ -78,27 +78,13 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.definer') }} {{ $t('word.definer') }}
</label> </label>
<select <BaseSelect
v-if="workspace.users.length"
v-model="localRoutine.definer" v-model="localRoutine.definer"
:options="[{value: '', name:$t('message.currentUser')}, ...workspace.users]"
:option-label="(user) => user.value === '' ? user.name : `${user.name}@${user.host}`"
:option-track-by="(user) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
class="form-select" 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> </div>
<div v-if="customizations.comment" class="column"> <div v-if="customizations.comment" class="column">
@ -118,10 +104,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('message.sqlSecurity') }} {{ $t('message.sqlSecurity') }}
</label> </label>
<select v-model="localRoutine.security" class="form-select"> <BaseSelect
<option>DEFINER</option> v-model="localRoutine.security"
<option>INVOKER</option> :options="['DEFINER', 'INVOKER']"
</select> class="form-select"
/>
</div> </div>
</div> </div>
<div v-if="customizations.procedureDataAccess" class="column col-auto"> <div v-if="customizations.procedureDataAccess" class="column col-auto">
@ -129,12 +116,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('message.dataAccess') }} {{ $t('message.dataAccess') }}
</label> </label>
<select v-model="localRoutine.dataAccess" class="form-select"> <BaseSelect
<option>CONTAINS SQL</option> v-model="localRoutine.dataAccess"
<option>NO SQL</option> :options="['CONTAINS SQL', 'NO SQL', 'READS SQL DATA', 'MODIFIES SQL DATA']"
<option>READS SQL DATA</option> class="form-select"
<option>MODIFIES SQL DATA</option> />
</select>
</div> </div>
</div> </div>
<div v-if="customizations.procedureDeterministic" class="column col-auto"> <div v-if="customizations.procedureDeterministic" class="column col-auto">
@ -187,6 +173,7 @@ import BaseLoader from '@/components/BaseLoader';
import WorkspaceTabPropsRoutineParamsModal from '@/components/WorkspaceTabPropsRoutineParamsModal'; import WorkspaceTabPropsRoutineParamsModal from '@/components/WorkspaceTabPropsRoutineParamsModal';
import ModalAskParameters from '@/components/ModalAskParameters'; import ModalAskParameters from '@/components/ModalAskParameters';
import Routines from '@/ipc-api/Routines'; import Routines from '@/ipc-api/Routines';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabPropsRoutine', name: 'WorkspaceTabPropsRoutine',
@ -194,7 +181,8 @@ export default {
QueryEditor, QueryEditor,
BaseLoader, BaseLoader,
WorkspaceTabPropsRoutineParamsModal, WorkspaceTabPropsRoutineParamsModal,
ModalAskParameters ModalAskParameters,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,

View File

@ -89,22 +89,15 @@
{{ $t('word.type') }} {{ $t('word.type') }}
</label> </label>
<div class="column"> <div class="column">
<select v-model="selectedParamObj.type" class="form-select text-uppercase"> <BaseSelect
<optgroup v-model="selectedParamObj.type"
v-for="group in workspace.dataTypes" class="form-select text-uppercase"
:key="group.group" :options="workspace.dataTypes"
:label="group.group" group-label="group"
> group-values="types"
<option option-label="name"
v-for="type in group.types" option-track-by="name"
:key="type.name" />
:selected="selectedParamObj.type.toUpperCase() === type.name"
:value="type.name"
>
{{ type.name }}
</option>
</optgroup>
</select>
</div> </div>
</div> </div>
<div v-if="customizations.parametersLength" class="form-group"> <div v-if="customizations.parametersLength" class="form-group">
@ -174,11 +167,13 @@
<script> <script>
import { uidGen } from 'common/libs/uidGen'; import { uidGen } from 'common/libs/uidGen';
import ConfirmModal from '@/components/BaseConfirmModal'; import ConfirmModal from '@/components/BaseConfirmModal';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabPropsRoutineParamsModal', name: 'WorkspaceTabPropsRoutineParamsModal',
components: { components: {
ConfirmModal ConfirmModal,
BaseSelect
}, },
props: { props: {
localParameters: { localParameters: {

View File

@ -51,30 +51,13 @@
<div class="column col-auto"> <div class="column col-auto">
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('word.definer') }}</label> <label class="form-label">{{ $t('word.definer') }}</label>
<select <BaseSelect
v-if="workspace.users.length"
v-model="localScheduler.definer" v-model="localScheduler.definer"
:options="users"
:option-label="(user) => user.value === '' ? $t('message.currentUser') : `${user.name}@${user.host}`"
:option-track-by="(user) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
class="form-select" class="form-select"
> />
<option value="">
{{ $t('message.currentUser') }}
</option>
<option v-if="!isDefinerInUsers" :value="originalScheduler.definer">
{{ originalScheduler.definer.replaceAll('`', '') }}
</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> </div>
<div class="column"> <div class="column">
@ -148,13 +131,15 @@ import BaseLoader from '@/components/BaseLoader';
import QueryEditor from '@/components/QueryEditor'; import QueryEditor from '@/components/QueryEditor';
import WorkspaceTabPropsSchedulerTimingModal from '@/components/WorkspaceTabPropsSchedulerTimingModal'; import WorkspaceTabPropsSchedulerTimingModal from '@/components/WorkspaceTabPropsSchedulerTimingModal';
import Schedulers from '@/ipc-api/Schedulers'; import Schedulers from '@/ipc-api/Schedulers';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabPropsScheduler', name: 'WorkspaceTabPropsScheduler',
components: { components: {
BaseLoader, BaseLoader,
QueryEditor, QueryEditor,
WorkspaceTabPropsSchedulerTimingModal WorkspaceTabPropsSchedulerTimingModal,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,
@ -217,6 +202,15 @@ export default {
.map(schema => schema.tables); .map(schema => schema.tables);
return schemaTables.length ? schemaTables[0].filter(table => table.type === 'table') : []; return schemaTables.length ? schemaTables[0].filter(table => table.type === 'table') : [];
},
users () {
const users = [{ value: '' }, ...this.workspace.users];
if (!this.isDefinerInUsers) {
const [name, host] = this.originalScheduler.definer.replaceAll('`', '').split('@');
users.unshift({ name, host });
}
return users;
} }
}, },
watch: { watch: {

View File

@ -18,14 +18,11 @@
{{ $t('word.execution') }} {{ $t('word.execution') }}
</label> </label>
<div class="column"> <div class="column">
<select <BaseSelect
ref="firstInput"
v-model="optionsProxy.execution" v-model="optionsProxy.execution"
:options="['EVERY', 'ONCE']"
class="form-select" class="form-select"
> />
<option>EVERY</option>
<option>ONCE</option>
</select>
</div> </div>
</div> </div>
<div v-if="optionsProxy.execution === 'EVERY'"> <div v-if="optionsProxy.execution === 'EVERY'">
@ -39,27 +36,26 @@
type="text" type="text"
@keypress="isNumberOrMinus($event)" @keypress="isNumberOrMinus($event)"
> >
<select <BaseSelect
v-model="optionsProxy.every[1]" v-model="optionsProxy.every[1]"
class="form-select text-uppercase" class="form-select text-uppercase"
:options="['YEAR',
'QUARTER',
'MONTH',
'WEEK',
'DAY',
'HOUR',
'MINUTE',
'SECOND',
'YEAR_MONTH',
'DAY_HOUR',
'DAY_MINUTE',
'DAY_SECOND',
'HOUR_MINUTE',
'HOUR_SECOND',
'MINUTE_SECOND']"
style="width: 0;" style="width: 0;"
> />
<option>YEAR</option>
<option>QUARTER</option>
<option>MONTH</option>
<option>WEEK</option>
<option>DAY</option>
<option>HOUR</option>
<option>MINUTE</option>
<option>SECOND</option>
<option>YEAR_MONTH</option>
<option>DAY_HOUR</option>
<option>DAY_MINUTE</option>
<option>DAY_SECOND</option>
<option>HOUR_MINUTE</option>
<option>HOUR_SECOND</option>
<option>MINUTE_SECOND</option>
</select>
</div> </div>
</div> </div>
</div> </div>
@ -140,11 +136,13 @@
<script> <script>
import moment from 'moment'; import moment from 'moment';
import ConfirmModal from '@/components/BaseConfirmModal'; import ConfirmModal from '@/components/BaseConfirmModal';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabPropsSchedulerTimingModal', name: 'WorkspaceTabPropsSchedulerTimingModal',
components: { components: {
ConfirmModal ConfirmModal,
BaseSelect
}, },
props: { props: {
localOptions: Object, localOptions: Object,
@ -169,10 +167,6 @@ export default {
if (!this.optionsProxy.starts) this.optionsProxy.starts = moment().format('YYYY-MM-DD HH:mm:ss'); if (!this.optionsProxy.starts) this.optionsProxy.starts = moment().format('YYYY-MM-DD HH:mm:ss');
if (!this.optionsProxy.ends) this.optionsProxy.ends = moment().format('YYYY-MM-DD HH:mm:ss'); if (!this.optionsProxy.ends) this.optionsProxy.ends = moment().format('YYYY-MM-DD HH:mm:ss');
if (!this.optionsProxy.every.length) this.optionsProxy.every = ['1', 'DAY']; if (!this.optionsProxy.every.length) this.optionsProxy.every = ['1', 'DAY'];
setTimeout(() => {
this.$refs.firstInput.focus();
}, 20);
}, },
methods: { methods: {
confirmOptionsChange () { confirmOptionsChange () {

View File

@ -101,15 +101,13 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.collation') }} {{ $t('word.collation') }}
</label> </label>
<select v-model="localOptions.collation" class="form-select"> <BaseSelect
<option v-model="localOptions.collation"
v-for="collation in workspace.collations" :options="workspace.collations"
:key="collation.id" option-label="collation"
:value="collation.collation" option-track-by="collation"
> class="form-select"
{{ collation.collation }} />
</option>
</select>
</div> </div>
</div> </div>
<div v-if="workspace.customizations.engines" class="column col-auto"> <div v-if="workspace.customizations.engines" class="column col-auto">
@ -117,15 +115,13 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.engine') }} {{ $t('word.engine') }}
</label> </label>
<select v-model="localOptions.engine" class="form-select"> <BaseSelect
<option v-model="localOptions.engine"
v-for="engine in workspace.engines" class="form-select"
:key="engine.name" :options="workspace.engines"
:value="engine.name" option-label="name"
> option-track-by="name"
{{ engine.name }} />
</option>
</select>
</div> </div>
</div> </div>
</div> </div>
@ -186,6 +182,7 @@ import BaseLoader from '@/components/BaseLoader';
import WorkspaceTabPropsTableFields from '@/components/WorkspaceTabPropsTableFields'; import WorkspaceTabPropsTableFields from '@/components/WorkspaceTabPropsTableFields';
import WorkspaceTabPropsTableIndexesModal from '@/components/WorkspaceTabPropsTableIndexesModal'; import WorkspaceTabPropsTableIndexesModal from '@/components/WorkspaceTabPropsTableIndexesModal';
import WorkspaceTabPropsTableForeignModal from '@/components/WorkspaceTabPropsTableForeignModal'; import WorkspaceTabPropsTableForeignModal from '@/components/WorkspaceTabPropsTableForeignModal';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabPropsTable', name: 'WorkspaceTabPropsTable',
@ -193,7 +190,8 @@ export default {
BaseLoader, BaseLoader,
WorkspaceTabPropsTableFields, WorkspaceTabPropsTableFields,
WorkspaceTabPropsTableIndexesModal, WorkspaceTabPropsTableIndexesModal,
WorkspaceTabPropsTableForeignModal WorkspaceTabPropsTableForeignModal,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,

View File

@ -117,19 +117,14 @@
{{ $t('message.referenceTable') }} {{ $t('message.referenceTable') }}
</label> </label>
<div class="column"> <div class="column">
<select <BaseSelect
v-model="selectedForeignObj.refTable" v-model="selectedForeignObj.refTable"
:options="schemaTables"
option-label="name"
option-track-by="name"
class="form-select" class="form-select"
@change="reloadRefFields" @change="reloadRefFields"
> />
<option
v-for="schemaTable in schemaTables"
:key="schemaTable.name"
:value="schemaTable.name"
>
{{ schemaTable.name }}
</option>
</select>
</div> </div>
</div> </div>
<div class="form-group mb-4"> <div class="form-group mb-4">
@ -153,15 +148,11 @@
{{ $t('message.onUpdate') }} {{ $t('message.onUpdate') }}
</label> </label>
<div class="column"> <div class="column">
<select v-model="selectedForeignObj.onUpdate" class="form-select"> <BaseSelect
<option v-model="selectedForeignObj.onUpdate"
v-for="action in foreignActions" :options="foreignActions"
:key="action" class="form-select"
:value="action" />
>
{{ action }}
</option>
</select>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -169,15 +160,11 @@
{{ $t('message.onDelete') }} {{ $t('message.onDelete') }}
</label> </label>
<div class="column"> <div class="column">
<select v-model="selectedForeignObj.onDelete" class="form-select"> <BaseSelect
<option v-model="selectedForeignObj.onDelete"
v-for="action in foreignActions" :options="foreignActions"
:key="action" class="form-select"
:value="action" />
>
{{ action }}
</option>
</select>
</div> </div>
</div> </div>
</form> </form>
@ -206,11 +193,13 @@ import { useNotificationsStore } from '@/stores/notifications';
import { uidGen } from 'common/libs/uidGen'; import { uidGen } from 'common/libs/uidGen';
import Tables from '@/ipc-api/Tables'; import Tables from '@/ipc-api/Tables';
import ConfirmModal from '@/components/BaseConfirmModal'; import ConfirmModal from '@/components/BaseConfirmModal';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabPropsTableForeignModal', name: 'WorkspaceTabPropsTableForeignModal',
components: { components: {
ConfirmModal ConfirmModal,
BaseSelect
}, },
props: { props: {
localKeyUsage: Array, localKeyUsage: Array,

View File

@ -89,16 +89,12 @@
{{ $t('word.type') }} {{ $t('word.type') }}
</label> </label>
<div class="column"> <div class="column">
<select v-model="selectedIndexObj.type" class="form-select"> <BaseSelect
<option v-model="selectedIndexObj.type"
v-for="index in indexTypes" :options="indexTypes"
:key="index" :option-disabled="(opt) => opt === 'PRIMARY'"
:value="index" class="form-select"
:disabled="index === 'PRIMARY' && hasPrimary" />
>
{{ index }}
</option>
</select>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -140,11 +136,13 @@
<script> <script>
import { uidGen } from 'common/libs/uidGen'; import { uidGen } from 'common/libs/uidGen';
import ConfirmModal from '@/components/BaseConfirmModal'; import ConfirmModal from '@/components/BaseConfirmModal';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabPropsTableIndexesModal', name: 'WorkspaceTabPropsTableIndexesModal',
components: { components: {
ConfirmModal ConfirmModal,
BaseSelect
}, },
props: { props: {
localIndexes: Array, localIndexes: Array,

View File

@ -53,31 +53,18 @@
> >
{{ localRow.type }} {{ localRow.type }}
</span> </span>
<select <BaseSelect
v-else v-else
ref="editField" ref="editField"
v-model="editingContent" v-model="editingContent"
:options="types"
group-label="group"
group-values="types"
option-label="name"
option-track-by="name"
class="form-select editable-field pl-1 pr-4 small-select text-uppercase" class="form-select editable-field pl-1 pr-4 small-select text-uppercase"
@blur="editOFF" @blur="editOFF"
> />
<option v-if="!isInDataTypes">
{{ row.type }}
</option>
<optgroup
v-for="group in dataTypes"
:key="group.group"
:label="group.group"
>
<option
v-for="type in group.types"
:key="type.name"
:selected="localRow.type === type.name"
:value="type.name"
>
{{ type.name }}
</option>
</optgroup>
</select>
</div> </div>
<div <div
v-if="customizations.tableArray" v-if="customizations.tableArray"
@ -218,22 +205,16 @@
> >
{{ localRow.collation }} {{ localRow.collation }}
</span> </span>
<select <BaseSelect
v-else v-else
ref="editField" ref="editField"
v-model="editingContent" v-model="editingContent"
:options="collations"
option-label="collation"
option-track-by="collation"
class="form-select small-select pl-1 pr-4 editable-field" class="form-select small-select pl-1 pr-4 editable-field"
@blur="editOFF" @blur="editOFF"
> />
<option
v-for="collation in collations"
:key="collation.collation"
:selected="localRow.collation === collation.collation"
:value="collation.collation"
>
{{ collation.collation }}
</option>
</select>
</template> </template>
</div> </div>
<ConfirmModal <ConfirmModal
@ -347,11 +328,13 @@ import { storeToRefs } from 'pinia';
import { useNotificationsStore } from '@/stores/notifications'; import { useNotificationsStore } from '@/stores/notifications';
import { useWorkspacesStore } from '@/stores/workspaces'; import { useWorkspacesStore } from '@/stores/workspaces';
import ConfirmModal from '@/components/BaseConfirmModal'; import ConfirmModal from '@/components/BaseConfirmModal';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabPropsTableRow', name: 'WorkspaceTabPropsTableRow',
components: { components: {
ConfirmModal ConfirmModal,
BaseSelect
}, },
props: { props: {
row: Object, row: Object,
@ -431,6 +414,13 @@ export default {
typeNames = [...groupTypeNames, ...typeNames]; typeNames = [...groupTypeNames, ...typeNames];
} }
return typeNames.includes(this.row.type); return typeNames.includes(this.row.type);
},
types () {
const types = [...this.dataTypes];
if (!this.isInDataTypes)
types.unshift({ name: this.row });
return types;
} }
}, },
watch: { watch: {

View File

@ -45,60 +45,44 @@
<div v-if="customizations.definer" class="column col-auto"> <div v-if="customizations.definer" class="column col-auto">
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('word.definer') }}</label> <label class="form-label">{{ $t('word.definer') }}</label>
<select <BaseSelect
v-if="workspace.users.length"
v-model="localTrigger.definer" v-model="localTrigger.definer"
:options="users"
:option-label="(user) => user.value === '' ? $t('message.currentUser') : `${user.name}@${user.host}`"
:option-track-by="(user) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
class="form-select" class="form-select"
> />
<option value="">
{{ $t('message.currentUser') }}
</option>
<option v-if="!isDefinerInUsers" :value="originalTrigger.definer">
{{ originalTrigger.definer.replaceAll('`', '') }}
</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> </div>
<fieldset class="column columns mb-0" :disabled="customizations.triggerOnlyRename"> <fieldset class="column columns mb-0" :disabled="customizations.triggerOnlyRename">
<div class="column col-auto"> <div class="column col-auto">
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('word.table') }}</label> <label class="form-label">{{ $t('word.table') }}</label>
<select v-model="localTrigger.table" class="form-select"> <BaseSelect
<option v-for="table in schemaTables" :key="table.name"> v-model="localTrigger.table"
{{ table.name }} :options="schemaTables"
</option> option-label="name"
</select> option-track-by="name"
class="form-select"
/>
</div> </div>
</div> </div>
<div class="column col-auto"> <div class="column col-auto">
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('word.event') }}</label> <label class="form-label">{{ $t('word.event') }}</label>
<div class="input-group"> <div class="input-group">
<select v-model="localTrigger.activation" class="form-select"> <BaseSelect
<option>BEFORE</option> v-model="localTrigger.activation"
<option>AFTER</option> :options="['BEFORE', 'AFTER']"
</select> class="form-select"
<select />
<BaseSelect
v-if="!customizations.triggerMultipleEvents" v-if="!customizations.triggerMultipleEvents"
v-model="localTrigger.event" v-model="localTrigger.event"
:options="Object.keys(localEvents)"
class="form-select" class="form-select"
> />
<option v-for="event in Object.keys(localEvents)" :key="event">
{{ event }}
</option>
</select>
<div v-if="customizations.triggerMultipleEvents" class="px-4"> <div v-if="customizations.triggerMultipleEvents" class="px-4">
<label <label
v-for="event in Object.keys(localEvents)" v-for="event in Object.keys(localEvents)"
@ -137,12 +121,14 @@ import { useWorkspacesStore } from '@/stores/workspaces';
import QueryEditor from '@/components/QueryEditor'; import QueryEditor from '@/components/QueryEditor';
import BaseLoader from '@/components/BaseLoader'; import BaseLoader from '@/components/BaseLoader';
import Triggers from '@/ipc-api/Triggers'; import Triggers from '@/ipc-api/Triggers';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabPropsTrigger', name: 'WorkspaceTabPropsTrigger',
components: { components: {
BaseLoader, BaseLoader,
QueryEditor QueryEditor,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,
@ -208,6 +194,15 @@ export default {
.map(schema => schema.tables); .map(schema => schema.tables);
return schemaTables.length ? schemaTables[0].filter(table => table.type === 'table') : []; return schemaTables.length ? schemaTables[0].filter(table => table.type === 'table') : [];
},
users () {
const users = [{ value: '' }, ...this.workspace.users];
if (!this.isDefinerInUsers) {
const [name, host] = this.originalTrigger.definer.replaceAll('`', '').split('@');
users.unshift({ name, host });
}
return users;
} }
}, },
watch: { watch: {

View File

@ -32,11 +32,11 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.language') }} {{ $t('word.language') }}
</label> </label>
<select v-model="localFunction.language" class="form-select"> <BaseSelect
<option v-for="language in customizations.triggerFunctionlanguages" :key="language"> v-model="localFunction.language"
{{ language }} :options="customizations.triggerFunctionlanguages"
</option> class="form-select"
</select> />
</div> </div>
</div> </div>
<div v-if="customizations.definer" class="column col-auto"> <div v-if="customizations.definer" class="column col-auto">
@ -44,27 +44,13 @@
<label class="form-label"> <label class="form-label">
{{ $t('word.definer') }} {{ $t('word.definer') }}
</label> </label>
<select <BaseSelect
v-if="workspace.users.length"
v-model="localFunction.definer" v-model="localFunction.definer"
:options="workspace.users"
:option-label="(user) => user.value === '' ? $t('message.currentUser') : `${user.name}@${user.host}`"
:option-track-by="(user) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
class="form-select" 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> </div>
<div v-if="customizations.comment" class="form-group"> <div v-if="customizations.comment" class="form-group">
@ -110,13 +96,15 @@ import BaseLoader from '@/components/BaseLoader';
import QueryEditor from '@/components/QueryEditor'; import QueryEditor from '@/components/QueryEditor';
import ModalAskParameters from '@/components/ModalAskParameters'; import ModalAskParameters from '@/components/ModalAskParameters';
import Functions from '@/ipc-api/Functions'; import Functions from '@/ipc-api/Functions';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabPropsTriggerFunction', name: 'WorkspaceTabPropsTriggerFunction',
components: { components: {
BaseLoader, BaseLoader,
QueryEditor, QueryEditor,
ModalAskParameters ModalAskParameters,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,

View File

@ -45,61 +45,44 @@
<div class="column col-auto"> <div class="column col-auto">
<div v-if="workspace.customizations.definer" class="form-group"> <div v-if="workspace.customizations.definer" class="form-group">
<label class="form-label">{{ $t('word.definer') }}</label> <label class="form-label">{{ $t('word.definer') }}</label>
<select <BaseSelect
v-if="workspace.users.length"
v-model="localView.definer" v-model="localView.definer"
:options="users"
:option-label="(user) => user.value === '' ? $t('message.currentUser') : `${user.name}@${user.host}`"
:option-track-by="(user) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
class="form-select" class="form-select"
> />
<option value="">
{{ $t('message.currentUser') }}
</option>
<option v-if="!isDefinerInUsers" :value="originalView.definer">
{{ originalView.definer.replaceAll('`', '') }}
</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> </div>
<div class="column col-auto mr-2"> <div class="column col-auto mr-2">
<div v-if="workspace.customizations.viewSqlSecurity" class="form-group"> <div v-if="workspace.customizations.viewSqlSecurity" class="form-group">
<label class="form-label">{{ $t('message.sqlSecurity') }}</label> <label class="form-label">{{ $t('message.sqlSecurity') }}</label>
<select v-model="localView.security" class="form-select"> <BaseSelect
<option>DEFINER</option> v-model="localView.security"
<option>INVOKER</option> :options="['DEFINER', 'INVOKER']"
</select> class="form-select"
/>
</div> </div>
</div> </div>
<div class="column col-auto mr-2"> <div class="column col-auto mr-2">
<div v-if="workspace.customizations.viewAlgorithm" class="form-group"> <div v-if="workspace.customizations.viewAlgorithm" class="form-group">
<label class="form-label">{{ $t('word.algorithm') }}</label> <label class="form-label">{{ $t('word.algorithm') }}</label>
<select v-model="localView.algorithm" class="form-select"> <BaseSelect
<option>UNDEFINED</option> v-model="localView.algorithm"
<option>MERGE</option> :options="['UNDEFINED', 'MERGE', 'TEMPTABLE']"
<option>TEMPTABLE</option> class="form-select"
</select> />
</div> </div>
</div> </div>
<div v-if="workspace.customizations.viewUpdateOption" class="column col-auto mr-2"> <div v-if="workspace.customizations.viewUpdateOption" class="column col-auto mr-2">
<div class="form-group"> <div class="form-group">
<label class="form-label">{{ $t('message.updateOption') }}</label> <label class="form-label">{{ $t('message.updateOption') }}</label>
<select v-model="localView.updateOption" class="form-select"> <BaseSelect
<option value=""> v-model="localView.updateOption"
None :option-track-by="(user) => user.value"
</option> :options="[{label: 'None', value: ''}, {label: 'CASCADED', value: 'CASCADED'}, {label: 'LOCAL', value: 'LOCAL'}]"
<option>CASCADED</option> class="form-select"
<option>LOCAL</option> />
</select>
</div> </div>
</div> </div>
</div> </div>
@ -126,12 +109,14 @@ import { useWorkspacesStore } from '@/stores/workspaces';
import BaseLoader from '@/components/BaseLoader'; import BaseLoader from '@/components/BaseLoader';
import QueryEditor from '@/components/QueryEditor'; import QueryEditor from '@/components/QueryEditor';
import Views from '@/ipc-api/Views'; import Views from '@/ipc-api/Views';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabPropsView', name: 'WorkspaceTabPropsView',
components: { components: {
BaseLoader, BaseLoader,
QueryEditor QueryEditor,
BaseSelect
}, },
props: { props: {
tabUid: String, tabUid: String,
@ -184,6 +169,15 @@ export default {
}, },
isDefinerInUsers () { isDefinerInUsers () {
return this.originalView ? this.workspace.users.some(user => this.originalView.definer === `\`${user.name}\`@\`${user.host}\``) : true; return this.originalView ? this.workspace.users.some(user => this.originalView.definer === `\`${user.name}\`@\`${user.host}\``) : true;
},
users () {
const users = [{ value: '' }, ...this.workspace.users];
if (!this.isDefinerInUsers) {
const [name, host] = this.originalView.definer.replaceAll('`', '').split('@');
users.unshift({ name, host });
}
return users;
} }
}, },
watch: { watch: {

View File

@ -115,14 +115,13 @@
</div> </div>
<div class="input-group pr-2" :title="$t('message.commitMode')"> <div class="input-group pr-2" :title="$t('message.commitMode')">
<i class="input-group-addon addon-sm mdi mdi-24px mdi-source-commit p-0" /> <i class="input-group-addon addon-sm mdi mdi-24px mdi-source-commit p-0" />
<select v-model="autocommit" class="form-select select-sm text-bold"> <BaseSelect
<option :value="true"> v-model="autocommit"
{{ $t('message.autoCommit') }} :options="[{value: true, label: $t('message.autoCommit')}, {value: false, label: $t('message.manualCommit')}]"
</option> :option-label="opt => opt.label"
<option :value="false"> :option-track-by="opt => opt.value"
{{ $t('message.manualCommit') }} class="form-select select-sm text-bold"
</option> />
</select>
</div> </div>
</div> </div>
<div class="workspace-query-info"> <div class="workspace-query-info">
@ -149,14 +148,12 @@
</div> </div>
<div class="input-group" :title="$t('word.schema')"> <div class="input-group" :title="$t('word.schema')">
<i class="input-group-addon addon-sm mdi mdi-24px mdi-database" /> <i class="input-group-addon addon-sm mdi mdi-24px mdi-database" />
<select v-model="selectedSchema" class="form-select select-sm text-bold">
<option :value="null"> <BaseSelect
{{ $t('message.noSchema') }} v-model="selectedSchema"
</option> :options="[{value: 'null', label: $t('message.noSchema')}, ...databaseSchemas.map(el => ({label: el, value: el}))]"
<option v-for="schemaName in databaseSchemas" :key="schemaName"> class="form-select select-sm text-bold"
{{ schemaName }} />
</option>
</select>
</div> </div>
</div> </div>
</div> </div>
@ -199,6 +196,7 @@ import WorkspaceTabQueryTable from '@/components/WorkspaceTabQueryTable';
import WorkspaceTabQueryEmptyState from '@/components/WorkspaceTabQueryEmptyState'; import WorkspaceTabQueryEmptyState from '@/components/WorkspaceTabQueryEmptyState';
import ModalHistory from '@/components/ModalHistory'; import ModalHistory from '@/components/ModalHistory';
import tableTabs from '@/mixins/tableTabs'; import tableTabs from '@/mixins/tableTabs';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabQuery', name: 'WorkspaceTabQuery',
@ -207,7 +205,8 @@ export default {
QueryEditor, QueryEditor,
WorkspaceTabQueryTable, WorkspaceTabQueryTable,
WorkspaceTabQueryEmptyState, WorkspaceTabQueryEmptyState,
ModalHistory ModalHistory,
BaseSelect
}, },
mixins: [tableTabs], mixins: [tableTabs],
props: { props: {

View File

@ -38,25 +38,21 @@
class="editable-field form-input input-sm px-1" class="editable-field form-input input-sm px-1"
@blur="editOFF" @blur="editOFF"
> >
<select <BaseSelect
v-else-if="inputProps.type === 'boolean'" v-else-if="inputProps.type === 'boolean'"
v-model="editingContent" v-model="editingContent"
:options="['true', 'false']"
class="form-select small-select editable-field" class="form-select small-select editable-field"
@blur="editOFF" @blur="editOFF"
> />
<option>true</option> <BaseSelect
<option>false</option>
</select>
<select
v-else-if="enumArray" v-else-if="enumArray"
v-model="editingContent" v-model="editingContent"
:options="enumArray"
class="form-select small-select editable-field" class="form-select small-select editable-field"
dropdown-class="small-select"
@blur="editOFF" @blur="editOFF"
> />
<option v-for="value in enumArray" :key="value">
{{ value }}
</option>
</select>
<input <input
v-else v-else
ref="editField" ref="editField"
@ -95,19 +91,14 @@
<label for="editorMode" class="form-label mr-2"> <label for="editorMode" class="form-label mr-2">
<b>{{ $t('word.content') }}</b>: <b>{{ $t('word.content') }}</b>:
</label> </label>
<select <BaseSelect
id="editorMode" id="editorMode"
v-model="editorMode" v-model="editorMode"
:options="availableLanguages"
option-label="name"
option-track-by="slug"
class="form-select select-sm" class="form-select select-sm"
> />
<option
v-for="language in availableLanguages"
:key="language.slug"
:value="language.slug"
>
{{ language.name }}
</option>
</select>
</div> </div>
<div class="d-flex"> <div class="d-flex">
<div class="p-vcentered"> <div class="p-vcentered">
@ -223,6 +214,7 @@ import ConfirmModal from '@/components/BaseConfirmModal';
import TextEditor from '@/components/BaseTextEditor'; import TextEditor from '@/components/BaseTextEditor';
import BaseMap from '@/components/BaseMap'; import BaseMap from '@/components/BaseMap';
import ForeignKeySelect from '@/components/ForeignKeySelect'; import ForeignKeySelect from '@/components/ForeignKeySelect';
import BaseSelect from '@/components/BaseSelect.vue';
export default { export default {
name: 'WorkspaceTabQueryTableRow', name: 'WorkspaceTabQueryTableRow',
@ -230,7 +222,8 @@ export default {
ConfirmModal, ConfirmModal,
TextEditor, TextEditor,
ForeignKeySelect, ForeignKeySelect,
BaseMap BaseMap,
BaseSelect
}, },
props: { props: {
row: Object, row: Object,

View File

@ -311,7 +311,8 @@ option:checked {
margin: 0; margin: 0;
padding: 0.3rem 0.8rem; padding: 0.3rem 0.8rem;
.select-sm & { .select-sm &,
.small-select & {
padding: 0.05rem 0.3rem; padding: 0.05rem 0.3rem;
} }
} }