Browse Source

refactor: ui improvements

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/958/head
Pranav C 3 years ago
parent
commit
0425538b32
  1. 6
      packages/nc-gui/assets/style.css
  2. 94
      packages/nc-gui/components/ProjectTreeView.vue
  3. 2
      packages/nc-gui/components/authTab.vue
  4. 49
      packages/nc-gui/components/global/xBtn.vue
  5. 2
      packages/nc-gui/components/project/spreadsheet/components/columnFilterMenu.vue
  6. 2
      packages/nc-gui/components/project/spreadsheet/components/fieldsMenu.vue
  7. 31
      packages/nc-gui/components/project/spreadsheet/components/moreActions.vue
  8. 61
      packages/nc-gui/components/project/spreadsheet/components/shareViewMenu.vue
  9. 2
      packages/nc-gui/components/project/spreadsheet/components/sortListMenu.vue
  10. 66
      packages/nc-gui/components/project/spreadsheet/components/spreadsheetNavDrawer.vue
  11. 14
      packages/nc-gui/components/project/spreadsheet/public/xcKanban.vue
  12. 2
      packages/nc-gui/components/project/spreadsheet/public/xcTable.vue
  13. 135
      packages/nc-gui/components/project/spreadsheet/rowsXcDataTable.vue
  14. 2
      packages/nc-gui/components/project/spreadsheet/views/xcGridView.vue
  15. 2
      packages/nc-gui/components/project/viewTabs/viewSpreadsheet.vue
  16. 66
      packages/nc-gui/components/projectTabs.vue
  17. 4
      packages/nc-gui/config/vuetify.options.js
  18. 2
      packages/nc-gui/helpers/treeViewDataSerializer.js
  19. 4
      packages/nc-gui/lang/en.json
  20. 38
      packages/nc-gui/layouts/default.vue
  21. 15
      packages/nc-gui/pages/nc/_project_id.vue
  22. 2
      packages/nc-gui/pages/nc/index.vue
  23. 2
      packages/nc-gui/pages/project/xcdb.vue

6
packages/nc-gui/assets/style.css

