@encatch/shared-module

v0.0.5

Published

A React library providing shared utilities, hooks, and components for API requests and permission management in the Encatch ecosystem.

Readme

@encatch/shared-module

A React library providing shared utilities, hooks, and components for API requests and permission management in the Encatch ecosystem.

Installation

npm install @encatch/shared-module

Features

  • API Request Hook: Unified API request handling with fallback support
  • Permission System: Complete permission management with React context, hooks, and components
  • TypeScript Support: Full TypeScript definitions included

Exports

Hooks

useEngageFetchApi

A custom hook for making API requests that intelligently uses window.fetchApi when available, or falls back to the standard fetch API.

import { useEngageFetchApi } from '@encatch/shared-module';

function MyComponent() {
  const requestData = useEngageFetchApi();

  const fetchUsers = async () => {
    try {
      const data = await requestData(
        '/api/users',
        'GET',
        undefined,
        { 'Content-Type': 'application/json' }
      );
      console.log(data);
    } catch (error) {
      console.error('Failed to fetch users:', error);
    }
  };

  return <button onClick={fetchUsers}>Fetch Users</button>;
}

Parameters:

  • url: string - The API endpoint URL
  • method: "GET" | "POST" | "PUT" | "DELETE" - HTTP method
  • body?: unknown - Request body (optional, not used for GET requests)
  • headers?: HeadersInit - Request headers (optional, defaults to {})

Returns: Promise<unknown> - The response data


usePermissionCheck

A hook to check if the current user has required permissions for organization or project scopes.

import { usePermissionCheck } from '@encatch/shared-module';

function MyComponent() {
  const hasPermission = usePermissionCheck({
    orgScopes: ['projects:create', 'projects:read'],
    projectScopes: ['forms:update'],
    organizationId: '123',
    projectId: '456'
  });

  return hasPermission ? <SecureContent /> : <AccessDenied />;
}

Parameters:

  • orgScopes?: string[] - Organization-level permission scopes to check
  • projectScopes?: string[] - Project-level permission scopes to check
  • organizationId?: string | number - Organization ID (optional, falls back to context)
  • projectId?: string | number - Project ID (optional, falls back to context)

Returns: boolean - true if the user has any of the required permissions


usePermissionContext

A hook to access the permission context values.

import { usePermissionContext } from '@encatch/shared-module';

function MyComponent() {
  const { permissions, organizationId, projectId } = usePermissionContext();

  return <div>Current Org: {organizationId}</div>;
}

Returns: PermissionContextValue

  • permissions: PermissionResponse | null - Current user permissions
  • organizationId?: string | number - Current organization ID
  • projectId?: string | number - Current project ID

Components

PermissionProvider

A context provider that supplies permission data to child components.

import { PermissionProvider } from '@encatch/shared-module';

function App() {
  const [permissions, setPermissions] = useState(null);

  return (
    <PermissionProvider
      permissions={permissions}
      organizationId="org-123"
      projectId="proj-456"
    >
      <YourApp />
    </PermissionProvider>
  );
}

Props:

  • children: ReactNode - Child components
  • permissions: PermissionResponse | null - User permission data
  • organizationId?: string | number - Current organization ID
  • projectId?: string | number - Current project ID

PermissionCheck

A component that conditionally renders children based on permission checks.

import { PermissionCheck } from '@encatch/shared-module';

function MyComponent() {
  return (
    <PermissionCheck
      orgScopes={['projects:create']}
      projectScopes={['forms:update']}
      organizationId="123"
    >
      <SecureContent />
    </PermissionCheck>
  );
}

Props:

  • children: ReactNode - Content to render if permissions are granted
  • orgScopes?: string[] - Organization-level permission scopes
  • projectScopes?: string[] - Project-level permission scopes
  • organizationId?: string | number - Organization ID
  • projectId?: string | number - Project ID

Utilities

generateModulePermissionsScopesForApi

Transforms module permissions into a flattened structure for API consumption.

import { generateModulePermissionsScopesForApi } from '@encatch/shared-module';

const modulePermissions = {
  forms: {
    create: { method: 'POST', url: '/forms', scopes: ['forms:create'] },
    read: { method: 'GET', url: '/forms', scopes: ['forms:read'] }
  }
};

const apiScopes = generateModulePermissionsScopesForApi(modulePermissions);
// Result: {
//   'POST:/forms': { 'forms:create': true },
//   'GET:/forms': { 'forms:read': true }
// }

Parameters:

  • modulePermissions: ModulePermissions - Module permissions object

Returns: Record<string, Record<string, boolean>> - Flattened permission scopes


Types

PermissionLevel

Enum defining CRUD permission levels:

enum PermissionLevel {
  CREATE = "create",
  DELETE = "delete",
  UPDATE = "update",
  READ = "read"
}

Level

Numeric mapping of permission levels:

const Level: Record<PermissionLevel, number> = {
  [PermissionLevel.CREATE]: 1,
  [PermissionLevel.DELETE]: 2,
  [PermissionLevel.UPDATE]: 3,
  [PermissionLevel.READ]: 4
}

ModulePermission

type ModulePermission = {
  method: string;
  url: string;
  scopes?: string[];
}

ModulePermissions

type ModulePermissions = {
  [key: string]: {
    [key: string]: ModulePermission;
  };
}

ApiPermission

type ApiPermission = {
  method: string;
  url: string;
  scopes: string[];
}

PermissionResponse

interface PermissionResponse {
  userUuid: string;
  organizationRoles: Record<string, Record<string, boolean>>;
  projectRoles: Record<string, Record<string, boolean>>;
  mappedOrganizationRoles: Record<string, string>;
  mappedProjectRoles: Record<string, string>;
  organizationDetails: Array<{
    orgId: number;
    orgUuid: string;
    orgName: string;
    orgDescription: string | null;
  }>;
  projectDetails: Array<{
    projectId: number;
    projectUuid: string;
    projectName: string;
    projectDescription: string | null;
    orgId: number;
  }>;
}

Usage Example

import {
  PermissionProvider,
  PermissionCheck,
  usePermissionCheck,
  useEngageFetchApi
} from '@encatch/shared-module';

function App() {
  const [permissions, setPermissions] = useState(null);
  const requestData = useEngageFetchApi();

  useEffect(() => {
    // Fetch user permissions
    requestData('/api/permissions', 'GET')
      .then(setPermissions)
      .catch(console.error);
  }, []);

  return (
    <PermissionProvider
      permissions={permissions}
      organizationId="org-123"
      projectId="proj-456"
    >
      <Dashboard />
    </PermissionProvider>
  );
}

function Dashboard() {
  const hasCreateAccess = usePermissionCheck({
    orgScopes: ['projects:create']
  });

  return (
    <div>
      {hasCreateAccess && <CreateButton />}

      <PermissionCheck projectScopes={['forms:update']}>
        <EditForm />
      </PermissionCheck>
    </div>
  );
}

Peer Dependencies

  • React ^19.1.1
  • React DOM ^19.1.1

License

Internal library for Encatch projects.