Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/store/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ export const useDataStore = defineStore('data', {
allColumns = allColumns.concat(MetaColumns.filter(col => columnSettingsMap[col.id]))
if (view.columnSettings) {
allColumns = allColumns.sort((a, b) => {
const orderA = columnSettingsMap[a.id]?.order ?? Number.MAX_SAFE_INTEGER
const orderB = columnSettingsMap[b.id]?.order ?? Number.MAX_SAFE_INTEGER
const orderA = a.viewColumnInformation?.order ?? columnSettingsMap[a.id]?.order ?? Number.MAX_SAFE_INTEGER
const orderB = b.viewColumnInformation?.order ?? columnSettingsMap[b.id]?.order ?? Number.MAX_SAFE_INTEGER
return orderA - orderB
})
}
Expand Down
116 changes: 76 additions & 40 deletions src/views/ContentReferenceWidget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@
<div v-if="rows && rows.length > 0" class="nc-table">
<NcTable
:rows="filteredRows"
:columns="richObject.columns"
:columns="columns"
:element-id="richObject.id"
:is-view="Boolean(richObject.type)"
:is-view="isView"
v-model:view-setting="localViewSetting"
v-bind="tablePermissions"
@edit-row="editRow"
@copy-row="copyRow"
@delete-row="deleteRow" />
</div>
<CreateRow
:columns="richObject.columns"
:is-view="Boolean(richObject.type)"
:columns="columns"
:is-view="isView"
:element-id="richObject.id"
:show-modal="showCopyRow"
:prefill-data="copyPrefillData"
Expand All @@ -38,11 +39,11 @@
v-if="rowToDelete !== null"
:rows-to-delete="[rowToDelete]"
:element-id="richObject.id"
:is-view="Boolean(richObject.type)"
:is-view="isView"
@cancel="rowToDelete = null" />
</div>
</template>

<script>
import NcTable from '../shared/components/ncTable/NcTable.vue'
import Options from '../shared/components/ncTable/sections/Options.vue'
Expand All @@ -54,19 +55,19 @@ import { useResizeObserver } from '@vueuse/core'
import { spawnDialog } from '@nextcloud/vue/functions/dialog'
import { useTablesStore } from '../store/store.js'
import { useDataStore } from '../store/data.js'

export default {

components: {
NcTable,
Options,
CreateRow,
DeleteRows,
NcLoadingIcon,
},

mixins: [permissionsMixin],

props: {
richObjectType: {
type: String,
Expand All @@ -81,20 +82,24 @@ export default {
default: true,
},
},

data() {
return {
searchExp: null,
localRows: [], // Keep as fallback only
localViewSetting: {},
showCopyRow: false,
copyPrefillData: null,
rowToDelete: null,
tablesStore: null,
dataStore: null,
}
},

computed: {
isView() {
return Boolean(this.richObject?.type)
},
tablePermissions() {
return {
canCreateRows: this.canCreateRowInElement(this.richObject),
Expand Down Expand Up @@ -124,7 +129,7 @@ export default {
}
},
getRows() {
return this.dataStore ? this.dataStore.getRows(false, this.richObject.id) : []
return this.dataStore ? this.dataStore.getRows(this.isView, this.richObject.id) : []
},
// Use computed property to get rows from store or richObject
rows() {
Expand All @@ -136,8 +141,19 @@ export default {
// Fallback to richObject rows or local rows
return this.richObject?.rows || this.localRows
},
getColumns() {
return this.dataStore ? this.dataStore.getColumns(this.isView, this.richObject.id) : []
},
// Prefer fresh store data over the (possibly stale) richObject snapshot
columns() {
const storeColumns = this.getColumns
if (storeColumns && storeColumns.length > 0) {
return storeColumns
}
return this.richObject?.columns || []
},
},

watch: {
richObject: {
deep: true,
Expand All @@ -161,22 +177,28 @@ export default {
},
},
},

async mounted() {
useResizeObserver(this.$el, (entries) => {
const entry = entries[0]
const { width } = entry.contentRect
// In Vue 3 $el can be a fragment/comment node (no style), so guard it.
this.$el?.style?.setProperty?.('--widget-content-width', `${width}px`)
})

this.tablesStore = useTablesStore()
this.dataStore = useDataStore()

await this.loadRows()
await Promise.all([this.loadRows(), this.loadColumns()])
},

methods: {
// { tableId } or { viewId } payload for loadRowsFromBE
elementIdPayload() {
return this.isView
? { viewId: this.richObject.id }
: { tableId: this.richObject.id }
},
search(searchString) {
this.searchExp = (searchString !== '')
? new RegExp(searchString.trim(), 'ig')
Expand All @@ -186,28 +208,24 @@ export default {
const { default: CreateRow } = await import('../modules/modals/CreateRow.vue')
spawnDialog(CreateRow, {
showModal: true,
columns: this.richObject.columns,
isView: Boolean(this.richObject.type),
columns: this.columns,
isView: this.isView,
elementId: this.richObject.id,
}, async () => {
// Reload rows from the backend to get the latest data
await this.dataStore.loadRowsFromBE({
tableId: this.richObject.id,
})
await this.dataStore.loadRowsFromBE(this.elementIdPayload())
})
},
async editRow(rowId) {
const { default: EditRow } = await import('../modules/modals/EditRow.vue')
spawnDialog(EditRow, {
showModal: true,
columns: this.richObject.columns,
columns: this.columns,
row: this.getRow(rowId),
isView: Boolean(this.richObject.type),
isView: this.isView,
element: this.richObject,
}, async () => {
await this.dataStore.loadRowsFromBE({
tableId: this.richObject.id,
})
await this.dataStore.loadRowsFromBE(this.elementIdPayload())
})
},
copyRow(rowId) {
Expand All @@ -222,41 +240,56 @@ export default {
},
async loadRows() {
if (!this.dataStore) return


// Paint from cached snapshot immediately, but it can be stale --
// always reconcile with the backend below.
if (this.richObject.rows) {
this.localRows = this.richObject.rows
this.dataStore.seedRows({
isView: Boolean(this.richObject.type),
isView: this.isView,
elementId: this.richObject.id,
rows: this.richObject.rows,
})
return
}

try {
await this.dataStore.loadRowsFromBE({
tableId: this.richObject.id,
})
await this.dataStore.loadRowsFromBE(this.elementIdPayload())
// No need to set local rows as the computed property will use store data
} catch (error) {
console.error('Error loading rows:', error)
}
},
async loadColumns() {
if (!this.dataStore) return
try {
if (this.isView) {
await this.dataStore.loadColumnsFromBE({ view: this.richObject })
} else {
await this.dataStore.loadColumnsFromBE({ tableId: this.richObject.id })
}
} catch (error) {
console.error('Error loading columns:', error)
}
},
},
}
</script>
<style lang="scss" scoped>

.tables-content-widget {
min-height: max(50vh, 200px);
height: 50vh;
height: auto;
max-height: calc(100dvh - 40px);
overflow: scroll;
overscroll-behavior: contain;
isolation: isolate;

& .header {
position: sticky;
top: 0;
inset-inline-start: 0;
z-index: 1;
z-index: 7;
background-color: var(--color-main-background);

:where(.options) {
position: sticky;
Expand Down Expand Up @@ -285,8 +318,11 @@ export default {
.nc-table {
min-width: var(--widget-content-width);

:where(.options.row) {
display: none;
:deep(.options.row) {
height: 0 !important;
overflow: hidden !important;
margin: 0 !important;
padding: 0 !important;
}

:where(thead) {
Expand Down
Loading