train-modle / static /js /token-manager.js
fokan's picture
Initial clean commit: Multi-Modal Knowledge Distillation Platform
ab4e093
/**
* Token Manager JavaScript
* Handles token management functionality
*/
class TokenManager {
constructor() {
this.tokens = [];
this.init();
}
init() {
this.loadTokens();
this.setupEventListeners();
this.setupTokenTypeHelp();
}
setupEventListeners() {
// Token form submission
document.getElementById('token-form').addEventListener('submit', (e) => {
e.preventDefault();
this.saveToken();
});
// Token validation
document.getElementById('validate-token').addEventListener('click', () => {
this.validateToken();
});
// Token type change
document.getElementById('token-type').addEventListener('change', (e) => {
this.updateTokenTypeHelp(e.target.value);
});
// Task type change
document.getElementById('task-type').addEventListener('change', (e) => {
this.updateTaskHelp(e.target.value);
});
// Get task token
document.getElementById('get-task-token').addEventListener('click', () => {
this.getTaskToken();
});
}
setupTokenTypeHelp() {
const tokenTypeHelp = {
'read': 'للتطوير والتعلم - قراءة فقط',
'write': 'لمشاركة النماذج - قراءة وكتابة',
'fine_grained': 'للمشاريع التجارية - أذونات مخصصة'
};
this.tokenTypeHelp = tokenTypeHelp;
this.updateTokenTypeHelp('read');
// Task type help
const taskTypeHelp = {
'read': 'قراءة النماذج والبيانات العامة - يستخدم رمز القراءة',
'download': 'تحميل النماذج من Hugging Face - يستخدم رمز القراءة',
'medical': 'الوصول للبيانات الطبية الحساسة - يستخدم الرمز المخصص',
'private': 'الوصول للنماذج الخاصة والمحدودة - يستخدم الرمز المخصص',
'write': 'رفع النماذج الجديدة - يستخدم رمز الكتابة',
'upload': 'مشاركة المحتوى مع المجتمع - يستخدم رمز الكتابة',
'commercial': 'المشاريع التجارية والحساسة - يستخدم الرمز المخصص',
'enterprise': 'استخدام المؤسسات الكبيرة - يستخدم الرمز المخصص'
};
this.taskTypeHelp = taskTypeHelp;
this.updateTaskHelp('read');
}
updateTokenTypeHelp(tokenType) {
const helpElement = document.getElementById('token-type-help');
helpElement.textContent = this.tokenTypeHelp[tokenType] || '';
}
updateTaskHelp(taskType) {
const helpElement = document.getElementById('task-help');
helpElement.textContent = this.taskTypeHelp[taskType] || '';
}
async getTaskToken() {
const taskType = document.getElementById('task-type').value;
const button = document.getElementById('get-task-token');
const resultDiv = document.getElementById('task-token-result');
const infoDiv = document.getElementById('selected-token-info');
// Show loading
const originalText = button.innerHTML;
button.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>جاري البحث...';
button.disabled = true;
try {
const response = await fetch(`/api/tokens/for-task/${taskType}`);
const data = await response.json();
if (response.ok && data.token_info) {
// Show token information
infoDiv.innerHTML = `
<div class="row">
<div class="col-md-6">
<strong>نوع الرمز:</strong> ${data.token_info.type_name}<br>
<strong>مستوى الأمان:</strong> ${data.token_info.security_level}<br>
<strong>الاستخدام المناسب:</strong> ${data.token_info.recommended_for}
</div>
<div class="col-md-6">
<strong>الرمز المحدد:</strong> ${data.token_info.token_name}<br>
<strong>آخر استخدام:</strong> ${data.token_info.last_used || 'لم يُستخدم بعد'}<br>
<strong>عدد مرات الاستخدام:</strong> ${data.token_info.usage_count || 0}
</div>
</div>
<div class="mt-2">
<small class="text-muted">
<strong>الوصف:</strong> ${data.token_info.description}
</small>
</div>
`;
resultDiv.style.display = 'block';
// Store selected token for use
this.selectedTaskToken = {
taskType: taskType,
tokenName: data.token_info.token_name,
tokenType: data.token_info.type
};
} else {
this.showError(data.error || 'لم يتم العثور على رمز مناسب لهذه المهمة');
resultDiv.style.display = 'none';
}
} catch (error) {
console.error('Error getting task token:', error);
this.showError('خطأ في الحصول على الرمز المناسب');
resultDiv.style.display = 'none';
} finally {
button.innerHTML = originalText;
button.disabled = false;
}
}
async loadTokens() {
try {
const response = await fetch('/api/tokens');
const data = await response.json();
if (response.ok) {
this.tokens = data.tokens;
this.renderTokens();
} else {
this.showError('فشل في تحميل الرموز');
}
} catch (error) {
console.error('Error loading tokens:', error);
this.showError('خطأ في الاتصال بالخادم');
}
}
renderTokens() {
const container = document.getElementById('tokens-list');
if (this.tokens.length === 0) {
container.innerHTML = `
<div class="text-center text-muted py-4">
<i class="fas fa-key fa-3x mb-3"></i>
<h5>لا توجد رموز محفوظة</h5>
<p>أضف رمز Hugging Face الأول للبدء</p>
</div>
`;
return;
}
const tokensHtml = this.tokens.map(token => this.renderTokenCard(token)).join('');
container.innerHTML = tokensHtml;
}
renderTokenCard(token) {
const typeInfo = token.type_info || {};
const securityLevel = typeInfo.security_level || 'medium';
const securityClass = `security-${securityLevel.replace('_', '-')}`;
const defaultBadge = token.is_default ?
'<span class="badge bg-success me-2">افتراضي</span>' : '';
const activeBadge = token.is_active ?
'<span class="badge bg-primary me-2">نشط</span>' :
'<span class="badge bg-secondary me-2">غير نشط</span>';
return `
<div class="token-card">
<div class="d-flex justify-content-between align-items-start">
<div class="flex-grow-1">
<h5 class="mb-2">
${token.name}
${defaultBadge}
${activeBadge}
</h5>
<div class="mb-2">
<span class="token-type-badge badge bg-info me-2">${typeInfo.name || token.type}</span>
<span class="security-level ${securityClass}">${this.getSecurityLevelText(securityLevel)}</span>
</div>
${token.description ? `<p class="text-muted mb-2">${token.description}</p>` : ''}
<small class="text-muted">
<i class="fas fa-calendar me-1"></i>
أُنشئ: ${this.formatDate(token.created_at)}
${token.last_used ? `| آخر استخدام: ${this.formatDate(token.last_used)}` : ''}
| مرات الاستخدام: ${token.usage_count || 0}
</small>
</div>
<div class="token-actions">
${!token.is_default ? `
<button class="btn btn-sm btn-outline-primary" onclick="tokenManager.setDefaultToken('${token.name}')">
<i class="fas fa-star"></i>
</button>
` : ''}
<button class="btn btn-sm btn-outline-danger" onclick="tokenManager.deleteToken('${token.name}')">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
<!-- Token Type Details -->
<div class="mt-3">
<small class="text-muted">
<strong>الاستخدامات المناسبة:</strong>
${(typeInfo.use_cases || []).join('، ')}
</small>
</div>
</div>
`;
}
getSecurityLevelText(level) {
const levels = {
'medium': 'متوسط',
'high': 'عالي',
'very_high': 'فائق'
};
return levels[level] || level;
}
formatDate(dateString) {
if (!dateString) return 'غير محدد';
const date = new Date(dateString);
return date.toLocaleDateString('ar-SA', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
}
async saveToken() {
const formData = new FormData();
formData.append('name', document.getElementById('token-name').value);
formData.append('token', document.getElementById('token-value').value);
formData.append('token_type', document.getElementById('token-type').value);
formData.append('description', document.getElementById('token-description').value);
formData.append('is_default', document.getElementById('is-default').checked);
try {
const response = await fetch('/api/tokens', {
method: 'POST',
body: formData
});
const data = await response.json();
if (response.ok) {
this.showSuccess(data.message);
this.clearForm();
this.loadTokens();
} else {
this.showError(data.detail || 'فشل في حفظ الرمز');
}
} catch (error) {
console.error('Error saving token:', error);
this.showError('خطأ في الاتصال بالخادم');
}
}
async validateToken() {
const tokenValue = document.getElementById('token-value').value;
if (!tokenValue) {
this.showError('يرجى إدخال قيمة الرمز أولاً');
return;
}
const button = document.getElementById('validate-token');
const originalText = button.innerHTML;
button.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>جاري التحقق...';
button.disabled = true;
try {
const formData = new FormData();
formData.append('token', tokenValue);
const response = await fetch('/api/tokens/validate', {
method: 'POST',
body: formData
});
const data = await response.json();
if (data.valid) {
this.showSuccess(`الرمز صحيح! المستخدم: ${data.username}, الخطة: ${data.plan}`);
} else {
this.showError(`الرمز غير صحيح: ${data.error}`);
}
} catch (error) {
console.error('Error validating token:', error);
this.showError('خطأ في التحقق من الرمز');
} finally {
button.innerHTML = originalText;
button.disabled = false;
}
}
async setDefaultToken(tokenName) {
try {
const response = await fetch(`/api/tokens/${tokenName}/set-default`, {
method: 'POST'
});
const data = await response.json();
if (response.ok) {
this.showSuccess(data.message);
this.loadTokens();
} else {
this.showError(data.detail || 'فشل في تعيين الرمز الافتراضي');
}
} catch (error) {
console.error('Error setting default token:', error);
this.showError('خطأ في الاتصال بالخادم');
}
}
async deleteToken(tokenName) {
if (!confirm(`هل أنت متأكد من حذف الرمز "${tokenName}"؟`)) {
return;
}
try {
const response = await fetch(`/api/tokens/${tokenName}`, {
method: 'DELETE'
});
const data = await response.json();
if (response.ok) {
this.showSuccess(data.message);
this.loadTokens();
} else {
this.showError(data.detail || 'فشل في حذف الرمز');
}
} catch (error) {
console.error('Error deleting token:', error);
this.showError('خطأ في الاتصال بالخادم');
}
}
clearForm() {
document.getElementById('token-form').reset();
this.updateTokenTypeHelp('read');
}
showSuccess(message) {
document.getElementById('success-message').textContent = message;
const toast = new bootstrap.Toast(document.getElementById('success-toast'));
toast.show();
}
showError(message) {
document.getElementById('error-message').textContent = message;
const toast = new bootstrap.Toast(document.getElementById('error-toast'));
toast.show();
}
}
// Initialize token manager when page loads
document.addEventListener('DOMContentLoaded', () => {
window.tokenManager = new TokenManager();
});