1
1
mirror of https://github.com/Fabio286/antares.git synced 2025-02-17 12:10:39 +01:00

feat(UI): sortable tabs

This commit is contained in:
Fabio Di Stasio 2021-07-14 20:30:54 +02:00
parent c87b8dc738
commit d38097d056
6 changed files with 124 additions and 111 deletions

View File

@ -8,7 +8,7 @@
@close-context="isContext = false" @close-context="isContext = false"
/> />
<ul class="settingbar-elements"> <ul class="settingbar-elements">
<draggable v-model="connections"> <Draggable v-model="connections">
<li <li
v-for="connection in connections" v-for="connection in connections"
:key="connection.uid" :key="connection.uid"
@ -22,7 +22,7 @@
<i class="settingbar-element-icon dbi" :class="`dbi-${connection.client} ${getStatusBadge(connection.uid)}`" /> <i class="settingbar-element-icon dbi" :class="`dbi-${connection.client} ${getStatusBadge(connection.uid)}`" />
<span class="ex-tooltip-content">{{ getConnectionName(connection.uid) }}</span> <span class="ex-tooltip-content">{{ getConnectionName(connection.uid) }}</span>
</li> </li>
</draggable> </Draggable>
<li <li
class="settingbar-element btn btn-link ex-tooltip" class="settingbar-element btn btn-link ex-tooltip"
:class="{'selected': 'NEW' === selectedWorkspace}" :class="{'selected': 'NEW' === selectedWorkspace}"
@ -52,13 +52,13 @@
<script> <script>
import { mapActions, mapGetters } from 'vuex'; import { mapActions, mapGetters } from 'vuex';
import draggable from 'vuedraggable'; import Draggable from 'vuedraggable';
import SettingBarContext from '@/components/SettingBarContext'; import SettingBarContext from '@/components/SettingBarContext';
export default { export default {
name: 'TheSettingBar', name: 'TheSettingBar',
components: { components: {
draggable, Draggable,
SettingBarContext SettingBarContext
}, },
data () { data () {

View File

@ -6,12 +6,88 @@
:is-selected="isSelected" :is-selected="isSelected"
/> />
<div v-if="workspace.connection_status === 'connected'" class="workspace-tabs column columns col-gapless"> <div v-if="workspace.connection_status === 'connected'" class="workspace-tabs column columns col-gapless">
<ul <Draggable
id="tabWrap"
ref="tabWrap" ref="tabWrap"
v-model="draggableTabs"
tag="ul"
group="tabs"
class="tab tab-block column col-12" class="tab tab-block column col-12"
draggable=".tab-draggable"
@mouseover.native="addWheelEvent"
> >
<li class="tab-item dropdown tools-dropdown"> <!-- <li
v-if="schemaChild && isSettingSupported"
class="tab-item"
:class="{'active': selectedTab === 'prop'}"
@click="selectTab({uid: workspace.uid, tab: 'prop'})"
>
<a class="tab-link">
<i class="mdi mdi-18px mdi-tune-vertical-variant mr-1" />
<span :title="schemaChild">{{ $t('word.settings').toUpperCase() }}: {{ schemaChild }}</span>
</a>
</li>
<li
v-if="workspace.breadcrumbs.table || workspace.breadcrumbs.view"
class="tab-item"
:class="{'active': selectedTab === 'data'}"
@click="selectTab({uid: workspace.uid, tab: 'data'})"
>
<a class="tab-link">
<i class="mdi mdi-18px mr-1" :class="workspace.breadcrumbs.table ? 'mdi-table' : 'mdi-table-eye'" />
<span :title="schemaChild">{{ $t('word.data').toUpperCase() }}: {{ schemaChild }}</span>
</a>
</li> -->
<li
v-for="(tab, i) of draggableTabs"
:key="i"
class="tab-item tab-draggable"
draggable="true"
:class="{'active': selectedTab === tab.uid}"
@click="selectTab({uid: workspace.uid, tab: tab.uid})"
@mouseup.middle="closeTab(tab)"
>
<a v-if="tab.type === 'query'" class="tab-link">
<i class="mdi mdi-18px mdi-code-tags mr-1" />
<span>
Query #{{ tab.index }}
<span
v-if="queryTabs.length > 1"
class="btn btn-clear"
:title="$t('word.close')"
@click.stop="closeTab(tab)"
/>
</span>
</a>
<a
v-else-if="tab.type === 'temp-data'"
class="tab-link"
@dblclick="openAsDataTab(tab)"
>
<i class="mdi mdi-18px mr-1" :class="tab.element === 'view' ? 'mdi-table-eye' : 'mdi-table'" />
<span :title="`${$t('word.data').toUpperCase()}: ${tab.table}`">
<span class=" text-italic">{{ tab.table }}</span>
<span
class="btn btn-clear"
:title="$t('word.close')"
@click.stop="closeTab(tab)"
/>
</span>
</a>
<a v-else-if="tab.type === 'data'" class="tab-link">
<i class="mdi mdi-18px mr-1" :class="tab.element === 'view' ? 'mdi-table-eye' : 'mdi-table'" />
<span :title="`${$t('word.data').toUpperCase()}: ${tab.table}`">
{{ tab.table }}
<span
class="btn btn-clear"
:title="$t('word.close')"
@click.stop="closeTab(tab)"
/>
</span>
</a>
</li>
<li slot="header" class="tab-item dropdown tools-dropdown">
<a <a
class="tab-link workspace-tools-link dropdown-toggle" class="tab-link workspace-tools-link dropdown-toggle"
tabindex="0" tabindex="0"
@ -48,78 +124,7 @@
</li> </li>
</ul> </ul>
</li> </li>
<!-- <li <li slot="footer" class="tab-item">
v-if="schemaChild && isSettingSupported"
class="tab-item"
:class="{'active': selectedTab === 'prop'}"
@click="selectTab({uid: workspace.uid, tab: 'prop'})"
>
<a class="tab-link">
<i class="mdi mdi-18px mdi-tune-vertical-variant mr-1" />
<span :title="schemaChild">{{ $t('word.settings').toUpperCase() }}: {{ schemaChild }}</span>
</a>
</li>
<li
v-if="workspace.breadcrumbs.table || workspace.breadcrumbs.view"
class="tab-item"
:class="{'active': selectedTab === 'data'}"
@click="selectTab({uid: workspace.uid, tab: 'data'})"
>
<a class="tab-link">
<i class="mdi mdi-18px mr-1" :class="workspace.breadcrumbs.table ? 'mdi-table' : 'mdi-table-eye'" />
<span :title="schemaChild">{{ $t('word.data').toUpperCase() }}: {{ schemaChild }}</span>
</a>
</li> -->
<li
v-for="tab of workspace.tabs"
:key="tab.uid"
class="tab-item"
:class="{'active': selectedTab === tab.uid}"
@click="selectTab({uid: workspace.uid, tab: tab.uid})"
@mouseup.middle="closeTab(tab)"
>
<a v-if="tab.type === 'query'" class="tab-link">
<i class="mdi mdi-18px mdi-code-tags mr-1" />
<span>
Query #{{ tab.index }}
<span
v-if="queryTabs.length > 1"
class="btn btn-clear"
:title="$t('word.close')"
@click.stop="closeTab(tab)"
/>
</span>
</a>
<a
v-if="tab.type === 'temp-data'"
class="tab-link"
@dblclick="openAsDataTab(tab)"
>
<i class="mdi mdi-18px mr-1" :class="tab.element === 'view' ? 'mdi-table-eye' : 'mdi-table'" />
<span :title="`${$t('word.data').toUpperCase()}: ${tab.table}`">
<span class=" text-italic">{{ tab.table }}</span>
<span
class="btn btn-clear"
:title="$t('word.close')"
@click.stop="closeTab(tab)"
/>
</span>
</a>
<a v-if="tab.type === 'data'" class="tab-link">
<i class="mdi mdi-18px mr-1" :class="tab.element === 'view' ? 'mdi-table-eye' : 'mdi-table'" />
<span :title="`${$t('word.data').toUpperCase()}: ${tab.table}`">
{{ tab.table }}
<span
class="btn btn-clear"
:title="$t('word.close')"
@click.stop="closeTab(tab)"
/>
</span>
</a>
</li>
<li class="tab-item">
<a <a
class="tab-add" class="tab-add"
:title="$t('message.openNewTab')" :title="$t('message.openNewTab')"
@ -128,7 +133,7 @@
<i class="mdi mdi-24px mdi-plus" /> <i class="mdi mdi-24px mdi-plus" />
</a> </a>
</li> </li>
</ul> </Draggable>
<!-- <WorkspacePropsTab <!-- <WorkspacePropsTab
v-show="selectedTab === 'prop' && workspace.breadcrumbs.table" v-show="selectedTab === 'prop' && workspace.breadcrumbs.table"
:is-selected="selectedTab === 'prop'" :is-selected="selectedTab === 'prop'"
@ -201,6 +206,7 @@
<script> <script>
import { mapGetters, mapActions } from 'vuex'; import { mapGetters, mapActions } from 'vuex';
import Draggable from 'vuedraggable';
import Connection from '@/ipc-api/Connection'; import Connection from '@/ipc-api/Connection';
import WorkspaceExploreBar from '@/components/WorkspaceExploreBar'; import WorkspaceExploreBar from '@/components/WorkspaceExploreBar';
import WorkspaceEditConnectionPanel from '@/components/WorkspaceEditConnectionPanel'; import WorkspaceEditConnectionPanel from '@/components/WorkspaceEditConnectionPanel';
@ -218,6 +224,7 @@ import ModalProcessesList from '@/components/ModalProcessesList';
export default { export default {
name: 'Workspace', name: 'Workspace',
components: { components: {
Draggable,
WorkspaceExploreBar, WorkspaceExploreBar,
WorkspaceEditConnectionPanel, WorkspaceEditConnectionPanel,
WorkspaceQueryTab, WorkspaceQueryTab,
@ -248,6 +255,14 @@ export default {
workspace () { workspace () {
return this.getWorkspace(this.connection.uid); return this.getWorkspace(this.connection.uid);
}, },
draggableTabs: {
get () {
return this.workspace.tabs;
},
set (val) {
this.updateTabs({ uid: this.connection.uid, tabs: val });
}
},
isSelected () { isSelected () {
return this.selectedWorkspace === this.connection.uid; return this.selectedWorkspace === this.connection.uid;
}, },
@ -305,14 +320,6 @@ export default {
if (isInitiated) if (isInitiated)
this.connectWorkspace(this.connection); this.connectWorkspace(this.connection);
}, },
mounted () {
if (this.$refs.tabWrap) {
this.$refs.tabWrap.addEventListener('wheel', e => {
if (e.deltaY > 0) this.$refs.tabWrap.scrollLeft += 50;
else this.$refs.tabWrap.scrollLeft -= 50;
});
}
},
methods: { methods: {
...mapActions({ ...mapActions({
addWorkspace: 'workspaces/addWorkspace', addWorkspace: 'workspaces/addWorkspace',
@ -320,15 +327,14 @@ export default {
removeConnected: 'workspaces/removeConnected', removeConnected: 'workspaces/removeConnected',
selectTab: 'workspaces/selectTab', selectTab: 'workspaces/selectTab',
newTab: 'workspaces/newTab', newTab: 'workspaces/newTab',
removeTab: 'workspaces/removeTab' removeTab: 'workspaces/removeTab',
updateTabs: 'workspaces/updateTabs'
}), }),
addQueryTab () { addQueryTab () {
this.newTab({ uid: this.connection.uid, type: 'query' }); this.newTab({ uid: this.connection.uid, type: 'query' });
this.addWheelEvent();
}, },
openAsDataTab (tab) { openAsDataTab (tab) {
this.newTab({ uid: this.connection.uid, schema: tab.schema, table: tab.table, type: 'data', element: tab.element }); this.newTab({ uid: this.connection.uid, schema: tab.schema, table: tab.table, type: 'data', element: tab.element });
this.addWheelEvent();
}, },
closeTab (tab) { closeTab (tab) {
if (tab.type === 'query' && this.queryTabs.length === 1) return; if (tab.type === 'query' && this.queryTabs.length === 1) return;
@ -345,9 +351,9 @@ export default {
}, },
addWheelEvent () { addWheelEvent () {
if (!this.hasWheelEvent) { if (!this.hasWheelEvent) {
this.$refs.tabWrap.addEventListener('wheel', e => { this.$refs.tabWrap.$el.addEventListener('wheel', e => {
if (e.deltaY > 0) this.$refs.tabWrap.scrollLeft += 50; if (e.deltaY > 0) this.$refs.tabWrap.$el.scrollLeft += 50;
else this.$refs.tabWrap.scrollLeft -= 50; else this.$refs.tabWrap.$el.scrollLeft -= 50;
}); });
this.hasWheelEvent = true; this.hasWheelEvent = true;
} }
@ -428,6 +434,8 @@ export default {
} }
&.tools-dropdown { &.tools-dropdown {
height: 34px;
.tab-link:focus { .tab-link:focus {
opacity: 1; opacity: 1;
outline: 0; outline: 0;

View File

@ -100,7 +100,7 @@
</div> </div>
</div> </div>
</div> </div>
<draggable <Draggable
ref="resultTable" ref="resultTable"
:list="fields" :list="fields"
class="tbody" class="tbody"
@ -117,14 +117,14 @@
@contextmenu="contextMenu" @contextmenu="contextMenu"
@rename-field="$emit('rename-field', $event)" @rename-field="$emit('rename-field', $event)"
/> />
</draggable> </Draggable>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { mapActions, mapGetters } from 'vuex'; import { mapActions, mapGetters } from 'vuex';
import draggable from 'vuedraggable'; import Draggable from 'vuedraggable';
import TableRow from '@/components/WorkspacePropsTableRow'; import TableRow from '@/components/WorkspacePropsTableRow';
import TableContext from '@/components/WorkspacePropsTableContext'; import TableContext from '@/components/WorkspacePropsTableContext';
@ -133,7 +133,7 @@ export default {
components: { components: {
TableRow, TableRow,
TableContext, TableContext,
draggable Draggable
}, },
props: { props: {
fields: Array, fields: Array,

View File

@ -197,19 +197,8 @@
color: $body-font-color-dark; color: $body-font-color-dark;
} }
& &.tools-dropdown { &.tools-dropdown {
.tab-link:focus { background-color: $bg-color-light-dark;
color: $primary-color;
}
.menu {
.menu-item a {
&:hover {
color: $primary-color;
background: $bg-color-gray;
}
}
}
} }
} }

View File

@ -191,6 +191,16 @@
} }
} }
.workspace-tabs {
.tab-block {
.tab-item {
&.tools-dropdown {
background-color: $body-bg;
}
}
}
}
.workspace-query-results { .workspace-query-results {
.table { .table {
.th { .th {

View File

@ -238,6 +238,9 @@ export default {
SELECT_TAB (state, { uid, tab }) { SELECT_TAB (state, { uid, tab }) {
state.workspaces = state.workspaces.map(workspace => workspace.uid === uid ? { ...workspace, selected_tab: tab } : workspace); state.workspaces = state.workspaces.map(workspace => workspace.uid === uid ? { ...workspace, selected_tab: tab } : workspace);
}, },
UPDATE_TABS (state, { uid, tabs }) {
state.workspaces = state.workspaces.map(workspace => workspace.uid === uid ? { ...workspace, tabs } : workspace); ;
},
SET_TAB_FIELDS (state, { cUid, tUid, fields }) { SET_TAB_FIELDS (state, { cUid, tUid, fields }) {
state.workspaces = state.workspaces.map(workspace => { state.workspaces = state.workspaces.map(workspace => {
if (workspace.uid === cUid) { if (workspace.uid === cUid) {
@ -552,6 +555,9 @@ export default {
selectTab ({ commit }, payload) { selectTab ({ commit }, payload) {
commit('SELECT_TAB', payload); commit('SELECT_TAB', payload);
}, },
updateTabs ({ commit }, payload) {
commit('UPDATE_TABS', payload);
},
setTabFields ({ commit }, payload) { setTabFields ({ commit }, payload) {
commit('SET_TAB_FIELDS', payload); commit('SET_TAB_FIELDS', payload);
}, },