Browse Source

feat(gui-v2): show view list and show data based on selected view

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/2716/head
Pranav C 2 years ago
parent
commit
0c772a3932
  1. 4
      packages/nc-gui-v2/components/cell/Checkbox.vue
  2. 4
      packages/nc-gui-v2/components/cell/Rating.vue
  3. 1
      packages/nc-gui-v2/components/index.ts
  4. 18
      packages/nc-gui-v2/components/smartsheet/Grid.vue
  5. 65
      packages/nc-gui-v2/components/smartsheet/Sidebar.vue
  6. 12
      packages/nc-gui-v2/components/tabs/Smartsheet.vue
  7. 22
      packages/nc-gui-v2/composables/useViewData.ts
  8. 7
      packages/nc-gui-v2/composables/useViews.ts

4
packages/nc-gui-v2/components/cell/Checkbox.vue

@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, inject } from '#imports' import { computed, inject } from '#imports'
import { ColumnInj, IsFormInj } from "~/components"; import { ColumnInj, IsFormInj } from '~/components'
interface Props { interface Props {
modelValue: boolean modelValue?: boolean | undefined | number
} }
const { modelValue: value } = defineProps<Props>() const { modelValue: value } = defineProps<Props>()

4
packages/nc-gui-v2/components/cell/Rating.vue

@ -1,11 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, inject } from '#imports' import { computed, inject } from '#imports'
import { ColumnInj, IsFormInj } from "~/components"; import { ColumnInj, IsFormInj } from '~/components'
import MdiStarIcon from '~icons/mdi/star' import MdiStarIcon from '~icons/mdi/star'
import MdiStarOutlineIcon from '~icons/mdi/star-outline' import MdiStarOutlineIcon from '~icons/mdi/star-outline'
interface Props { interface Props {
modelValue: string | number modelValue?: string | number
readOnly?: boolean readOnly?: boolean
} }

1
packages/nc-gui-v2/components/index.ts

