> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognigy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Members

export const ExpandableTable = ({headers = [], rows = [], initialRowsToShow, showMoreRowsText = "Show more", showLessRowsText = "Hide"}) => {
  const [isExpanded, setIsExpanded] = useState(false);
  const [columnWidths, setColumnWidths] = useState([]);
  const hiddenTableRef = useRef(null);
  const visibleTableRef = useRef(null);
  const shouldLimitRows = initialRowsToShow !== undefined && initialRowsToShow < rows.length;
  const hasMoreRows = shouldLimitRows;
  useEffect(() => {
    if (hiddenTableRef.current && visibleTableRef.current && rows.length > 0) {
      const hiddenTable = hiddenTableRef.current;
      const visibleTable = visibleTableRef.current;
      const hiddenHeaders = hiddenTable.querySelectorAll('th');
      const visibleHeaders = visibleTable.querySelectorAll('th');
      const widths = Array.from(hiddenHeaders).map(th => th.offsetWidth);
      setColumnWidths(widths);
      visibleHeaders.forEach((th, index) => {
        if (widths[index]) {
          th.style.width = `${widths[index]}px`;
          th.style.minWidth = `${widths[index]}px`;
        }
      });
    }
  }, [rows.length, headers.length]);
  const renderContent = content => {
    if (content && typeof content === 'object' && content.$$typeof) {
      return content;
    }
    if (typeof content === 'string' && content.includes('<')) {
      return <span dangerouslySetInnerHTML={{
        __html: content
      }} />;
    }
    return content;
  };
  const renderCell = cell => renderContent(cell);
  return <>
      {}
      <div style={{
    position: 'absolute',
    visibility: 'hidden',
    height: 0,
    overflow: 'hidden',
    width: '100%'
  }}>
        <table ref={hiddenTableRef} className="bg-card dark:bg-muted min-w-full divide-y divide-neutral-200 dark:divide-neutral-700">
          <thead className="dark:text-neutral-300">
            <tr>
              {headers.map((header, index) => <th key={index} className="cursor-pointer whitespace-nowrap px-4 py-3 text-left text-xs font-medium" scope="col" style={header.minWidth ? {
    minWidth: header.minWidth
  } : {}}>
                  {typeof header === 'object' && header.content !== undefined ? renderContent(header.content) : renderContent(header)}
                </th>)}
            </tr>
          </thead>
          <tbody className="bg-background dark:bg-card divide-y divide-neutral-200 dark:divide-neutral-700">
            {rows.map((row, rowIndex) => <tr key={rowIndex}>
                {row.map((cell, cellIndex) => <td key={cellIndex} className="px-4 py-3 text-sm text-neutral-900 dark:text-neutral-100">
                    {renderCell(cell)}
                  </td>)}
              </tr>)}
          </tbody>
        </table>
      </div>
      
      <div className="overflow-x-auto rounded-md">
        <table ref={visibleTableRef} className="bg-card dark:bg-muted min-w-full divide-y divide-neutral-200 dark:divide-neutral-700">
          <thead className="dark:text-neutral-300">
            <tr>
              {headers.map((header, index) => <th key={index} className="cursor-pointer whitespace-nowrap px-4 py-3 text-left text-xs font-medium" scope="col" style={header.minWidth ? {
    minWidth: header.minWidth
  } : {}}>
                  {typeof header === 'object' && header.content !== undefined ? renderContent(header.content) : renderContent(header)}
                </th>)}
            </tr>
          </thead>
          <tbody className="bg-background dark:bg-card divide-y divide-neutral-200 dark:divide-neutral-700">
            {rows.map((row, rowIndex) => {
    const shouldShow = isExpanded || !shouldLimitRows || rowIndex < initialRowsToShow;
    return <tr key={rowIndex} style={{
      display: shouldShow ? 'table-row' : 'none'
    }}>
                  {row.map((cell, cellIndex) => <td key={cellIndex} className="px-4 py-3 text-sm text-neutral-900 dark:text-neutral-100">
                      {renderCell(cell)}
                    </td>)}
                </tr>;
  })}
          </tbody>
        </table>
        {hasMoreRows && <div className="flex justify-center" style={{
    marginTop: '-0.5em',
    marginBottom: '1em'
  }}>
            <button className="rounded-full border border-neutral-200 px-3 py-1 text-sm text-neutral-800 transition-colors hover:bg-neutral-300 dark:border-neutral-500 dark:text-neutral-200 dark:hover:bg-neutral-600" type="button" onClick={() => setIsExpanded(!isExpanded)}>
              {isExpanded ? showLessRowsText : showMoreRowsText}
            </button>
          </div>}
      </div>
    </>;
};

<a href="/release-notes/4.75"><Badge className="version-badge" color="blue">Updated in 4.75</Badge></a>

The *Members* interface in a Cognigy.AI Project allows Project admins to assign and manage Project-specific roles. This interface allows fine-grained control over who can create, edit, view, or update different parts of a Project, complementing the [global roles](/ai/administer/access/admin-center/access-control) set in the Access Control.

