BayBreezy / ui-thing

A set of components created with Radix-Vue. Inspired by shadcn/ui & shadcn-vue.
https://ui-thing.behonbaker.com
Other
309 stars 21 forks source link

AlertDialog not playing nice with Table #20

Closed alvor-sergio closed 1 month ago

alvor-sergio commented 1 month ago

I wanted to add a confirmation dialog inside a table. My use case is asking for user validation before executing an action (remove the user in my case). I noticed that the reference that gets passed to the button inside the dialog is always the last item in whatever item list the table uses.

<template>
  <UiTable>
    <UiTableCaption>A list of registered users.</UiTableCaption>
    <UiTableHeader>
      <UiTableRow>
        <UiTableHead>First name</UiTableHead>
        <UiTableHead>Last name</UiTableHead>
        <UiTableHead>Email</UiTableHead>
        <UiTableHead>Username</UiTableHead>
        <UiTableHead class="text-right">Actions</UiTableHead>
      </UiTableRow>
    </UiTableHeader>
    <UiTableBody class="last:border-b">
      <template v-for="usr in demoUsers" :key="usr.id">
        <UiTableRow>
          <UiTableCell class="font-medium">{{ usr.firstName }}</UiTableCell>
          <UiTableCell>{{ usr.lastName }}</UiTableCell>
          <UiTableCell>{{ usr.email }}</UiTableCell>
          <UiTableCell>
            {{ usr.username }}
          </UiTableCell>
          <UiTableCell class="text-right">
            <UiAlertDialog v-model:open="model">
              <UiAlertDialogTrigger as-child>
                <UiButton variant="outline" size="icon"><Icon class="h-4 w-4" name="material-symbols:person-remove" /></UiButton>
              </UiAlertDialogTrigger>
              <UiAlertDialogContent>
                <UiAlertDialogHeader>
                  <UiAlertDialogTitle>Are you absolutely sure?</UiAlertDialogTitle>
                  <UiAlertDialogDescription>This action cannot be undone. This will permanently remove the user from the application</UiAlertDialogDescription>
                </UiAlertDialogHeader>
                <UiAlertDialogFooter>
                  <UiAlertDialogCancel />
                  <UiAlertDialogAction @click="handleRemove(usr)" />
                </UiAlertDialogFooter>
              </UiAlertDialogContent>
            </UiAlertDialog>
          </UiTableCell>
        </UiTableRow>
      </template>
    </UiTableBody>
  </UiTable>
</template>
<script lang="ts" setup>
  definePageMeta({ layout: "empty" });
  const model = ref(false);
  const demoUsers = [
    {
      id: "691e66bf-ef80-4611-96df-a2c96dc8e18c", firstName: "admin", lastName: "admin",  email: "admin@test.com",
      username: "admin",
    },
    {
      id: "f73c17cf-52b7-4406-a6d0-3b278f5ae0d6", firstName: "test",  lastName: "test",  email: "test@test.com",
      username: "test",
    },
    {
      id: "ab7c26dc-66b0-401e-b504-624b287c9918",  firstName: "test2",  lastName: "test2",   email: "test2@test.com",
      username: "tes2t",
    },
  ];

  const handleRemove = (user: any) => {
    console.log("useriD: ", user.id);
  };
</script>

whatever you click, the id is always the last item in the data array. Replacing the dialog with a button works nicely.

BayBreezy commented 1 month ago

Hey. It's kinda hard to follow the code like this. Are you able to give me a repo with a simple demo or a stackblitz?

alvor-sergio commented 1 month ago

Right, sorry. Here it is https://github.com/byteslash/ui-thing-error.git

BayBreezy commented 1 month ago

So I made some changes to the update branch and did a PR. https://github.com/byteslash/ui-thing-error/pull/1 What I did was to remove the alert dialog from the look inside the table, set the item being edited when the user clicks the button in the table, show the dialog and then perform the action on the user record that was set to be edited.

Let me know if this is clear please.

alvor-sergio commented 1 month ago

this solves the issue. I have suspicion that this situation will also happen with other tables and dialogs though.