@ -275,7 +275,7 @@ tbody tr:nth-of-type(odd) {
}
.project-tabs > .v-tabs-items {
height: calc(100% - 35px);
height: calc(100% - 30px);
overflow: auto;
}
@ -491,3 +491,7 @@ body.dark .toasted .primary.info, body.dark .toasted.toasted-primary.info {
.v-date-picker-table {
height: auto !important;
}
.nc-remove-border{
border: none !important;
}

94
packages/nc-gui/components/ProjectTreeView.vue

@ -1,13 +1,18 @@
<template>
<div style="height: 100%" class="nc-tree-view" @mouseenter="onMiniHoverEnter" @mouseleave="onMiniHoverLeave">
<!-- :expand-on-hover="mini"-->
<div
class="primary nc-project-title theme--dark"
>
<div>{{ $store.getters["project/GtrProjectName"] }}</div>
</div>
<v-navigation-drawer
ref="drawer"
v-model="navigation.shown"
permanent
mini-variant-width="50"
class="pl-2 nc-nav-drawer"
style="min-width: 100%; height: 100%"
style="min-width: 100%; height: calc(100% - 30px)"
>
<div class="h-100 d-flex flex-column">
<div class="flex-grow-1" style="overflow-y: auto; min-height: 200px">
@ -156,11 +161,11 @@
<v-list-item-title>
<v-tooltip v-if="!isNonAdminAccessAllowed(item)" top>
<template #activator="{ on }">
<span v-if="item.type === 'tableDir'" class="caption font-weight-regular" v-on="on">
<span v-if="item.type === 'tableDir'" class="body-2 font-weight-medium" v-on="on">
Tables<template v-if="item.children && item.children.length"> ({{
item.children.filter(child => !search || child.name.toLowerCase().includes(search.toLowerCase())).length
}})</template></span>
<span v-else class="caption font-weight-regular" v-on="on">
<span v-else class="body-2 font-weight-medium" v-on="on">
{{ item.name }}</span>
</template>
<span class="caption">Only visible to Creator</span>
@ -168,7 +173,7 @@
<template
v-else
>
<span v-if="item.type === 'tableDir'" class="caption font-weight-regular">
<span v-if="item.type === 'tableDir'" class="body-2 font-weight-medium">
Tables<template v-if="item.children && item.children.length"> ({{
item.children.filter(child => !search || child.name.toLowerCase().includes(search.toLowerCase())).length
}})</template></span>
@ -312,7 +317,7 @@
</v-list>
</v-menu>
<!-- <v-icon @click.stop="" x-small>mdi-delete-outline</v-icon>-->
<!-- <v-icon @click.stop="" x-small>mdi-delete-outline</v-icon>-->
</div>
</template>
</v-list-item>
@ -392,12 +397,12 @@
<v-list-item>
<v-list-item-title>
<!-- Settings -->
<span class="body-2 grey--text">{{ $t('treeview.settings.title') }}</span>
<span class="body-2 font-weight-medium">{{ $t('treeview.settings.title') }}</span>
<v-tooltip top>
<template #activator="{ on }">
<x-icon
class="mt-n1"
color="pink grey"
color="pink textColor"
icon-class="ml-2"
small
v-on="on"
@ -472,6 +477,26 @@
<!-- Meta Management -->
{{ $t('treeview.project_metadata.tooltip') }}
</v-tooltip>
<v-tooltip bottom>
<template #activator="{ on }">
<v-list-item dense class="body-2 nc-settings-projmeta" @click="openAuditTab" v-on="on">
<v-list-item-icon>
<v-icon x-small>
mdi-notebook-outline
</v-icon>
</v-list-item-icon>
<!-- Project Metadata -->
<v-list-item-title>
<span class="font-weight-regular caption">{{
$t('treeview.audit.title')
}}</span>
</v-list-item-title>
</v-list-item>
</template>
<!-- Meta Management -->
{{ $t('treeview.audit.tooltip') }}
</v-tooltip>
</template>
</v-list>
<v-divider />
@ -529,7 +554,7 @@
<v-list v-if="_isUIAllowed('previewAs') || previewAs" dense>
<v-list-item>
<!-- Preview as -->
<span class="body-2 grey--text">{{ $t('treeview.preview_as') }}</span>
<span class="body-2 font-weight-medium">{{ $t('treeview.preview_as') }}</span>
<v-icon small class="ml-1">
mdi-drama-masks
</v-icon>
@ -718,8 +743,9 @@ export default {
dlgLabelSubmitCancel,
},
data: () => ({
drag:false,
dragOptions:{
treeViewStatus: {},
drag: false,
dragOptions: {
animation: 200,
group: "description",
disabled: false,
@ -970,6 +996,21 @@ export default {
item._nodes.type = 'disableOrEnableModel';
this.$store.dispatch('tabs/ActAddTab', item);
}
}, openAuditTab() {
const tabIndex = this.tabs.findIndex(el => el.key === `migrationsDir`);
if (tabIndex !== -1) {
this.changeActiveTab(tabIndex);
} else {
console.log('add audit tab');
let item = {name: 'Audit', key: `migrationsDir`};
item._nodes = {
env: '_noco',
dbAlias: 'db'
};
item._nodes.type = 'migrationsDir';
item._nodes.dbKey = '';
this.$store.dispatch('tabs/ActAddTab', item);
}
},
toggleMini() {
this.$store.commit('panelSize/MutSize', {
@ -1097,7 +1138,7 @@ export default {
}
},
isActiveList(item) {
return item.type === this.$route.query.type || item.type === `${this.$route.query.type}Dir`;
return true//this.treeViewStatus[item.type] = this.treeViewStatus[item.type] || item.type === this.$route.query.type || item.type === `${this.$route.query.type}Dir`;
},
showNode(item) {
return (
@ -1223,7 +1264,7 @@ export default {
} else if (action === "ENV_DB_TABLES_REFRESH") {
await this.loadTables(this.menuItem);
this.$toast.success('Tables refreshed').goAway(1000);
}else if (action === 'ENV_DB_VIEWS_REFRESH') {
} else if (action === 'ENV_DB_VIEWS_REFRESH') {
await this.loadViews(this.menuItem);
this.$toast.success('Views refreshed').goAway(1000);
} else if (action === 'IMPORT_EXCEL') {
@ -1861,18 +1902,39 @@ export default {
}
.flip-list-move {
.flip-list-move {
transition: transform 0.5s;
}
.no-move {
.no-move {
transition: transform 0s;
}
.ghost {
.ghost {
opacity: 0.5;
background: grey;
}
.nc-project-title {
height: 30px;
width: 100%;
display: flex;
justify-content: center;
}
.nc-project-title > div {
display: block;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
color: white;
font-weight: bold;
padding:0 10px 10px 10px;
text-transform: capitalize;
line-height: 20px;
min-width: calc(100% - 30px);
}
</style>
<!--

2
packages/nc-gui/components/authTab.vue

@ -9,7 +9,7 @@
</span>
</v-tab>
<v-tab-item class="h-100">
<user-management :nodes="nodes" />
<user-management class="backgroundColor" :nodes="nodes" />
</v-tab-item>
<template v-if="_isUIAllowed('apiTokenTab')">

49
packages/nc-gui/components/global/xBtn.vue

@ -1,31 +1,47 @@
<template>
<v-tooltip v-if="tooltip || $slots['tooltip']" v-bind="tooltipProp">
<template #activator="{ on }">
<v-btn :class="[btnClass,$attrs['btn.class']]" v-bind="$attrs" v-on="{...$listeners,...on}">
<template v-if="icon">
<v-icon small>
{{ icon }}
</v-icon>&nbsp;
</template>
<slot />
</v-btn>
<v-hover v-slot="{ hover }">
<v-btn
:style="{backgroundColor : hover ? colors[0] : colors[1]}"
:class="[btnClass,$attrs['btn.class']]"
v-bind="$attrs"
v-on="{...$listeners,...on}"
>
<template v-if="icon">
<v-icon small>
{{ icon }}
</v-icon>&nbsp;
</template>
<slot />
</v-btn>
</v-hover>
</template>
<slot name="tooltip">
<span>{{ tooltip }}</span>
</slot>
</v-tooltip>
<v-btn v-else ref="btn" v-bind="$attrs" :class="[btnClass,$attrs['btn.class']]" v-on="$listeners">
<v-icon v-if="icon">
{{ icon }}
</v-icon>
<slot />
</v-btn>
<v-hover v-else v-slot="{ hover }">
<v-btn
ref="btn"
v-bind="$attrs"
:class="[btnClass,$attrs['btn.class']]"
:style="{backgroundColor : hover ? colors[0] : colors[1]}"
v-on="$listeners"
>
<v-icon v-if="icon">
{{ icon }}
</v-icon>
<slot />
</v-btn>
</v-hover>
</template>
<script>
export default {
name: 'XBtn',
props: {
color: String,
tooltipProp: {
type: Object,
default: () => ({
@ -36,6 +52,11 @@ export default {
tooltip: String,
icon: String
},
computed: {
colors() {
return this.color ? (Array.isArray(this.color) ? this.color : this.color.split(' ')) : []
}
},
methods: {
}
}

2
packages/nc-gui/components/project/spreadsheet/components/columnFilterMenu.vue

@ -8,7 +8,7 @@
overlap
>
<v-btn
class="nc-filter-menu-btn px-2"
class="nc-filter-menu-btn px-2 nc-remove-border"
:disabled="isLocked"
outlined
small

2
packages/nc-gui/components/project/spreadsheet/components/fieldsMenu.vue

@ -8,7 +8,7 @@
overlap
>
<v-btn
class="nc-fields-menu-btn px-2"
class="nc-fields-menu-btn px-2 nc-remove-border"
:disabled="isLocked"
outlined
small

31
packages/nc-gui/components/project/spreadsheet/components/exportImport.vue → packages/nc-gui/components/project/spreadsheet/components/moreActions.vue

@ -8,7 +8,7 @@
<template #activator="{on}">
<v-btn
outlined
class="nc-actions-menu-btn caption px-2"
class="nc-actions-menu-btn caption px-2 nc-remove-border font-weight-medium"
small
text
v-on="on"
@ -16,7 +16,7 @@
<v-icon small color="#777">
mdi-flash-outline
</v-icon>
Actions
More
<v-icon small color="#777">
mdi-menu-down
@ -56,6 +56,33 @@
</x-icon> version)</span>
</v-list-item-title>
</v-list-item>
<v-list-item
v-if="_isUIAllowed('csvImport') && !isView"
dense
@click="$emit('showAdditionalFeatOverlay', 'shared-views')"
>
<v-list-item-title>
<v-icon small class="mr-1" color="">
mdi-view-list-outline
</v-icon>
<span class="caption ">
Shared View List
</span>
</v-list-item-title>
</v-list-item> <v-list-item
v-if="_isUIAllowed('csvImport') && !isView"
dense
@click="$emit('webhook')"
>
<v-list-item-title>
<v-icon small class="mr-1" color="">
mdi-hook
</v-icon>
<span class="caption ">
Webhooks
</span>
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
<drop-or-select-file-modal v-model="importModal" accept=".csv" text="CSV" @file="onCsvFileSelection" />

61
packages/nc-gui/components/project/spreadsheet/components/shareViewMenu.vue

@ -0,0 +1,61 @@
<template>
<div>
<!-- <v-menu
open-on-hover
bottom
offset-y
>
<template #activator="{on}">-->
<v-btn
outlined
class="nc-actions-menu-btn caption px-2 nc-remove-border font-weight-medium"
small
text
@click="$emit('share')"
>
<v-icon size="13" class="mr-1" color="#777">
mdi-open-in-new
</v-icon>
Share View
</v-btn>
<!-- </template>
<v-list dense>
<v-list-item
dense
>
<v-list-item-title>
<v-icon small class="mr-1">
mdi-open-in-new
</v-icon>
<span class="caption">
Share View
</span>
</v-list-item-title>
</v-list-item>
<v-list dense>
<v-list-item
dense
>
<v-list-item-title>
<v-icon small class="mr-1">
mdi-download-outline
</v-icon>
<span class="caption">
Shared Views List
</span>
</v-list-item-title>
</v-list-item>
</v-list>
</v-list>
</v-menu>-->
</div>
</template>
<script>
export default {
name: 'ShareViewMenu'
}
</script>
<style scoped />

2
packages/nc-gui/components/project/spreadsheet/components/sortListMenu.vue

@ -8,7 +8,7 @@
overlap
>
<v-btn
class="nc-sort-menu-btn px-2"
class="nc-sort-menu-btn px-2 nc-remove-border"
:disabled="isLocked"
small
text

66
packages/nc-gui/components/project/spreadsheet/components/spreadsheetNavDrawer.vue

@ -13,7 +13,7 @@
<v-list v-if="viewsList && viewsList.length" dense>
<v-list-item dense>
<!-- Views -->
<span class="body-2 grey--text">{{ $t('nav_drawer.title') }}</span>
<span class="body-2 font-weight-medium">{{ $t('nav_drawer.title') }}</span>
</v-list-item>
<v-list-item-group v-model="selectedViewIdLocal" mandatory color="primary">
<draggable
@ -138,13 +138,13 @@
>
<v-list-item dense>
<!-- Create a View -->
<span class="body-2 grey--text" @dblclick="enableDummyFeat = true">
<span class="body-2 font-weight-medium" @dblclick="enableDummyFeat = true">
{{ $t('nav_drawer.virtual_views.title') }}
</span>
<v-tooltip top>
<template #activator="{ on }">
<x-icon
color="pink grey"
color="pink textColor"
icon-class="ml-2"
small
v-on="on"
@ -332,7 +332,7 @@
</v-hover>
</div>
-->
<div v-if="_isUIAllowed('table-advanced')">
<!-- <div v-if="_isUIAllowed('table-advanced')">
<v-divider />
<v-list
dense
@ -342,13 +342,13 @@
>
<v-list-item dense>
<span
class="body-2 grey--text"
class="body-2 font-weight-medium"
@dblclick="$emit('update:showAdvanceOptions', !showAdvanceOptions)"
>Advanced</span>
<v-tooltip top>
<template #activator="{ on }">
<x-icon
color="pink grey"
color="pink textColor"
icon-class="ml-2"
small
v-on="on"
@ -359,21 +359,21 @@
</x-icon>
</template>
<span class="caption">
<!-- Only visible to Creator -->
&lt;!&ndash; Only visible to Creator &ndash;&gt;
{{ $t('nav_drawer.virtual_views.caption') }}
</span>
</v-tooltip>
</v-list-item>
<!-- <v-tooltip bottom>-->
<!-- <template v-slot:activator="{on}">-->
<!-- <v-menu offset-x left>-->
<!-- <template v-slot:activator="{on}">-->
&lt;!&ndash; <v-tooltip bottom>&ndash;&gt;
&lt;!&ndash; <template v-slot:activator="{on}">&ndash;&gt;
&lt;!&ndash; <v-menu offset-x left>&ndash;&gt;
&lt;!&ndash; <template v-slot:activator="{on}">&ndash;&gt;
<!--
&lt;!&ndash;
TODO:
- Add selectedView.show_as === 'kanban' when it is ready
-->
<v-list-item
&ndash;&gt;
&lt;!&ndash; <v-list-item
v-show="
selectedView && (selectedView.type === 'view' || selectedView.type === 'table' || selectedView.show_as === 'form' || selectedView.show_as === 'grid' )
"
@ -384,7 +384,7 @@
mdi-open-in-new
</v-icon>
<span class="caption">
<!-- Share View -->
&lt;!&ndash; Share View &ndash;&gt;
{{ $t('nav_drawer.advanced.title1') }}
</span>
<v-spacer />
@ -398,34 +398,34 @@
<v-list-item dense @click="$emit('showAdditionalFeatOverlay', 'shared-views')">
<v-list-item-title>
<span class="font-weight-regular">
<!-- Views List -->
&lt;!&ndash; Views List &ndash;&gt;
{{ $t('nav_drawer.advanced.views_list') }}
</span>
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-list-item>
<!-- <v-tooltip bottom>-->
<!-- <template #activator="{ on }">-->
<!-- <v-list-item v-on="on" @click="copyapiUrlToClipboard">-->
<!-- <v-icon x-small class="mr-2">-->
<!-- mdi-content-copy-->
<!-- </v-icon>-->
<!-- &lt;!&ndash; Copy API URL &ndash;&gt;-->
<!-- <span class="caption">{{ $t('nav_drawer.advanced.views_list') }}</span>-->
<!-- </v-list-item>-->
<!-- </template>-->
<!-- &lt;!&ndash; Copy API URL &ndash;&gt;-->
<!-- {{ $t('nav_drawer.advanced.views_list') }}-->
<!-- </v-tooltip>-->
</v-list-item>&ndash;&gt;
&lt;!&ndash; <v-tooltip bottom>&ndash;&gt;
&lt;!&ndash; <template #activator="{ on }">&ndash;&gt;
&lt;!&ndash; <v-list-item v-on="on" @click="copyapiUrlToClipboard">&ndash;&gt;
&lt;!&ndash; <v-icon x-small class="mr-2">&ndash;&gt;
&lt;!&ndash; mdi-content-copy&ndash;&gt;
&lt;!&ndash; </v-icon>&ndash;&gt;
&lt;!&ndash; &lt;!&ndash; Copy API URL &ndash;&gt;&ndash;&gt;
&lt;!&ndash; <span class="caption">{{ $t('nav_drawer.advanced.views_list') }}</span>&ndash;&gt;
&lt;!&ndash; </v-list-item>&ndash;&gt;
&lt;!&ndash; </template>&ndash;&gt;
&lt;!&ndash; &lt;!&ndash; Copy API URL &ndash;&gt;&ndash;&gt;
&lt;!&ndash; {{ $t('nav_drawer.advanced.views_list') }}&ndash;&gt;
&lt;!&ndash; </v-tooltip>&ndash;&gt;
<template v-if="_isUIAllowed('model')">
<v-divider class="advance-menu-divider" />
&lt;!&ndash; <v-divider class="advance-menu-divider" />&ndash;&gt;
<slot />
</template>
</v-list>
</div>
</div>-->
</div>
</v-container>

14
packages/nc-gui/components/project/spreadsheet/public/xcKanban.vue

@ -32,15 +32,15 @@
:class="`cell-height-${cellHeight}`"
style="overflow:auto;transition: width 500ms "
>
<v-container fluid v-if="loadingData">
<v-container v-if="loadingData" fluid>
<v-row>
<v-col v-for="idx in 5" :key="idx">
<v-skeleton-loader type="image@3"></v-skeleton-loader>
<v-skeleton-loader type="image@3" />
</v-col>
</v-row>
</v-container>
<kanban-view
v-if="!loadingData && kanban.data.length"
v-if="!loadingData && kanban.data.length"
:nodes="nodes"
:table="table"
:show-fields="showFields"
@ -64,7 +64,7 @@ import spreadsheet from '../mixins/spreadsheet'
import FieldsMenu from '../components/fieldsMenu'
import SortListMenu from '../components/sortListMenu'
import ColumnFilterMenu from '../components/columnFilterMenu'
import CsvExportImport from '~/components/project/spreadsheet/components/exportImport'
import CsvExportImport from '~/components/project/spreadsheet/components/moreActions'
import KanbanView from '@/components/project/spreadsheet/views/kanbanView'
export default {
name: 'XcKanban',
@ -153,11 +153,11 @@ export default {
recordCnt: {},
recordTotalCnt: {},
groupingColumnItems: [],
loadingData : true,
loadingData: true,
selectedExpandRow: null,
selectedExpandOldRow: null,
selectedExpandRowMeta: null,
},
selectedExpandRowMeta: null
}
}),
computed: {

2
packages/nc-gui/components/project/spreadsheet/public/xcTable.vue

@ -199,7 +199,7 @@ import SortListMenu from '../components/sortListMenu'
import ColumnFilterMenu from '../components/columnFilterMenu'
import XcGridView from '../views/xcGridView'
import { SqlUI } from '@/helpers/sqlUi'
import CsvExportImport from '~/components/project/spreadsheet/components/exportImport'
import CsvExportImport from '~/components/project/spreadsheet/components/moreActions'
// import ExpandedForm from "../expandedForm";
export default {

135
packages/nc-gui/components/project/spreadsheet/rowsXcDataTable.vue

@ -1,5 +1,5 @@
<template>
<v-container class="h-100 j-excel-container pa-0 ma-0" fluid>
<v-container class="h-100 j-excel-container backgroundColor pa-0 ma-0" fluid>
<v-toolbar
height="32"
dense
@ -11,7 +11,7 @@
<template #activator="{on}">
<div style="min-width: 56px" v-on="on">
<v-icon
class="pa-1 pr-0 ml-2"
class="ml-2"
small
color="grey"
>
@ -45,7 +45,7 @@
<v-text-field
v-model="searchQueryVal"
autocomplete="new-password"
style="min-width: 100px ; width: 300px"
style="min-width: 100px ; width: 150px"
flat
dense
solo
@ -63,7 +63,54 @@
>{{ refTable }}({{
relationPrimaryValue
}}) -> {{ relationType === 'hm' ? ' Has Many ' : ' Belongs To ' }} -> {{ table }}</span>
<div class="d-inline-flex">
<fields
v-if="!isForm"
v-model="showFields"
:field-list="fieldList"
:meta="meta"
:is-locked="isLocked"
:fields-order.sync="fieldsOrder"
:sql-ui="sqlUi"
:show-system-fields.sync="showSystemFields"
:cover-image-field.sync="coverImageField"
:grouping-field.sync="groupingField"
:is-gallery="isGallery"
:is-kanban="isKanban"
/>
<sort-list
v-if="!isForm"
v-model="sortList"
:is-locked="isLocked"
:field-list="[...realFieldList, ...formulaFieldList]"
/>
<column-filter
v-if="!isForm"
v-model="filters"
:is-locked="isLocked"
:field-list="[...realFieldList, ...formulaFieldList]"
dense
/>
<share-view-menu @share="$refs.drawer && $refs.drawer.genShareLink()" />
<MoreActions
v-if="!isForm"
ref="csvExportImport"
:meta="meta"
:nodes="nodes"
:query-params="{
fieldsOrder,
fieldFilter,
sortList,
showFields
}"
:selected-view="selectedView"
@showAdditionalFeatOverlay="showAdditionalFeatOverlay($event)"
@webhook="showAdditionalFeatOverlay('webhooks')"
/>
</div>
<v-spacer class="h-100" @dblclick="debug=true" />
<template v-if="!isForm">
@ -185,44 +232,6 @@
<!-- <span class="">Delete table</span>-->
<!-- </v-tooltip>-->
</template>
<fields
v-model="showFields"
:field-list="fieldList"
:meta="meta"
:is-locked="isLocked"
:fields-order.sync="fieldsOrder"
:sql-ui="sqlUi"
:show-system-fields.sync="showSystemFields"
:cover-image-field.sync="coverImageField"
:grouping-field.sync="groupingField"
:is-gallery="isGallery"
:is-kanban="isKanban"
/>
<sort-list
v-model="sortList"
:is-locked="isLocked"
:field-list="[...realFieldList, ...formulaFieldList]"
/>
<column-filter
v-model="filters"
:is-locked="isLocked"
:field-list="[...realFieldList, ...formulaFieldList]"
dense
/>
<csv-export-import
ref="csvExportImport"
:meta="meta"
:nodes="nodes"
:query-params="{
fieldsOrder,
fieldFilter,
sortList,
showFields
}"
:selected-view="selectedView"
/>
<!-- Cell height -->
<!-- <v-menu>
@ -329,15 +338,15 @@
/>
</template>
<template v-else-if="isKanban">
<v-container fluid v-if="kanban.loadingData">
<v-container v-if="kanban.loadingData" fluid>
<v-row>
<v-col v-for="idx in 5" :key="idx">
<v-skeleton-loader type="image@3"></v-skeleton-loader>
<v-skeleton-loader type="image@3" />
</v-col>
</v-row>
</v-container>
<kanban-view
v-if="!kanban.loadingData && kanban.data.length"
v-if="!kanban.loadingData && kanban.data.length"
:nodes="nodes"
:table="table"
:show-fields="showFields"
@ -428,7 +437,7 @@
@loadTableData="loadTableData"
@showAdditionalFeatOverlay="showAdditionalFeatOverlay($event)"
>
<v-tooltip bottom>
<!-- <v-tooltip bottom>
<template #activator="{on}">
<v-list-item
v-on="on"
@ -441,7 +450,7 @@
</v-list-item>
</template>
Create Automations or API Webhooks
</v-tooltip>
</v-tooltip>-->
<!-- <v-tooltip bottom>
<template #activator="{on}">
<v-list-item
@ -648,12 +657,14 @@ import ExpandedForm from '@/components/project/spreadsheet/components/expandedFo
import Pagination from '@/components/project/spreadsheet/components/pagination'
import { SqlUI } from '~/helpers/sqlUi'
import ColumnFilter from '~/components/project/spreadsheet/components/columnFilterMenu'
import CsvExportImport from '~/components/project/spreadsheet/components/exportImport'
import MoreActions from '~/components/project/spreadsheet/components/moreActions'
import ShareViewMenu from '~/components/project/spreadsheet/components/shareViewMenu'
export default {
name: 'RowsXcDataTable',
components: {
CsvExportImport,
ShareViewMenu,
MoreActions,
FormView,
DebugMetas,
Pagination,
@ -772,11 +783,11 @@ export default {
recordCnt: {},
recordTotalCnt: {},
groupingColumnItems: [],
loadingData : true,
loadingData: true,
selectedExpandRow: null,
selectedExpandOldRow: null,
selectedExpandRowMeta: null,
},
selectedExpandRowMeta: null
}
}),
watch: {
isActive(n, o) {
@ -1168,7 +1179,7 @@ export default {
},
oldRow: {}
})
if (data[focusRow].row[this.groupingField] === "Uncategorized") {
if (data[focusRow].row[this.groupingField] === 'Uncategorized') {
data[focusRow].row[this.groupingField] = null
}
this.selected = { row: focusRow, col: focusCol }
@ -1324,7 +1335,7 @@ export default {
if (initKanbanProps) {
this.kanban = kanban
}
if (this.api) {
const groupingColumn = this.meta.columns.find(c => c._cn === this.groupingField)
@ -1394,7 +1405,7 @@ export default {
}
},
async loadMoreKanbanData(groupingFieldVal) {
const uncategorized = "uncategorized"
const uncategorized = 'uncategorized'
const {
data
} = await this.api.get(`/nc/${this.$store.state.project.projectId}/api/v1/${this.$route.query.name}`, {
@ -1402,17 +1413,17 @@ export default {
where: groupingFieldVal === uncategorized ? `(${this.groupingField},is,null)` : `(${this.groupingField},eq,${groupingFieldVal})`,
offset: this.kanban.recordCnt[groupingFieldVal]
})
data.map(d => {
data.map((d) => {
// handle composite primary key
d.c_pk = this.meta.columns.filter(c => c.pk).map(c => d[c._cn]).join('___')
if (!d.id) {
// id is required for <kanban-board/>
d.id = d.c_pk
}
// id is required for <kanban-board/>
d.id = d.c_pk
}
this.kanban.data.push({
row: d,
oldRow: d,
rowMeta: {},
rowMeta: {}
})
this.kanban.blocks.push({
status: groupingFieldVal,
@ -1425,12 +1436,12 @@ export default {
if (rowIdx != -1) {
// not a new record -> find the target record
data = this.kanban.data.filter(o => o.row.c_pk == rowIdx)[0]
}
}
this.showExpandModal = true
this.kanban.selectedExpandRow = data.row
this.kanban.selectedExpandOldRow = data.oldRow
this.kanban.selectedExpandRowMeta = data.rowMeta
},
}
},
computed: {
tabsState() {
@ -1473,7 +1484,7 @@ export default {
table: this.meta.tn
})
// return this.meta && this.meta._tn ? ApiFactory.create(this.$store.getters['project/GtrProjectType'], this.meta && this.meta._tn, this.meta && this.meta.columns, this, this.meta) : null
},
}
}
}
</script>

2
packages/nc-gui/components/project/spreadsheet/views/xcGridView.vue

@ -9,7 +9,7 @@
>
<table
v-if="data"
class="xc-row-table nc-grid"
class="xc-row-table nc-grid backgroundColorDefault"
style=" "
>
<thead>

2
packages/nc-gui/components/project/viewTabs/viewSpreadsheet.vue

@ -125,7 +125,7 @@
<div
:class="`cell-height-${cellHeight}`"
style="overflow:auto;transition: width 500ms ;height : calc(100% - 36px)"
class="d-flex"
class="d-flex backgroundColor"
>
<div class="flex-grow-1 h-100" style="overflow-y: auto">
<div ref="table" style=" overflow: auto;width:100%; height: calc(100% - 36px);">

66
packages/nc-gui/components/projectTabs.vue

@ -1,5 +1,5 @@
<template>
<v-container fluid class="project-container ma-0 pa-0" style="position: relative">
<v-container fluid class="project-container ma-0 pa-0 " style="position: relative">
<v-tabs
ref="projectTabs"
v-model="activeTab"
@ -90,7 +90,11 @@
</sqlLogAndOutput>
</div>
<div v-else-if="tab._nodes.type === 'db'" style="height:100%">
<audit-tab :ref="'tabs'+index" :nodes="tab._nodes" />
<audit-tab
:ref="'tabs'+index"
class="backgroundColor"
:nodes="tab._nodes"
/>
<!-- <sqlLogAndOutput>-->
<!-- <DbTab :nodes="tab._nodes" :ref="'tabs'+index"/>-->
<!-- </sqlLogAndOutput>-->
@ -104,14 +108,22 @@
</sqlLogAndOutput>
</div>
<div v-else-if="tab._nodes.type === 'migrationsDir'" style="height:100%">
<audit-tab :ref="'tabs'+index" :nodes="tab._nodes" />
<audit-tab
:ref="'tabs'+index"
class="backgroundColor"
:nodes="tab._nodes"
/>
<!-- <sqlLogAndOutput>-->
<!-- <DbTab :nodes="tab._nodes" :ref="'tabs'+index"/>-->
<!-- </sqlLogAndOutput>-->
</div>
<div v-else-if="tab._nodes.type === 'apisDir'" style="height:100%">
<ApisTab :ref="'tabs'+index" :nodes="tab._nodes" />
<ApisTab
:ref="'tabs'+index"
class="backgroundColor"
:nodes="tab._nodes"
/>
</div>
<div
v-else-if="tab._nodes.type === 'apiClientDir'"
@ -143,7 +155,10 @@
v-else-if="tab._nodes.type === 'graphqlClientDir'"
style="height:100%"
>
<graphql-client style="height: 100%" />
<graphql-client
class="backgroundColor"
style="height: 100%"
/>
</div>
<div
v-else-if="tab._nodes.type === 'swaggerClientDir'"
@ -161,19 +176,31 @@
v-else-if="tab._nodes.type === 'meta'"
style="height:100%"
>
<xc-meta style="height: 100%" />
<xc-meta
class="backgroundColor"
style="height: 100%"
/>
</div>
<div
v-else-if="tab._nodes.type === 'roles'"
style="height:100%"
>
<auth-tab v-if="_isUIAllowed('team-auth')" :nodes="tab._nodes" style="height: 100%" />
<auth-tab
v-if="_isUIAllowed('team-auth')"
class="backgroundColor"
:nodes="tab._nodes"
style="height: 100%"
/>
</div>
<div
v-else-if="tab._nodes.type === 'acl'"
style="height:100%"
>
<global-acl :nodes="tab._nodes" style="height: 100%" />
<global-acl
class="backgroundColor"
:nodes="tab._nodes"
style="height: 100%"
/>
</div>
<div
v-else-if="tab._nodes.type === 'projectSettings'"
@ -181,6 +208,7 @@
>
<project-settings
v-if="_isUIAllowed('settings')"
class="backgroundColor"
:nodes="tab._nodes"
style="height: 100%"
/>
@ -191,6 +219,7 @@
>
<disable-or-enable-models
v-if="_isUIAllowed('project-metadata')"
class="backgroundColor"
:nodes="tab._nodes"
style="height: 100%"
/>
@ -211,7 +240,10 @@
v-else-if="tab._nodes.type === 'appStore'"
style="height:100%"
>
<app-store :nodes="tab._nodes" class="h-100" />
<app-store
:nodes="tab._nodes"
class="backgroundColor h-100"
/>
</div>
<div v-else style="height:100%">
<h1>{{ tab.name }}</h1>
@ -231,20 +263,20 @@
mdi-plus-box
</x-icon>
<v-spacer />
<div
class="powered-by align-self-center grey--text text--lighten-3 d-flex align-center"
<!-- <div
class="powered-by align-self-center grey&#45;&#45;text text&#45;&#45;lighten-3 d-flex align-center"
style="margin-right: 34px;font-size: .65rem ;"
>
<span>Powered by <a
href="https://nocodb.com"
target="_blank"
class=" white--text"
class=" white&#45;&#45;text"
style="text-decoration: none"
>NocoDB</a></span>
<v-icon x-small class="ml-1 powered-by-close" color="grey lighten-1" @click="upgradeToEE">
mdi-close-circle
</v-icon>
</div>
</div>-->
</v-tabs>
<dlg-table-create
@ -509,7 +541,7 @@ export default {
}
/deep/ .project-tabs > .v-tabs-bar {
max-height: 35px;
max-height: 30px;
}
/*/deep/ .project-tabs .v-tabs-slider-wrapper {*/
@ -518,9 +550,9 @@ export default {
/deep/ .project-tabs .v-tab.project-tab {
text-transform: capitalize;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
background: #ffffff22;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
background: #0002;
margin: 0px 1px 0 1px;
color: white !important;
}

4
packages/nc-gui/config/vuetify.options.js

@ -15,6 +15,7 @@ export default function({ app }) {
dark: {
primary: '#0989ff',
// primary: '#0989ff',
'x-active': '#e91e63',
textColor: '#ffffff',
text: '#ffffff',
@ -23,7 +24,8 @@ export default function({ app }) {
backgroundColorDefault: '#1f1f1f'
},
light: {
primary: '#0989ff',
primary: '#1348ba',
// primary: '#0989ff',
'x-active': '#e91e63',
textColor: '#333333',
text: '#333333',

2
packages/nc-gui/helpers/treeViewDataSerializer.js

@ -105,7 +105,7 @@ function dbparser(data, envKey, env) {
// json.children.push(procedureParser(db.procedures, dbKey, env, db.meta.dbAlias, db));
// }
json.children.push(migrationsParser([], dbKey, env, db.meta.dbAlias, db));
// json.children.push(migrationsParser([], dbKey, env, db.meta.dbAlias, db));
json.children.push(sqlClientParser([], dbKey, env, db.meta.dbAlias, db));
dbs.push(json);
}

4
packages/nc-gui/lang/en.json

@ -165,6 +165,10 @@
"title": "Project Metadata",
"tooltip": "Meta Management"
},
"audit": {
"title": "Audit",
"tooltip": "Audit Log"
},
"preview_as": "Preview as",
"reset_review": "Reset Preview"
},

38
packages/nc-gui/layouts/default.vue

@ -8,10 +8,10 @@
clipped-left
dense
dark
height="40"
height="48"
@contextmenu="showAirtabLikeLink++"
>
{{ $store.state.plugins.brand }}
<!-- {{ $store.state.plugins.brand }}-->
<!-- <v-toolbar-side-icon></v-toolbar-side-icon> -->
<v-toolbar-title>
<v-tooltip bottom>
@ -29,25 +29,26 @@
$store.state.project.projectInfo && $store.state.project.projectInfo.version
}})</span>
</v-tooltip>
<template>
<span class="title"> {{ brandName }}</span>
</template>
<!-- <template>-->
<!-- <span class="title"> {{ brandName }}</span>-->
<!-- </template>-->
</v-toolbar-title>
<v-toolbar-items class="ml-3">
<v-toolbar-items class="ml-0">
<gh-btns-star
icon="mark-github"
slug="nocodb/nocodb"
show-count
class="mr-3 align-self-center"
:class="{'dark' : isDark}"
>
{{ ghStarText }}
</gh-btns-star>
<a
class="align-self-center caption font-weight-bold ml-1 mr-2 white--text"
<!-- <a
class="align-self-center caption font-weight-bold ml-1 mr-2 white&#45;&#45;text"
href="https://docs.nocodb.com"
target="_blank"
>Docs</a>
>Docs</a>-->
<!-- <templates-modal v-if="isDashboard && _isUIAllowed('template-import')" v-model="templateModal" class="align-self-center" />-->
<!-- <better-u-x v-if="clickCount" />-->
@ -83,7 +84,7 @@
/>
<v-spacer />
<div style="position: absolute; top:0;left:0;width:100%; pointer-events: none" class="d-flex align-center">
<!-- <div style="position: absolute; top:0;left:0;width:100%; pointer-events: none" class="d-flex align-center">
<h5
v-if="isDashboard && $store.getters['project/GtrProjectName'] !== '__project__'"
class="text-center mx-auto mb-0 mt-1 title font-weight-bold text-capitalize"
@ -101,7 +102,7 @@
Project name
</v-tooltip>
</h5>
</div>
</div>-->
<v-spacer />
@ -113,8 +114,7 @@
<x-btn
v-if="_isUIAllowed('add-user')"
small
color="white"
btn-class="primary--text nc-menu-share"
btn-class="primary--text nc-menu-share white"
@click="rolesTabAdd"
>
<v-icon small class="mr-1">
@ -124,7 +124,7 @@
</x-btn>
</div>
<v-tooltip bottom>
<!-- <v-tooltip bottom>
<template #activator="{ on }">
<v-icon
v-ripple="{class : 'nc-ripple'}"
@ -159,7 +159,7 @@
{{ $vuetify.theme.dark ? 'Click for light theme' : 'Click for dark theme' }}
<i />
</span>
</v-tooltip>
</v-tooltip>-->
<span
v-shortkey="[ 'ctrl','shift', 'd']"
@ -1061,9 +1061,13 @@ export default {
}
</script>
<style scoped>
/deep/ .gh-button-container > a {
/deep/ .gh-button-container{
background: #fff2;
border-radius: 4px;
}
/deep/ .gh-button-container:not(.dark) > a {
background: transparent !important;
color: white !important;
color: #cdcdcd !important;
}
a {

15
packages/nc-gui/pages/nc/_project_id.vue

@ -1,6 +1,6 @@
<template>
<v-container fluid class="pa-0 ma-0" style="overflow: auto">
<splitpanes style="height:calc(100vh - 40px); position: relative;" class="xc-theme">
<splitpanes style="height:calc(100vh - 48px); position: relative;" class="xc-theme nc-dashboard">
<pane :min-size="showProjectTree? 10 : 1.5" :size="showProjectTree ? paneSize : 1.5" :max-size="showProjectTree? 50 : 1.5" style="position: relative;overflow-x: hidden">
<ProjectTreeView v-show="showProjectTree" ref="treeview" />
<v-btn
@ -118,6 +118,19 @@ export default {
background: #7f828b33 !important;
border: #7f828b33 !important;
}
/deep/ .nc-dashboard > .splitpanes__splitter {
margin-top: 30px;
position: relative;
}
/deep/ .nc-dashboard > .splitpanes__splitter::before {
height: 30px;
content: '';
position: absolute;
top:-30px;
left: 0;
width: 100%;
background: var(--v-primary-base);
}
.pane-toggle {
position: absolute;
right: 0;

2
packages/nc-gui/pages/nc/index.vue

@ -1,7 +1,7 @@
<template>
<v-container fluid class="pa-0 ma-0" style="overflow: auto">
<!-- <trialExpired v-if="$store.getters['windows/GtrHasTrialPeriodExpired']"></trialExpired>-->
<splitpanes style="height:calc(100vh - 40px)" class="xc-theme">
<splitpanes style="height:calc(100vh - 48px)" class="xc-theme">
<pane min-size="10" :size="paneSize" max-size="50" style="overflow: auto">
<ProjectTreeView />
</pane>

2
packages/nc-gui/pages/project/xcdb.vue

@ -186,6 +186,6 @@ export default {
}
.main {
height: calc(100vh - 40px)
height: calc(100vh - 48px)
}
</style>

Loading…
Cancel
Save