@ -11,3 +11,4 @@ export const ChangePageInj: InjectionKey<ReturnType<typeof useViewData>['changeP
export const IsFormInj: InjectionKey<boolean> = Symbol('is-form-injection') export const IsFormInj: InjectionKey<boolean> = Symbol('is-form-injection')
export const IsGridInj: InjectionKey<boolean> = Symbol('is-grid-injection') export const IsGridInj: InjectionKey<boolean> = Symbol('is-grid-injection')
export const ValueInj: InjectionKey<any> = Symbol('value-injection') export const ValueInj: InjectionKey<any> = Symbol('value-injection')
export const ActiveViewInj: InjectionKey<any> = Symbol('active-view-injection')

18
packages/nc-gui-v2/components/smartsheet/Grid.vue

@ -1,10 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import { isVirtualCol } from 'nocodb-sdk' import { isVirtualCol } from 'nocodb-sdk'
import { inject, onKeyStroke, onMounted, provide } from '#imports' import { inject, onKeyStroke, onMounted, provide } from '#imports'
import { ChangePageInj, IsFormInj, IsGridInj, MetaInj, PaginationDataInj } from '~/components' import { ActiveViewInj, ChangePageInj, IsFormInj, IsGridInj, MetaInj, PaginationDataInj } from '~/components'
import useViewData from '~/composables/useViewData' import useViewData from '~/composables/useViewData'
const meta = inject(MetaInj) const meta = inject(MetaInj)
const view = inject(ActiveViewInj)
// todo: get from parent ( inject or use prop ) // todo: get from parent ( inject or use prop )
const isPublicView = false const isPublicView = false
@ -12,15 +13,13 @@ const isPublicView = false
const selected = reactive<{ row?: number | null; col?: number | null }>({}) const selected = reactive<{ row?: number | null; col?: number | null }>({})
const editEnabled = ref(false) const editEnabled = ref(false)
const { loadData, paginationData, formattedData: data, updateRowProperty, changePage } = useViewData(meta) const { loadData, paginationData, formattedData: data, updateRowProperty, changePage } = useViewData(meta, view)
provide(IsFormInj, false) provide(IsFormInj, false)
provide(IsGridInj, true) provide(IsGridInj, true)
provide(PaginationDataInj, paginationData) provide(PaginationDataInj, paginationData)
provide(ChangePageInj, changePage) provide(ChangePageInj, changePage)
onMounted(() => loadData({}))
const selectCell = (row: number, col: number) => { const selectCell = (row: number, col: number) => {
selected.row = row selected.row = row
selected.col = col selected.col = col
@ -31,6 +30,16 @@ onKeyStroke(['Enter'], (e) => {
editEnabled.value = true editEnabled.value = true
} }
}) })
watch(
[meta, view],
async () => {
if (meta?.value && view?.value) {
await loadData()
}
},
{ immediate: true },
)
</script> </script>
<template> <template>
@ -164,6 +173,7 @@ onKeyStroke(['Enter'], (e) => {
// todo : proper height calculation // todo : proper height calculation
height: calc(100vh - 250px); height: calc(100vh - 250px);
overflow: auto; overflow: auto;
td, td,
tr { tr {
min-height: 31px !important; min-height: 31px !important;

65
packages/nc-gui-v2/components/smartsheet/Sidebar.vue

@ -2,17 +2,20 @@
import type { TableType } from 'nocodb-sdk' import type { TableType } from 'nocodb-sdk'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import { inject, onMounted, ref } from '#imports' import { inject, onMounted, ref } from '#imports'
import { MetaInj } from '~/components' import { ActiveViewInj, MetaInj } from '~/components'
import useViews from '~/composables/useViews' import useViews from '~/composables/useViews'
import { viewIcons } from '~/utils/viewUtils' import { viewIcons } from '~/utils/viewUtils'
const meta = inject(MetaInj) const meta = inject(MetaInj)
const activeView = inject(ActiveViewInj)
const { views, loadViews } = useViews(meta as Ref<TableType>) const { views, loadViews } = useViews(meta as Ref<TableType>)
const _isUIAllowed = (view: string) => {} const _isUIAllowed = (view: string) => {}
onMounted(loadViews) loadViews().then(() => {
activeView.value = views.value?.[0]
})
const selectedViewIdLocal = ref('')
const toggleDrawer = ref(false) const toggleDrawer = ref(false)
</script> </script>
@ -31,8 +34,9 @@ const toggleDrawer = ref(false)
<!-- Views --> <!-- Views -->
<span class="body-2 font-weight-medium">{{ $t('objects.views') }}</span> <span class="body-2 font-weight-medium">{{ $t('objects.views') }}</span>
</v-list-item> </v-list-item>
<v-list-group v-model="selectedViewIdLocal" mandatory color="primary">
<!-- <!-- <v-list-group v-model="selectedViewIdLocal" mandatory color="primary"> -->
<!--
todo: add sortable todo: add sortable
<draggable <draggable
:is="_isUIAllowed('viewlist-drag-n-drop') ? 'draggable' : 'div'" :is="_isUIAllowed('viewlist-drag-n-drop') ? 'draggable' : 'div'"
@ -41,45 +45,48 @@ const toggleDrawer = ref(false)
v-bind="dragOptions" v-bind="dragOptions"
@change="onMove($event)" @change="onMove($event)"
> --> > -->
<!-- <transition-group <!-- <transition-group
type="transition" type="transition"
:name="!drag ? 'flip-list' : null" :name="!drag ? 'flip-list' : null"
> --> > -->
<v-list-item <v-list-item
v-for="(view, i) in views" v-for="view in views"
:key="view.id" :key="view.id"
v-t="['a:view:open', { view: view.type }]" v-t="['a:view:open', { view: view.type }]"
dense dense
:value="view.id" :value="view.id"
active-class="x-active--text" active-class="x-active--text"
> @click="activeView = view"
<!-- :class="`body-2 view nc-view-item nc-draggable-child nc-${ >
<!-- :class="`body-2 view nc-view-item nc-draggable-child nc-${
viewTypeAlias[view.type] viewTypeAlias[view.type]
}-view-item`" }-view-item`"
@click="$emit('rerender')" --> @click="$emit('rerender')" -->
<v-icon <!-- <v-icon
v-if="_isUIAllowed('viewlist-drag-n-drop')" v-if="_isUIAllowed('viewlist-drag-n-drop')"
small small
:class="`nc-child-draggable-icon nc-child-draggable-icon-${view.title}`" :class="`nc-child-draggable-icon nc-child-draggable-icon-${view.title}`"
@click.stop @click.stop
> >
mdi-drag-vertical mdi-drag-vertical
</v-icon> </v-icon> -->
<v-list-item-icon class="mr-n1"> <!-- <v-list-item-icon class="mr-n1">
<v-icon v-if="viewIcons[view.type]" x-small :color="viewIcons[view.type].color"> <v-icon v-if="viewIcons[view.type]" x-small :color="viewIcons[view.type].color">
{{ viewIcons[view.type].icon }} {{ viewIcons[view.type].icon }}
</v-icon> </v-icon>
<v-icon v-else color="primary" small> mdi-table </v-icon> <v-icon v-else color="primary" small> mdi-table </v-icon>
</v-list-item-icon> </v-list-item-icon> -->
<v-list-item-title> <span>{{ view.alias || view.title }}</span>
<!-- <v-list-item-title>
<v-tooltip bottom> <v-tooltip bottom>
<template #activator="{ on }"> <template #activator="{ on }">
<div class="font-weight-regular" style="overflow: hidden; text-overflow: ellipsis"> <div class="font-weight-regular" style="overflow: hidden; text-overflow: ellipsis">
<input v-if="view.edit" :ref="`input${i}`" v-model="view.title_temp" /> <input v-if="view.edit" :ref="`input${i}`" v-model="view.title_temp" />
<!-- @click.stop &lt;!&ndash; @click.stop
@keydown.enter.stop="updateViewName(view, i)" @keydown.enter.stop="updateViewName(view, i)"
@blur="updateViewName(view, i)" --> @blur="updateViewName(view, i)" &ndash;&gt;
<template v-else> <template v-else>
<span v-on="on">{{ view.alias || view.title }}</span> <span v-on="on">{{ view.alias || view.title }}</span>
</template> </template>
@ -87,9 +94,9 @@ const toggleDrawer = ref(false)
</template> </template>
{{ view.alias || view.title }} {{ view.alias || view.title }}
</v-tooltip> </v-tooltip>
</v-list-item-title> </v-list-item-title> -->
<v-spacer /> <v-spacer />
<!-- <template v-if="_isUIAllowed('virtualViewsCreateOrEdit')"> <!-- <template v-if="_isUIAllowed('virtualViewsCreateOrEdit')">
&lt;!&ndash; Copy view &ndash;&gt; &lt;!&ndash; Copy view &ndash;&gt;
<x-icon <x-icon
v-if="!view.edit" v-if="!view.edit"
@ -131,10 +138,10 @@ const toggleDrawer = ref(false)
> >
mdi-check-bold mdi-check-bold
</v-icon> --> </v-icon> -->
</v-list-item> </v-list-item>
<!-- </transition-group> --> <!-- </transition-group> -->
<!-- </draggable> --> <!-- </draggable> -->
</v-list-group> <!-- </v-list-group> -->
</v-list> </v-list>
</div> </div>
</div> </div>

12
packages/nc-gui-v2/components/tabs/Smartsheet.vue

@ -1,6 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import type { FormType, GalleryType, GridType, KanbanType } from 'nocodb-sdk'
import { ViewTypes } from 'nocodb-sdk'
import { computed, onMounted, provide, watch } from '#imports' import { computed, onMounted, provide, watch } from '#imports'
import { MetaInj, TabMetaInj } from '~/components' import { ActiveViewInj, MetaInj, TabMetaInj } from '~/components'
import useMetas from '~/composables/useMetas' import useMetas from '~/composables/useMetas'
const { tabMeta } = defineProps({ const { tabMeta } = defineProps({
@ -9,6 +11,7 @@ const { tabMeta } = defineProps({
const { getMeta, metas } = useMetas() const { getMeta, metas } = useMetas()
const activeView = ref<GridType | FormType | KanbanType | GalleryType>()
const meta = computed(() => metas.value?.[tabMeta?.id]) const meta = computed(() => metas.value?.[tabMeta?.id])
onMounted(async () => { onMounted(async () => {
@ -17,6 +20,7 @@ onMounted(async () => {
provide(MetaInj, meta) provide(MetaInj, meta)
provide(TabMetaInj, tabMeta) provide(TabMetaInj, tabMeta)
provide(ActiveViewInj, activeView)
watch( watch(
() => tabMeta && tabMeta?.id, () => tabMeta && tabMeta?.id,
@ -29,10 +33,10 @@ watch(
<template> <template>
<div class="overflow-auto"> <div class="overflow-auto">
<SmartsheetToolbar /> <SmartsheetToolbar />
<template v-if="meta && tabMeta"> <template v-if="meta">
<div class="d-flex"> <div class="d-flex">
<div class="flex-grow-1 min-w-0"> <div v-if="activeView" class="flex-grow-1 min-w-0">
<SmartsheetGrid /> <SmartsheetGrid v-if="activeView.type === ViewTypes.GRID" />
</div> </div>
<SmartsheetSidebar /> <SmartsheetSidebar />
</div> </div>

22
packages/nc-gui-v2/composables/useViewData.ts

@ -10,7 +10,10 @@ const formatData = (list: Array<Record<string, any>>) =>
rowMeta: {}, rowMeta: {},
})) }))
export default (meta: Ref<TableType> | ComputedRef<TableType> | undefined) => { export default (
meta: Ref<TableType> | ComputedRef<TableType> | undefined,
viewMeta: Ref<TableType> | ComputedRef<TableType> | undefined,
) => {
const data = ref<Array<Record<string, any>>>() const data = ref<Array<Record<string, any>>>()
const formattedData = ref<Array<{ row: Record<string, any>; oldRow: Record<string, any>; rowMeta?: any }>>() const formattedData = ref<Array<{ row: Record<string, any>; oldRow: Record<string, any>; rowMeta?: any }>>()
const paginationData = ref<PaginatedType>({ page: 1, pageSize: 25 }) const paginationData = ref<PaginatedType>({ page: 1, pageSize: 25 })
@ -18,9 +21,9 @@ export default (meta: Ref<TableType> | ComputedRef<TableType> | undefined) => {
const { project } = useProject() const { project } = useProject()
const { $api } = useNuxtApp() const { $api } = useNuxtApp()
const loadData = async (params: Parameters<Api<any>['dbTableRow']['list']>[3] = {}) => { const loadData = async (params: Parameters<Api<any>['dbViewRow']['list']>[4] = {}) => {
if (!project?.value?.id || !meta?.value?.id) return if (!project?.value?.id || !meta?.value?.id || !viewMeta?.value?.id) return
const response = await $api.dbTableRow.list('noco', project.value.id, meta.value.id, params) const response = await $api.dbViewRow.list('noco', project.value.id, meta.value.id, viewMeta.value.id, params)
data.value = response.list data.value = response.list
formattedData.value = formatData(response.list) formattedData.value = formatData(response.list)
paginationData.value = response.pageInfo paginationData.value = response.pageInfo
@ -32,10 +35,11 @@ export default (meta: Ref<TableType> | ComputedRef<TableType> | undefined) => {
.map((c) => row[c.title as string]) .map((c) => row[c.title as string])
.join('___') as string .join('___') as string
return $api.dbTableRow.update( return $api.dbViewRow.update(
'noco', 'noco',
project?.value.id as string, project?.value.id as string,
meta?.value.id as string, meta?.value.id as string,
viewMeta?.value?.id as string,
id, id,
{ {
[property]: row[property], [property]: row[property],
@ -72,7 +76,13 @@ export default (meta: Ref<TableType> | ComputedRef<TableType> | undefined) => {
return o return o
}, {}) }, {})
const insertedData = await $api.dbTableRow.create('noco', project?.value.id as string, meta?.value.id as string, insertObj) const insertedData = await $api.dbViewRow.create(
'noco',
project?.value.id as string,
meta?.value.id as string,
viewMeta?.value?.id as string,
insertObj,
)
formattedData.value?.splice(rowIndex ?? 0, 1, { formattedData.value?.splice(rowIndex ?? 0, 1, {
row: insertedData, row: insertedData,

7
packages/nc-gui-v2/composables/useViews.ts

@ -1,13 +1,14 @@
import type { TableType } from 'nocodb-sdk' import type { FormType, GalleryType, GridType, KanbanType, TableType } from 'nocodb-sdk'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import { useNuxtApp } from '#app' import { useNuxtApp } from '#app'
export default function (meta: Ref<TableType>) { export default function (meta: Ref<TableType>) {
const views = ref() const views = ref<Array<GridType | FormType | KanbanType | GalleryType>>()
const { $api } = useNuxtApp() const { $api } = useNuxtApp()
const loadViews = async () => { const loadViews = async () => {
if (meta.value?.id) views.value = (await $api.dbView.list(meta.value?.id)).list if (meta.value?.id)
views.value = (await $api.dbView.list(meta.value?.id)).list as Array<GridType | FormType | KanbanType | GalleryType>
} }
return { views, loadViews } return { views, loadViews }

Loading…
Cancel
Save