Browse Source

feat: Enable customization in Gallery view

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/498/head
Pranav C 3 years ago
parent
commit
166142d351
  1. 2
      packages/nc-gui/components/project/spreadsheet/components/cell.vue
  2. 81
      packages/nc-gui/components/project/spreadsheet/components/fieldsMenu.vue
  3. 6
      packages/nc-gui/components/project/spreadsheet/components/spreadsheetNavDrawer.vue
  4. 5
      packages/nc-gui/components/project/spreadsheet/dialog/createViewDialog.vue
  5. 11
      packages/nc-gui/components/project/spreadsheet/mixins/spreadsheet.js
  6. 20
      packages/nc-gui/components/project/spreadsheet/rowsXcDataTable.vue
  7. 85
      packages/nc-gui/components/project/spreadsheet/views/galleryView.vue

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

@ -26,7 +26,7 @@ import SetListCell from '@/components/project/spreadsheet/components/cell/setLis
import EnumCell from '@/components/project/spreadsheet/components/cell/enumCell' import EnumCell from '@/components/project/spreadsheet/components/cell/enumCell'
import EditableAttachmentCell from '@/components/project/spreadsheet/components/editableCell/editableAttachmentCell' import EditableAttachmentCell from '@/components/project/spreadsheet/components/editableCell/editableAttachmentCell'
import DateCell from './cell/dateCell' import DateCell from './cell/dateCell'
import DateTimeCell from './cell/timeCell' import DateTimeCell from './cell/dateTimeCell'
import TimeCell from './cell/timeCell' import TimeCell from './cell/timeCell'
export default { export default {

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

@ -27,7 +27,34 @@
</template> </template>
<v-list dense class="pt-0" min-width="280" @click.stop> <v-list dense class="pt-0" min-width="280" @click.stop>
<v-list-item dense class=""> <template v-if="isGallery">
<div class="pa-2">
<v-select
v-model="coverImageFieldLoc"
label="Cover Image"
class="caption cover-image"
dense
outlined
:items="attachmentFields"
item-text="alias"
item-value="_cn"
hide-details
@click.stop
>
<template #prepend-inner>
<v-icon small class="cover-image-icon">
mdi-image
</v-icon>
</template>
</v-select>
</div>
<v-divider />
</template>
<v-list-item
dense
class=""
>
<v-text-field <v-text-field
v-model="fieldFilter" v-model="fieldFilter"
dense dense
@ -109,6 +136,8 @@ export default {
draggable draggable
}, },
props: { props: {
coverImageField: String,
isGallery: Boolean,
sqlUi: [Object, Function], sqlUi: [Object, Function],
meta: Object, meta: Object,
fieldsOrder: [Array], fieldsOrder: [Array],
@ -126,6 +155,20 @@ export default {
fieldsOrderLoc: [] fieldsOrderLoc: []
}), }),
computed: { computed: {
attachmentFields() {
return [...(this.meta && this.meta.columns ? this.meta.columns.filter(f => f.uidt === 'Attachment') : []), {
alias: 'None',
_cn: ''
}]
},
coverImageFieldLoc: {
get() {
return this.coverImageField
},
set(val) {
this.$emit('update:coverImageField', val)
}
},
columnMeta() { columnMeta() {
return this.meta && this.meta.columns ? this.meta.columns.reduce((o, c) => ({ ...o, [c._cn]: c }), {}) : {} return this.meta && this.meta.columns ? this.meta.columns.reduce((o, c) => ({ ...o, [c._cn]: c }), {}) : {}
}, },
@ -186,17 +229,37 @@ export default {
} }
</script> </script>
<style scoped> <style scoped lang="scss">
/deep/ .v-list-item { ::v-deep {
min-height: 30px; .v-list-item {
} min-height: 30px;
}
/deep/ .v-input--checkbox .v-icon { .v-input--checkbox .v-icon {
font-size: 12px !important; font-size: 12px !important;
}
.cover-image {
.v-input__append-inner {
margin-top: 4px !important;
}
.v-input__slot {
min-height: 25px !important;
}
&.v-input input {
max-height: 20px !important;
}
.cover-image-icon{
margin-top: 2px;
}
}
} }
.drag-icon { .drag-icon {
cursor: all-scroll; cursor: all-scroll; /*cursor: grab;*/
/*cursor: grab;*/
} }
</style> </style>

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

@ -513,7 +513,9 @@ export default {
currentApiUrl: String, currentApiUrl: String,
fieldsOrder: Array, fieldsOrder: Array,
viewStatus: Object, viewStatus: Object,
columnsWidth: Object columnsWidth: Object,
coverImageField: String,
showSystemFields: Boolean
}, },
data: () => ({ data: () => ({
time: Date.now(), time: Date.now(),
@ -562,6 +564,8 @@ export default {
this.$emit('update:fieldsOrder', queryParams.fieldsOrder || []) this.$emit('update:fieldsOrder', queryParams.fieldsOrder || [])
this.$emit('update:viewStatus', queryParams.viewStatus || {}) this.$emit('update:viewStatus', queryParams.viewStatus || {})
this.$emit('update:columnsWidth', queryParams.columnsWidth || {}) this.$emit('update:columnsWidth', queryParams.columnsWidth || {})
this.$emit('update:coverImageField', queryParams.coverImageField)
this.$emit('update:showSystemFields', queryParams.showSystemFields)
if (queryParams.showFields) { if (queryParams.showFields) {
this.$emit('update:showFields', queryParams.showFields) this.$emit('update:showFields', queryParams.showFields)
} else { } else {

5
packages/nc-gui/components/project/spreadsheet/dialog/createViewDialog.vue

@ -75,10 +75,10 @@ export default {
methods: { methods: {
async createView() { async createView() {
let showFields = null let showFields = null
let attachmentCol
if (this.show_as === 'gallery') { if (this.show_as === 'gallery') {
showFields = { [this.primaryValueColumn]: true } showFields = { [this.primaryValueColumn]: true }
const attachmentCol = this.meta.columns.find(c => c.uidt === 'Attachment') attachmentCol = this.meta.columns.find(c => c.uidt === 'Attachment')
if (attachmentCol) { if (attachmentCol) {
showFields[attachmentCol.cn] = true showFields[attachmentCol.cn] = true
} }
@ -97,6 +97,7 @@ export default {
title: this.view_name, title: this.view_name,
query_params: { query_params: {
showFields, showFields,
coverImageField: attachmentCol ? attachmentCol._cn : '',
...this.queryParams ...this.queryParams
}, },
parent_model_title: this.table, parent_model_title: this.table,

11
packages/nc-gui/components/project/spreadsheet/mixins/spreadsheet.js

@ -86,6 +86,7 @@ export default {
availableColumns() { availableColumns() {
let columns = [] let columns = []
if (!this.meta) { return [] }
// todo: generate hideCols based on default values // todo: generate hideCols based on default values
const hideCols = ['created_at', 'updated_at'] const hideCols = ['created_at', 'updated_at']
@ -277,6 +278,11 @@ export default {
}, },
deep: true deep: true
}, },
coverImageField(v) {
if (!this.loadingMeta || !this.loadingData) {
this.syncDataDebounce(this)
}
},
fieldsOrder: { fieldsOrder: {
handler(v) { handler(v) {
if (!this.loadingMeta || !this.loadingData) { if (!this.loadingMeta || !this.loadingData) {
@ -285,6 +291,11 @@ export default {
}, },
deep: true deep: true
}, },
showSystemFields(v) {
if (!this.loadingMeta || !this.loadingData) {
this.syncDataDebounce(this)
}
},
filters: { filters: {
async handler(filter) { async handler(filter) {
let defaultQuery = '' let defaultQuery = ''

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

@ -104,6 +104,8 @@
:fields-order.sync="fieldsOrder" :fields-order.sync="fieldsOrder"
:sql-ui="sqlUi" :sql-ui="sqlUi"
:show-system-fields.sync="showSystemFields" :show-system-fields.sync="showSystemFields"
:cover-image-field.sync="coverImageField"
:is-gallery="isGallery"
/> />
<sort-list <sort-list
@ -217,7 +219,7 @@
@loadMeta="loadMeta" @loadMeta="loadMeta"
/> />
</template> </template>
<template v-else-if="selectedView && selectedView.show_as === 'gallery' "> <template v-else-if="isGallery ">
<gallery-view <gallery-view
:nodes="nodes" :nodes="nodes"
:table="table" :table="table"
@ -225,7 +227,9 @@
:available-columns="availableColumns" :available-columns="availableColumns"
:meta="meta" :meta="meta"
:data="data" :data="data"
:sql-ui="sqlUi"
:primary-value-column="primaryValueColumn" :primary-value-column="primaryValueColumn"
:cover-image-field="coverImageField"
@expandForm="({rowIndex,rowMeta}) => expandRow(rowIndex,rowMeta)" @expandForm="({rowIndex,rowMeta}) => expandRow(rowIndex,rowMeta)"
/> />
</template> </template>
@ -237,6 +241,7 @@
:available-columns="availableColumns" :available-columns="availableColumns"
:meta="meta" :meta="meta"
:data="data" :data="data"
:sql-ui="sqlUi"
:primary-value-column="primaryValueColumn" :primary-value-column="primaryValueColumn"
@expandForm="({rowIndex,rowMeta}) => expandRow(rowIndex,rowMeta)" @expandForm="({rowIndex,rowMeta}) => expandRow(rowIndex,rowMeta)"
/> />
@ -272,6 +277,7 @@
:table="table" :table="table"
:meta="meta" :meta="meta"
:selected-view-id.sync="selectedViewId" :selected-view-id.sync="selectedViewId"
:cover-image-field.sync="coverImageField"
:selected-view.sync="selectedView" :selected-view.sync="selectedView"
:primary-value-column="primaryValueColumn" :primary-value-column="primaryValueColumn"
:concatenated-x-where="concatenatedXWhere" :concatenated-x-where="concatenatedXWhere"
@ -285,6 +291,7 @@
:fields-order.sync="fieldsOrder" :fields-order.sync="fieldsOrder"
:view-status.sync="viewStatus" :view-status.sync="viewStatus"
:columns-width.sync="columnsWidth" :columns-width.sync="columnsWidth"
:show-system-fields.sync="showSystemFields"
@mapFieldsAndShowFields="mapFieldsAndShowFields" @mapFieldsAndShowFields="mapFieldsAndShowFields"
@loadTableData="loadTableData" @loadTableData="loadTableData"
@showAdditionalFeatOverlay="showAdditionalFeatOverlay($event)" @showAdditionalFeatOverlay="showAdditionalFeatOverlay($event)"
@ -519,6 +526,7 @@ export default {
type: null type: null
}, },
fieldsOrder: [], fieldsOrder: [],
coverImageField: null,
showSystemFields: false, showSystemFields: false,
showAdvanceOptions: false, showAdvanceOptions: false,
loadViews: false, loadViews: false,
@ -659,7 +667,12 @@ export default {
showFields: this.showFields, showFields: this.showFields,
fieldsOrder: this.fieldsOrder, fieldsOrder: this.fieldsOrder,
viewStatus: this.viewStatus, viewStatus: this.viewStatus,
columnsWidth: this.columnsWidth columnsWidth: this.columnsWidth,
showSystemFields: this.showSystemFields
}
if (this.isGallery) {
queryParams.coverImageField = this.coverImageField
} }
this.$set(this.selectedView, 'query_params', JSON.stringify(queryParams)) this.$set(this.selectedView, 'query_params', JSON.stringify(queryParams))
@ -978,6 +991,9 @@ export default {
} }
}, },
computed: { computed: {
isGallery() {
return this.selectedView && this.selectedView.show_as === 'gallery'
},
meta() { meta() {
return this.$store.state.meta.metas[this.table] return this.$store.state.meta.metas[this.table]
}, },

85
packages/nc-gui/components/project/spreadsheet/views/galleryView.vue

@ -1,6 +1,6 @@
<template> <template>
<v-container fluid> <v-container fluid>
<v-row> <v-row class="align-stretch">
<v-col <v-col
v-for="({row, rowMeta},rowIndex) in data" v-for="({row, rowMeta},rowIndex) in data"
:key="rowIndex" :key="rowIndex"
@ -8,10 +8,12 @@
> >
<v-hover v-slot="{hover}"> <v-hover v-slot="{hover}">
<v-card <v-card
class="h-100"
:elevation="hover ? 4 : 1" :elevation="hover ? 4 : 1"
@click="$emit('expandForm', {row,rowIndex,rowMeta})" @click="$emit('expandForm', {row,rowIndex,rowMeta})"
> >
<v-carousel <v-carousel
v-if="attachmentColumn"
:continuous="false" :continuous="false"
:cycle="true" :cycle="true"
:show-arrows="false" :show-arrows="false"
@ -31,10 +33,56 @@
</v-carousel-item> </v-carousel-item>
</v-carousel> </v-carousel>
<v-card-title <!-- <v-card-title-->
class="text-capitalize" <!-- class="text-capitalize"-->
v-text="row[primaryValueColumn]" <!-- v-text="row[primaryValueColumn]"-->
/> <!-- />-->
<v-card-text>
<v-container>
<v-row class="">
<v-col
v-for="(col) in fields"
v-show="showFields[col.alias|| col._cn]"
:key="col.alias || col._cn"
class="col-12 mt-1 mb-2 "
>
<label :for="`data-table-form-${col._cn}`" class="body-2 text-capitalize caption grey--text">
<virtual-header-cell
v-if="col.virtual"
:column="col"
:nodes="nodes"
:is-form="true"
:meta="meta"
/>
<header-cell
v-else
:is-form="true"
:value="col._cn"
:column="col"
/>
</label>
<virtual-cell
v-if="col.virtual"
ref="virtual"
:column="col"
:row="row"
:nodes="nodes"
:meta="meta"
/>
<table-cell
v-else
:value="row[col._cn]"
:column="col"
:sql-ui="sqlUi"
class="xc-input body-2"
:meta="meta"
/>
</v-col>
</v-row>
</v-container>
</v-card-text>
</v-card> </v-card>
</v-hover> </v-hover>
</v-col> </v-col>
@ -43,8 +91,13 @@
</template> </template>
<script> <script>
import VirtualHeaderCell from '../components/virtualHeaderCell'
import HeaderCell from '../components/headerCell'
import VirtualCell from '../components/virtualCell'
import TableCell from '../components/cell'
export default { export default {
name: 'GalleryView', name: 'GalleryView',
components: { TableCell, VirtualCell, HeaderCell, VirtualHeaderCell },
props: [ props: [
'nodes', 'nodes',
'table', 'table',
@ -52,11 +105,29 @@ export default {
'availableColumns', 'availableColumns',
'meta', 'meta',
'data', 'data',
'primaryValueColumn' 'primaryValueColumn',
'showSystemFields',
'sqlUi',
'coverImageField'
], ],
computed: { computed: {
attachmentColumn() { attachmentColumn() {
return this.meta && this.meta.columns && this.meta.columns.find(c => c.uidt === 'Attachment') return this.coverImageField && this.meta && this.meta.columns && this.meta.columns.find(c => c._cn === this.coverImageField)
},
fields() {
if (this.availableColumns) {
return this.availableColumns
}
const hideCols = ['created_at', 'updated_at']
if (this.showSystemFields) {
return this.meta.columns || []
} else {
return this.meta.columns.filter(c => !(c.pk && c.ai) && !hideCols.includes(c.cn) &&
!((this.meta.v || []).some(v => v.bt && v.bt.cn === c.cn))
) || []
}
} }
}, },
methods: { methods: {

Loading…
Cancel
Save