frontend_nyla/src/components/Connections/logic.tsx

339 lines
No EOL
9.6 KiB
TypeScript

import { useEffect, useState } from 'react';
import { IoIosLink, IoIosTrash } from 'react-icons/io';
import { MdModeEdit } from 'react-icons/md';
import { GoUnlink } from 'react-icons/go';
import React from 'react';
import { useConnections, useOAuthConnect, useDisconnect } from '../../hooks/useConnections';
import { useLanguage } from '../../contexts/LanguageContext';
import { ColumnConfig } from '../FormGenerator';
import { EditFieldConfig } from '../Popup';
import {
Connection,
CreateConnectionData,
ConnectionsLogicReturn,
TableAction
} from './interfaces';
export function useConnectionsLogic(): ConnectionsLogicReturn {
const { t } = useLanguage();
// Hooks
const {
connections,
fetchConnections,
createConnection,
updateConnection,
connectService,
disconnectService,
deleteConnection,
isLoading,
error
} = useConnections();
const {
connectWithPopup,
isConnecting,
error: connectError
} = useOAuthConnect();
const {
disconnect,
isDisconnecting,
error: disconnectError
} = useDisconnect();
// Local state
const [editPopupOpen, setEditPopupOpen] = useState(false);
const [editingConnection, setEditingConnection] = useState<Connection | null>(null);
// Define field configuration for editing connections
const connectionEditFields: EditFieldConfig[] = [
{
key: 'authority',
label: t('connections.field.service', 'Service'),
type: 'readonly',
editable: false,
formatter: (value: string) => {
if (!value) return t('connections.unknown', 'Unknown');
const labels = {
'google': t('connections.service.google', 'Google'),
'msft': t('connections.service.microsoft', 'Microsoft'),
'local': t('connections.service.local', 'Local')
};
return labels[value as keyof typeof labels] || value;
}
},
{
key: 'status',
label: t('connections.field.status', 'Status'),
type: 'readonly',
editable: false,
formatter: (value: string) => value ? value.charAt(0).toUpperCase() + value.slice(1) : t('connections.unknown', 'Unknown')
},
{
key: 'externalUsername',
label: t('connections.field.external_username', 'External Username'),
type: 'string',
editable: true,
required: false,
placeholder: t('connections.placeholder.external_username', 'Enter external username')
},
{
key: 'externalEmail',
label: t('connections.field.external_email', 'External Email'),
type: 'email',
editable: true,
required: false,
placeholder: t('connections.placeholder.external_email', 'Enter external email address')
},
{
key: 'connectedAt',
label: t('connections.field.connected_at', 'Connected At'),
type: 'readonly',
editable: false,
formatter: (value: string) => {
if (!value) return t('connections.not_available', 'N/A');
try {
return new Date(value).toLocaleString();
} catch {
return t('connections.invalid_date', 'Invalid Date');
}
}
},
{
key: 'lastChecked',
label: t('connections.field.last_checked', 'Last Checked'),
type: 'readonly',
editable: false,
formatter: (value: string) => {
if (!value) return t('connections.not_available', 'N/A');
try {
return new Date(value).toLocaleString();
} catch {
return t('connections.invalid_date', 'Invalid Date');
}
}
}
];
// Define custom columns for the connections table
const connectionColumns: ColumnConfig[] = [
{
key: 'authority',
label: t('connections.field.service', 'Service'),
type: 'enum',
filterOptions: ['google', 'msft', 'local'],
formatter: (value: string) => {
if (!value) return t('connections.unknown', 'Unknown');
const labels = {
'google': t('connections.service.google', 'Google'),
'msft': t('connections.service.microsoft', 'Microsoft'),
'local': t('connections.service.local', 'Local')
};
return labels[value as keyof typeof labels] || value;
},
width: 150,
sortable: true,
filterable: true
},
{
key: 'status',
label: t('connections.field.status', 'Status'),
type: 'enum',
filterOptions: ['active', 'pending', 'expired', 'revoked'],
formatter: (value: string) => {
return value?.charAt(0).toUpperCase() + value?.slice(1) || t('connections.unknown', 'Unknown');
},
width: 120,
sortable: true,
filterable: true
},
{
key: 'externalUsername',
label: t('connections.field.external_username', 'External Username'),
type: 'string',
width: 200,
sortable: true,
filterable: false,
searchable: true
},
{
key: 'externalEmail',
label: t('connections.field.external_email', 'External Email'),
type: 'string',
width: 250,
sortable: true,
filterable: false,
searchable: true
},
{
key: 'connectedAt',
label: t('connections.field.connected_at', 'Connected At'),
type: 'date',
width: 150,
sortable: true,
filterable: false,
searchable: true
},
{
key: 'lastChecked',
label: t('connections.field.last_checked', 'Last Checked'),
type: 'date',
width: 150,
sortable: true,
filterable: true,
searchable: true
},
{
key: 'expiresAt',
label: t('connections.field.expires_at', 'Expires At'),
type: 'date',
width: 150,
sortable: true,
filterable: true
}
];
// Fetch connections on mount
useEffect(() => {
fetchConnections();
}, []);
// Handler functions
const handleCreateConnection = async (type: 'msft' | 'google') => {
console.log('Creating connection for type:', type);
try {
const connectionData: CreateConnectionData = {
type: type,
status: 'pending',
connectedAt: new Date().toISOString(),
lastChecked: new Date().toISOString()
};
console.log('Sending connection data to backend:', connectionData);
const newConnection = await createConnection(connectionData);
console.log('Connection created successfully:', newConnection);
await fetchConnections();
} catch (error) {
console.error('Error creating connection:', error);
}
};
const handleConnect = async (connection: Connection) => {
console.log('Connecting to service:', connection);
try {
await connectWithPopup(connection.id);
await fetchConnections();
} catch (error) {
console.error('Error connecting to service:', error);
}
};
const handleDisconnect = async (connection: Connection) => {
console.log('Disconnecting from service:', connection);
try {
await disconnect(connection.id);
await fetchConnections();
} catch (error) {
console.error('Error disconnecting from service:', error);
}
};
const handleDelete = async (connection: Connection) => {
const serviceName = connection.authority?.charAt(0).toUpperCase() + connection.authority?.slice(1) || t('connections.unknown', 'Unknown');
const confirmMessage = t('connections.confirm_delete', 'Are you sure you want to delete the {service} connection?').replace('{service}', serviceName);
if (window.confirm(confirmMessage)) {
try {
await deleteConnection(connection.id);
await fetchConnections();
} catch (error) {
console.error('Error deleting connection:', error);
}
}
};
const handleConnectOrDisconnect = async (connection: Connection) => {
if (connection.status === 'active') {
await handleDisconnect(connection);
} else {
await handleConnect(connection);
}
};
const handleEditConnection = async (connection: Connection) => {
console.log('Editing connection:', connection);
setEditingConnection(connection);
setEditPopupOpen(true);
};
const handleSaveConnection = async (updatedConnection: Connection) => {
if (!editingConnection) return;
try {
const updateData = {
externalUsername: updatedConnection.externalUsername,
externalEmail: updatedConnection.externalEmail
};
await updateConnection(editingConnection.id, updateData);
console.log('Connection updated successfully');
await fetchConnections();
setEditPopupOpen(false);
setEditingConnection(null);
} catch (error) {
console.error('Error updating connection:', error);
}
};
const handleCancelEdit = () => {
setEditPopupOpen(false);
setEditingConnection(null);
};
// Table actions
const tableActions: TableAction[] = [
{
label: t('connections.action.edit', 'Edit'),
onClick: handleEditConnection,
icon: <MdModeEdit />
},
{
label: t('connections.action.toggle_connection', 'Toggle Connection'),
onClick: handleConnectOrDisconnect,
icon: (connection: Connection) => connection.status === 'active' ? <GoUnlink /> : <IoIosLink />
},
{
label: t('connections.action.delete', 'Delete'),
onClick: handleDelete,
icon: <IoIosTrash />
}
];
return {
// Data
connections,
isLoading,
isConnecting,
isDisconnecting,
error,
connectError,
disconnectError,
editPopupOpen,
editingConnection,
connectionColumns,
connectionEditFields,
tableActions,
// Handlers
handleCreateConnection,
handleConnect,
handleDisconnect,
handleDelete,
handleConnectOrDisconnect,
handleEditConnection,
handleSaveConnection,
handleCancelEdit
};
}