Search code examples
vue.jspermissionsvuetify.jsroles

Vue JS Roles & Permission in a table grid using checkboxes


I would like to check permissions of a role using checkbox in vue. For example if an admin can create, view, delete a checkbox will be selected, if not checkbox will not be selected. So far i have the table created with proper roles and permissions that below to each role but don't know how to check checkbox based on permission in role.

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  
  data() {
    return {
    
    
permissions: [
    {
        id: 1,
        name: "view posts"
    },
    {
        id: 2,
        name: "create posts"
    },
    {
        id: 3,
        "name": "edit posts"
    },
    {
        id: 4,
        name: "delete posts"
    }
],
roles: [
    {
        id: 1,
        name: "admin",
        description: "Full admin access to all the areas of the blog.",
        permissions: [
            {
                id: 1,
                name: "view posts",  
            },
            {
                id: 2,
                name: "create posts",
            },
            {
                id: 3,
                name: "edit posts",
            },
            {
                id: 4,
                name: "delete posts",
            }
        ]
    },
    {
        id: 2,
        name: "executive",
        description: "Limited access to critical areas of the blog",
        permissions: [
            {
                id: 1,
                name: "view posts",   
            },
            {
                id: 2,
                name: "create posts",
            }
        ]
    },
    {
        id: 3,
        name: "user",
        description: "Basic view access to some areas of the blog",
        permissions: [
            {
                id: 1,
                name: "view posts",
            }
        ]
    }
]

     
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

 <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
        
        
         <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
        
<div id="app">

<template>

<div>

<div id='permissionsTable'>
                <v-row class='headerRow'>
                  <v-col cols='3'>Permissions</v-col>
                  <v-col v-for="role in roles" v-bind:key="role.id">{{role.name}}</v-col>
                </v-row>
                <v-row v-for="permission in permissions" v-bind:key="permission.id" class="bodyRow">
                  <v-col cols='3'>{{permission.name}}</v-col>
                  <v-col v-for="(role, index) in roles" v-bind:key="role.name">

                    {{roles[index].permissions}}

                      <v-checkbox :input-value="roles[index].permissions.includes(permission.id)" @change="onItemClick($event,role.name,permission.id)">
                </v-checkbox>
               
                  </v-col>
                </v-row>
              </div>

</div>

</template>

 
</div>


Solution

  • Let me know if this help.

    new Vue({
      el: "#app",
      vuetify: new Vuetify(),
      methods: {
        onItemClick(e, role, permissionId) {
          const index = this.roles.findIndex((r) => r.name === role);
          const found=this.roles[index].permissions.find(perm=> perm.id === permissionId)
          if (
            found
          ) {
            this.roles[index].permissions.splice(
              this.roles[index].permissions.findIndex(perm=>perm.id===permissionId),
              1
            );
          } else {
            this.roles[index].permissions.push(this._permissions[permissionId]);
          }
        }
      },
      computed: {
        _permissions() {
          return this.permissions.reduce((acc, curr) => {
            const id = curr.id;
            acc[id] = curr;
            return acc;
          }, {});
        },
        _roles() {
          return this.roles.reduce((acc, curr) => {
            const id = curr.id;
            acc[id] = curr;
            return acc;
          }, {});
        }
      },
      data() {
        return {
          permissions: [
            {
              id: 1,
              name: "view posts"
            },
            {
              id: 2,
              name: "create posts"
            },
            {
              id: 3,
              name: "edit posts"
            },
            {
              id: 4,
              name: "delete posts"
            }
          ],
          roles: [
            {
              id: 1,
              name: "admin",
              description: "Full admin access to all the areas of the blog.",
              permissions: [
                {
                  id: 1,
                  name: "view posts"
                },
                {
                  id: 2,
                  name: "create posts"
                },
                {
                  id: 3,
                  name: "edit posts"
                },
                {
                  id: 4,
                  name: "delete posts"
                }
              ]
            },
            {
              id: 2,
              name: "executive",
              description: "Limited access to critical areas of the blog",
              permissions: [
                {
                  id: 1,
                  name: "view posts"
                },
                {
                  id: 2,
                  name: "create posts"
                }
              ]
            },
            {
              id: 3,
              name: "user",
              description: "Basic view access to some areas of the blog",
              permissions: [
                {
                  id: 1,
                  name: "view posts"
                }
              ]
            }
          ]
        };
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    
     <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
        <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
        <link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
            <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
            
            
             <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
            <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
     <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
    
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
    
    <div id="app">
    
      <template>
    
        <div>
          <div id='permissionsTable'>
            <v-row class='headerRow'>
              <v-col cols='3'>Permissions</v-col>
              <v-col v-for="role in roles" v-bind:key="role.id">{{role.name}}</v-col>
            </v-row>
            <v-row v-for="permission in permissions" v-bind:key="permission.id" class="bodyRow">
              <v-col cols='3'>{{permission.name}}</v-col>
              <v-col v-for="(role, index) in roles" v-bind:key="role.name">
    
                {{roles[index].permissions}}
    
                <v-checkbox :input-value="_roles[role.id].permissions.find(perm=>perm.id===permission.id)" @change="onItemClick($event,role.name,permission.id)">
                </v-checkbox>
    
              </v-col>
            </v-row>
          </div>
    
        </div>
    
      </template>
    
    </div>