## Project Roles

Project roles let you control what users can do within a specific Project. To manage permissions across the whole organization, use [global roles](/ai/administer/access/admin-center/access-control).

<Note>
  Project roles assigned to users determine what actions a user can perform in the UI and through API endpoints, ensuring consistent access control across both interfaces.
</Note>

Each permission works as follows:

* **Create** – create a new resource.
* **Read** – view or retrieve the resource and its details.
* **Update** – view and change an existing resource's data or settings.
* **Delete** – permanently remove the resource.

Having full permissions means a user can create, read, update, and delete the resource.

<ExpandableTable
  headers={["Role", "Description"]}
  rows={[
["<code>agentAssistConfigAdmin</code>", "Full permissions for the configuration of Agent Copilot workspace."],
["<code>agentAssistConfigViewer</code>", "Access to read the configuration of the Agent Copilot workspace."],
["<code>analytics</code>", "Full permissions for Analytics."],
["<code>basic</code>", "Access to read all Project resources except User Details, Contact Profiles, Node Comments, Logs, and Member Details."],
["<code>connection_admin</code>", "Full permissions for Connections."],
["<code>contact_profile_admin</code>", "Full permissions for Contact Profiles and Conversation History."],
["<code>contact_profile_editor</code>", "Access to update Contact Profiles."],
["<code>contact_profile_viewer</code>", "Access to read Contact Profiles."],
["<code>conversationHistory</code>", "Full permissions for Conversation History."],
["<code>data_privacy_admin</code>", "Full permissions for data privacy settings (Collect Analytics, Store Contact Profiles, Collect Conversations, Mask Analytics, Mask Logging)."],
["<code>data_privacy_editor</code>", "Access to update data privacy settings."],
["<code>data_privacy_viewer</code>", "Access to read data privacy settings."],
["<code>developer</code>", "Full permissions for Extensions, Node Comments, Node Descriptions, Locales, Logs, and the Live Follow feature."],
["<code>endpoint_admin</code>", "Full permissions for Endpoints."],
["<code>extension_admin</code>", "Full permissions for Extensions."],
["<code>extension_editor</code>", "Access to update Extensions."],
["<code>extension_trust_admin</code>", "Access to mark Extensions as trusted or untrusted."],
["<code>flowEditor</code>", "Full permissions for the Flow editor and access to update Intents."],
["<code>flowNodeComments</code>", "Full permissions for Node Comments."],
["<code>flowNodeDescription</code>", "Full permissions for Node Descriptions."],
["<code>followUser</code>", "Full permissions for the Live Follow feature."],
["<code>function_admin</code>", "Full permissions for Functions."],
["<code>function_editor</code>", "Access to update Functions."],
["<code>handoverProviderAdmin</code>", "Full permissions for handover providers."],
["<code>intents</code>", "Full permissions for Intents."],
["<code>knowledgeAdmin</code>", "Full permissions for Knowledge AI resources."],
["<code>large_language_model_admin</code>", "Full permissions for Large Language Models."],
["<code>lexicon_admin</code>", "Full permissions for Lexicons."],
["<code>lexicon_editor</code>", "Access to update Lexicons."],
["<code>localesAdmin</code>", "Full permissions for Locales."],
["<code>logs</code>", "Full permissions for Logs."],
["<code>memberManager</code>", "Full permissions for Member Details and read access to the Access Control page in the Admin Center."],
["<code>nlu_connector_admin</code>", "Full permissions for NLU connectors."],
["<code>packages_admin</code>", "Full permissions for Packages."],
["<code>playbook_admin</code>", "Full permissions for Playbooks."],
["<code>playbook_editor</code>", "Access to update Playbooks."],
["<code>projectAdmin</code>", "Full permissions for Project resources and read access to the Access Control page in the Admin Center."],
["<code>simulator_admin</code>", "Full permissions for the Simulator."],
["<code>snapshot_admin</code>", "Full permissions for Snapshots. Permission to restore a Snapshot remains with the `projectAdmin` role."],
["<code>tokenAdmin</code>", "Full permissions for Tokens."],
["<code>tokenEditor</code>", "Access to update Tokens."]
]}
  initialRowsToShow={5}
  showMoreRowsText="Show more roles"
  showLessRowsText="Hide roles"
/>

## Add a Member

1. In the left-side menu of the Project, go to **Manage > Members**, then click **+ Add new Member** in the upper-left corner.
2. In the **New Member** pane, select the user you want to add to the Project. Click **Add**.
3. In the **Project Roles** section, click **+** to select one or more roles to assign. You can assign multiple roles to a user.
4. *(Optional)* In the **Local restrictions** section, assign a user to specific locales by selecting the **User is restricted to the following locales** option and the locales.

## More Information

* [Access Control](/ai/administer/access/admin-center/access-control)
