Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[atable] Missing state API(s) for cell updates #207

Closed
Alchez opened this issue Dec 5, 2024 · 0 comments · Fixed by #213
Closed

[atable] Missing state API(s) for cell updates #207

Alchez opened this issue Dec 5, 2024 · 0 comments · Fixed by #213
Assignees
Labels
enhancement New feature or request

Comments

@Alchez
Copy link
Collaborator

Alchez commented Dec 5, 2024

Note

For state management, every ATable component uses an instance of a data store class (TableDataStore) that has the following features:

  • Each table instance (in case of multiple table renders) auto-generates an ID for itself to allow identifying individual tables.
    • If a table uses modal components, then the instance ID is also automatically shared to the modal component(s).
  • Each table instance is individually provided to the current Vue instance on setup.
  • Each table instance also exposes a setCellData API to update the table's data.

Problem:
When a table cell can be edited via both the cell and modal inputs, syncing the cell -> modal action isn't currently straightforward via the API, which breaks two-way reactivity in the table.

Explanation:
The above happens because implementing an ATable component in a file doesn't give you easy access to the data store (the unique class instance ID isn't exposed), which means trying to use the setCellData API in that file is a hassle.

Possible solutions:
I think there's multiple iterations that can happen to fix this issue, some of which include:

  • At the very minimum, ATable can expose the data store class after initialization. Vue has a defineExpose API that can let parent components access attributes inside the ATable component (tableData, for our purpose here).
  • We can also use a state-management plugin like Pinia to implement shared states (+ APIs) without relying on provide/inject/expose.
    • In cases of multiple tables, this could either mean defining a store instance per ATable (differentiated using the id?), or maintaining a shared store which can hold all table states simultaneously. Either case would also work in parallel with other stores defined in the future inside the Stonecrop context.

Example using exposed attributes (doesn't work perfectly, but this should be useful for the concept atleast 😅):

// ATable.vue
<script setup>
// ... existing code

defineExpose({ tableData })
</script>
// Implementation.vue
<template>
	<ATable ref="table" />
</template>

<script setup>
const tableRows = ref([])
const tableRef = useTemplateRef('table')

watch(tableRef, (table) => {
	// access the data in the table defined in the template
	tableRows.value = table?.tableData.rows
})

watch(tableRows, (rows) => {
	const cellData = {} // figure out which cell has changed
	tableRef.value?.tableData.setCellData() // use store APIs to update cell data
})
</script>
@Alchez Alchez added the enhancement New feature or request label Dec 5, 2024
@Alchez Alchez linked a pull request Dec 11, 2024 that will close this issue
@Alchez Alchez closed this as completed Dec 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants