🔍 Code Extractor

class TrainingCompletion

Maturity: 28

UI component for completing training requirements.

File:
/tf/active/vicechatdev/CDocs/ui/training_completion.py
Lines:
24 - 783
Complexity:
moderate

Purpose

UI component for completing training requirements.

Source Code

class TrainingCompletion(BaseUIComponent):
    """UI component for completing training requirements."""
    
    def __init__(self, parent_app=None, document_uid: str = None, **params):
        super().__init__(parent_app, **params)
        self.current_user = None
        self.document_uid = document_uid
        self.document = None
        self.current_version = None  # ADD THIS LINE
        self.training_config = None
        self.user_training = None
        
        # UI components
        self.main_content = pn.Column(sizing_mode='stretch_width')
        self.document_content = None
        self.quiz_section = None
        self.completion_form = None
        
        self._build_ui()
    
    def _build_ui(self):
        """Build the training completion UI."""
        try:
            # Create header
            self.header = pn.pane.Markdown("# Training Completion", sizing_mode='stretch_width')
            
            # Create loading message
            self.loading_panel = pn.pane.HTML(
                "<div class='alert alert-info'>Loading training content...</div>",
                sizing_mode='stretch_width'
            )
            
            # Add components to main content
            self.main_content.extend([
                self.header,
                self.loading_panel
            ])
            
        except Exception as e:
            logger.error(f"Error building training completion UI: {e}")
            self.main_content.append(pn.pane.Markdown(f"**Error:** {str(e)}"))
    
    def set_user_and_document(self, user: DocUser, document_uid: str):
        """Set the current user and document for training."""
        try:
            self.current_user = user
            self.document_uid = document_uid
            self._load_training_content()
        except Exception as e:
            logger.error(f"Error setting user and document: {e}")
            self.show_error(f"Error loading training: {str(e)}")
    
    def _load_training_content(self):
        """Load the document and training configuration."""
        try:
            if not self.current_user or not self.document_uid:
                self.show_error("Missing user or document information")
                return
            
            # Load document
            self.document = ControlledDocument(uid=self.document_uid)
            if not self.document or not self.document.uid:
                self.show_error("Document not found")
                return
            
            # Get current version - ADD THIS
            self.current_version = self.document.current_version
            if not self.current_version:
                self.show_error("No document version available")
                return
            
            logger.info(f"Loaded document: {self.document.doc_number} v{self.current_version.version_number}")
            
            # Load training configuration
            self.training_config = DocumentTraining(document_uid=self.document_uid)
            if not self.training_config._data.get('training_required'):
                self.show_error("Training is not required for this document")
                return
            
            # Load user training status
            self.user_training = UserTraining(self.current_user.uid, self.document_uid)
            if not self.user_training._data:
                self.show_error("You are not assigned to training for this document")
                return
            
            # Build the training interface
            self._build_training_interface()
            
        except Exception as e:
            logger.error(f"Error loading training content: {e}")
            self.show_error(f"Error loading training: {str(e)}")
    
    def _build_training_interface(self):
        """Build the main training interface."""
        try:
            # Clear main content
            self.main_content.clear()
            logger.info("document uid: %s", self.document.uid)
            # Update header with document info
            header_text = f"# Training: {self.document.doc_number} - {self.document.title}"
            self.header = pn.pane.Markdown(header_text, sizing_mode='stretch_width')
            self.main_content.append(self.header)
            
            # Add notification area for messages
            self.notification_area = pn.pane.HTML("", sizing_mode='stretch_width')
            self.main_content.append(self.notification_area)
            
            # Add training instructions if available
            instructions = self.training_config._data.get('instructions', '')
            if instructions:
                instructions_panel = pn.pane.Markdown(
                    f"## Training Instructions\n\n{instructions}",
                    sizing_mode='stretch_width'
                )
                self.main_content.append(instructions_panel)
        
            # Add document content section - FIX: Call the method and append result
            document_content_section = self._build_document_content()
            self.main_content.append(document_content_section)
            
            # Add quiz section if required
            if self.training_config._data.get('quiz_required'):
                self._build_quiz_section()
            
            # Add completion form
            self._build_completion_form()
            
        except Exception as e:
            logger.error(f"Error building training interface: {e}")
            self.show_error(f"Error building training interface: {str(e)}")
    
    def _build_document_content(self) -> pn.viewable.Viewable:
        """Build document content display similar to document detail view."""
        try:
            if not self.document:
                return pn.pane.Markdown("No document available.")
            
            if not hasattr(self, 'current_version') or not self.current_version:
                # Try to get current version if not set
                self.current_version = self.document.current_version
                if not self.current_version:
                    return pn.pane.Markdown("No document version available.")
            
            # Create document information section
            doc_info = pn.Column(
                pn.pane.Markdown(f"## {self.document.title}"),
                pn.pane.Markdown(f"**Document Number:** {self.document.doc_number}"),
                pn.pane.Markdown(f"**Version:** {self.current_version.version_number}"),
                sizing_mode='stretch_width'
            )
            
            # Add optional fields only if they exist
            try:
                if hasattr(self.document, 'doc_type_name') and self.document.doc_type_name:
                    doc_info.append(pn.pane.Markdown(f"**Type:** {self.document.doc_type_name}"))
            except:
                pass
            
            try:
                if hasattr(self.document, 'get_department_name'):
                    dept_name = self.document.get_department_name()
                    if dept_name:
                        doc_info.append(pn.pane.Markdown(f"**Department:** {dept_name}"))
            except:
                pass
            
            try:
                if hasattr(self.document, 'get_status_name'):
                    status_name = self.document.get_status_name()
                    if status_name:
                        doc_info.append(pn.pane.Markdown(f"**Status:** {status_name}"))
            except:
                pass
            
            # Add document description if available
            try:
                description = getattr(self.document, 'description', None)
                if description:
                    doc_info.append(pn.pane.Markdown(f"**Description:** {description}"))
            except:
                pass
            
            # Style the info section
            doc_info.styles = {'background':'#f8f9fa'}
            doc_info.css_classes = ['p-3', 'border', 'rounded']
            
            # Use DocumentAccessControls for view/edit functionality (same as document_detail)
            access_controls_section = None
            if self.current_version and self.current_user:
                try:
                    from CDocs.ui.components.document_access_controls import DocumentAccessControls
                    
                    access_controls = DocumentAccessControls(
                        document_uid=self.document.uid,
                        user_uid=self.current_user.uid,
                        show_access_indicator=True
                    )
                    
                    access_controls_section = pn.Column(
                        pn.pane.Markdown("### Document Access"),
                        access_controls.view(),
                        sizing_mode='stretch_width'
                    )
                    
                except Exception as e:
                    logger.warning(f"Error creating access controls: {e}")
                    # Fallback to simple view button
                    access_controls_section = self._create_fallback_view_button()
            else:
                access_controls_section = pn.pane.Markdown("*Document access not available*")
        
            # Create document preview section
            preview_section = self._create_document_preview()
            
            # Combine all sections
            content_layout = pn.Column(
                pn.pane.Markdown("## Document Information"),
                doc_info,
                access_controls_section,
                pn.pane.Markdown("---"),  # Separator
                preview_section,
                sizing_mode='stretch_width'
            )
            
            return content_layout
            
        except Exception as e:
            logger.error(f"Error building document content: {e}")
            import traceback
            logger.error(f"Traceback: {traceback.format_exc()}")
            return pn.pane.Markdown(f"Error loading document content: {str(e)}")

    def _create_document_preview(self) -> pn.viewable.Viewable:
        """Create document preview section."""
        try:
            if not hasattr(self, 'current_version') or not self.current_version:
                return pn.pane.Markdown("No document version available for preview.")
            
            # Get file information safely
            file_path = None
            file_type = "Unknown"
            
            try:
                # Determine primary file path based on document status
                if hasattr(self.document, 'is_published') and self.document.is_published():
                    file_path = getattr(self.current_version, 'pdf_file_path', None)
                    file_type = "PDF"
                else:
                    file_path = getattr(self.current_version, 'word_file_path', None)
                    file_type = "Document"
                
                if not file_path:
                    # Try alternative file path
                    if hasattr(self.document, 'is_published') and self.document.is_published():
                        file_path = getattr(self.current_version, 'word_file_path', None)
                        file_type = "Document"
                    else:
                        file_path = getattr(self.current_version, 'pdf_file_path', None)
                        file_type = "PDF"
            except Exception as e:
                logger.warning(f"Error determining file path: {e}")
            
            if file_path:
                preview_info = pn.Column(
                    pn.pane.Markdown("### Document Preview"),
                    pn.pane.Markdown(f"**File Type:** {file_type}"),
                    pn.pane.Markdown(f"**File Path:** {file_path}"),
                    pn.pane.Markdown("*Use the 'View Document' button above to open the document.*"),
                    styles={'background':'#e9ecef'},
                    css_classes=['p-3', 'border', 'rounded']
                )
            else:
                preview_info = pn.pane.Markdown(
                    "**No document file available for preview.**",
                    styles={'background':'#fff3cd'},
                    css_classes=['p-3', 'border', 'rounded']
                )
            
            return preview_info
            
        except Exception as e:
            logger.error(f"Error creating document preview: {e}")
            return pn.pane.Markdown(f"Error creating preview: {str(e)}")

    def _view_document(self, event=None):
        """View the current document version using the same method as document detail view."""
        try:
            if not self.document or not hasattr(self, 'current_version') or not self.current_version:
                self.show_error("No document available to view")
                return
            
            logger.info(f"Getting document view URL for document {self.document.uid}")
            
            # Import the document controller to get the view URL
            from CDocs.controllers.document_controller import get_document_edit_url
            
            # Get the document view URL
            result = get_document_edit_url(
                document_uid=self.document.uid,
                user=self.current_user,
                version_uid=self.current_version.uid
            )
            
            if result.get('success'):
                view_url = result.get('view_url')
                if view_url:
                    # Open document in new tab/window
                    notification_html = f"""
                    <div class='alert alert-info'>
                    <strong>Opening document...</strong><br>
                    If the document doesn't open automatically, <a href='{view_url}' target='_blank'>click here</a>.
                    </div>
                    <script>
                    window.open('{view_url}', '_blank');
                    </script>
                    """
                    
                    if hasattr(self, 'notification_area') and self.notification_area:
                        self.notification_area.object = notification_html
                    else:
                        self.show_info(f"Opening document: {view_url}")
                else:
                    self.show_error("Document view URL not available")
            else:
                error_msg = result.get('message', 'Unknown error')
                self.show_error(f"Error getting document URL: {error_msg}")
            
        except Exception as e:
            logger.error(f"Error viewing document: {e}")
            import traceback
            logger.error(f"Traceback: {traceback.format_exc()}")
            self.show_error(f"Error viewing document: {str(e)}")

    def _build_quiz_section(self):
        """Build the quiz section if required."""
        try:
            quiz_header = pn.pane.Markdown("## Training Quiz", sizing_mode='stretch_width')
            self.main_content.append(quiz_header)
            
            # Simple quiz placeholder - in a real implementation, this would load actual quiz questions
            quiz_questions = [
                {
                    "question": "Have you read and understood the document content?",
                    "type": "boolean",
                    "required": True
                },
                {
                    "question": "Do you understand the procedures described in this document?",
                    "type": "boolean", 
                    "required": True
                },
                {
                    "question": "Any questions or concerns about this document?",
                    "type": "text",
                    "required": False
                }
            ]
            
            self.quiz_widgets = []
            
            for i, q in enumerate(quiz_questions):
                question_panel = pn.Column(sizing_mode='stretch_width')
                question_panel.append(pn.pane.Markdown(f"**Question {i+1}:** {q['question']}"))
                
                if q['type'] == 'boolean':
                    widget = pn.widgets.RadioButtonGroup(
                        name=f"question_{i}",
                        options=['Yes', 'No'],
                        value='Yes' if not q['required'] else None,
                        sizing_mode='stretch_width'
                    )
                elif q['type'] == 'text':
                    widget = pn.widgets.TextAreaInput(
                        name=f"question_{i}",
                        placeholder="Enter your response...",
                        rows=3,
                        sizing_mode='stretch_width'
                    )
                
                self.quiz_widgets.append(widget)
                question_panel.append(widget)
                self.main_content.append(question_panel)
            
        except Exception as e:
            logger.error(f"Error building quiz section: {e}")
            self.main_content.append(pn.pane.Markdown(f"**Error building quiz:** {str(e)}"))
    
    def _build_completion_form(self):
        """Build the training completion form."""
        try:
            completion_header = pn.pane.Markdown("## Complete Training", sizing_mode='stretch_width')
            self.main_content.append(completion_header)
            
            # Confirmation checkbox
            self.confirm_checkbox = pn.widgets.Checkbox(
                name="I confirm that I have completed this training and understand the content",
                value=False,
                sizing_mode='stretch_width'
            )
            
            # Comments field
            self.comments_input = pn.widgets.TextAreaInput(
                name="Comments (optional)",
                placeholder="Enter any comments about this training...",
                rows=3,
                sizing_mode='stretch_width'
            )
            
            # Buttons
            self.complete_btn = pn.widgets.Button(
                name="Complete Training",
                button_type="success",
                width=150
            )
            
            self.cancel_btn = pn.widgets.Button(
                name="Cancel",
                button_type="default", 
                width=100
            )
            
            # Button handlers
            self.complete_btn.on_click(self._handle_complete_training)
            self.cancel_btn.on_click(self._handle_cancel)
            
            # Add completion form components
            completion_form = pn.Column(
                self.confirm_checkbox,
                self.comments_input,
                pn.Row(
                    pn.layout.HSpacer(),
                    self.cancel_btn,
                    self.complete_btn
                ),
                sizing_mode='stretch_width',
                styles={'background': '#f8f9fa'},
                css_classes=['p-3', 'border', 'rounded']
            )
            
            self.main_content.append(completion_form)
            
        except Exception as e:
            logger.error(f"Error building completion form: {e}")
            self.main_content.append(pn.pane.Markdown(f"**Error building completion form:** {str(e)}"))
    
    def _handle_complete_training(self, event):
        """Handle training completion."""
        try:
            # Validate form
            if not self.confirm_checkbox.value:
                self.show_error("You must confirm completion to proceed")
                return
            
            # Validate quiz if required
            quiz_passed = True
            if self.training_config._data.get('quiz_required') and hasattr(self, 'quiz_widgets'):
                quiz_passed = self._validate_quiz()
                if not quiz_passed:
                    self.show_error("Please complete all required quiz questions")
                    return
            
            # Complete the training
            result = training_controller.complete_user_training(
                user=self.current_user,
                document_uid=self.document_uid,
                quiz_passed=quiz_passed
            )
            
            if result.get('success'):
                self.show_success("Training completed successfully!")
                
                # Navigate back to training dashboard
                if self.parent_app:
                    self.parent_app.navigate_to('training_dashboard')
            else:
                error_msg = result.get('message', 'Unknown error')
                self.show_error(f"Error completing training: {error_msg}")
                
        except Exception as e:
            logger.error(f"Error completing training: {e}")
            self.show_error(f"Error completing training: {str(e)}")
    
    def _handle_cancel(self, event):
        """Handle training cancellation."""
        try:
            # Navigate back to training dashboard
            if self.parent_app:
                self.parent_app.navigate_to('training_dashboard')
        except Exception as e:
            logger.error(f"Error canceling training: {e}")
    
    def _validate_quiz(self) -> bool:
        """Validate quiz responses."""
        try:
            for widget in self.quiz_widgets:
                if hasattr(widget, 'value'):
                    if widget.value is None or widget.value == '':
                        return False
            return True
        except Exception as e:
            logger.error(f"Error validating quiz: {e}")
            return False
    
    def get_view(self) -> pn.viewable.Viewable:
        """Get the main view component."""
        return self.main_content

    def _build_training_instructions(self) -> pn.viewable.Viewable:
        """Build training instructions section with enhanced information."""
        try:
            if not self.training_config:
                return pn.pane.Markdown("No training configuration available.")
            
            # Get training instructions
            instructions = self.training_config.get('instructions', '')
            if not instructions:
                instructions = "Please review the document carefully and complete any required assessments."
            
            # Get training requirements
            quiz_required = self.training_config.get('quiz_required', False)
            validity_days = self.training_config.get('validity_days', 365)
            
            # Create instructions content
            instructions_content = [
                pn.pane.Markdown("## Training Instructions"),
                pn.pane.Markdown(instructions),
                pn.pane.Markdown("---"),
                pn.pane.Markdown("### Training Requirements"),
            ]
            
            # Add requirement details
            if quiz_required:
                instructions_content.append(
                    pn.pane.Markdown("âš ī¸ **Quiz Required:** You must complete a quiz after reviewing the document.")
                )
            else:
                instructions_content.append(
                    pn.pane.Markdown("â„šī¸ **No Quiz Required:** Simply review the document and mark as complete.")
                )
            
            instructions_content.append(
                pn.pane.Markdown(f"📅 **Training Validity:** {validity_days} days from completion")
            )
            
            # Add steps to complete training
            instructions_content.extend([
                pn.pane.Markdown("---"),
                pn.pane.Markdown("### Steps to Complete Training"),
                pn.pane.Markdown("""
1. **Review the Document:** Use the 'View Document' button to open and read the document thoroughly
2. **Understand the Content:** Make sure you understand the procedures and requirements
3. **Complete Assessment:** If required, complete the quiz below
4. **Mark as Complete:** Click the 'Complete Training' button when finished
            """)
            ])
            
            return pn.Column(
                *instructions_content,
                styles={'background':'#f9f9fa'},
                css_classes=['p-3', 'border', 'rounded'],
                sizing_mode='stretch_width'
            )
            
        except Exception as e:
            logger.error(f"Error building training instructions: {e}")
            return pn.pane.Markdown(f"Error loading training instructions: {str(e)}")

    def load_training(self, document_uid: str, user: DocUser):
        """Load training data for a specific document and user."""
        try:
            self.document_uid = document_uid
            self.current_user = user
            
            logger.info(f"Loading training for document {document_uid} and user {user.uid}")
            
            # Load document and version information
            from CDocs.models.document import ControlledDocument
            self.document = ControlledDocument(uid=document_uid)
            
            if not self.document or not self.document.uid:
                self.show_error("Document not found")
                return False
            
            # Get current version
            self.current_version = self.document.current_version
            if not self.current_version:
                self.show_error("No document version available")
                return False
            
            logger.info(f"Loaded document: {self.document.doc_number} v{self.current_version.version_number}")
            
            # Load training configuration
            from CDocs.models.training import DocumentTraining
            self.training_config_obj = DocumentTraining(document_uid=document_uid)
            self.training_config = self.training_config_obj._data
            
            if not self.training_config.get('training_required', False):
                self.show_error("Training is not enabled for this document")
                return False
            
            # Load user training data
            from CDocs.models.training import UserTraining
            self.user_training = UserTraining(user_uid=user.uid, document_uid=document_uid)
            
            if not self.user_training._data:
                self.show_error("No training assignment found for this user and document")
                return False
            
            # Check if already completed
            if self.user_training._data.get('status') == 'TRAINED':
                completion_date = self.user_training._data.get('trained_on')
                self.show_info(f"Training already completed on {self._format_date(completion_date)}")
            
            # Rebuild UI with loaded data
            self._build_ui()
            
            return True
            
        except Exception as e:
            logger.error(f"Error loading training: {e}")
            import traceback
            logger.error(f"Traceback: {traceback.format_exc()}")
            self.show_error(f"Error loading training: {str(e)}")
            return False

    def show_error(self, message: str):
        """Show error message to user."""
        try:
            if hasattr(self, 'notification_area') and self.notification_area:
                self.notification_area.object = f"<div class='alert alert-danger'><strong>Error:</strong> {message}</div>"
            else:
                logger.error(f"Error: {message}")
        except Exception as e:
            logger.error(f"Error showing error message: {e}")
            logger.error(f"Original error: {message}")

    def show_success(self, message: str):
        """Show success message to user."""
        try:
            if hasattr(self, 'notification_area') and self.notification_area:
                self.notification_area.object = f"<div class='alert alert-success'><strong>Success:</strong> {message}</div>"
            else:
                logger.info(f"Success: {message}")
        except Exception as e:
            logger.error(f"Error showing success message: {e}")
            logger.info(f"Original success: {message}")

    def show_info(self, message: str):
        """Show info message to user."""
        try:
            if hasattr(self, 'notification_area') and self.notification_area:
                self.notification_area.object = f"<div class='alert alert-info'><strong>Info:</strong> {message}</div>"
            else:
                logger.info(f"Info: {message}")
        except Exception as e:
            logger.error(f"Error showing info message: {e}")
            logger.info(f"Original info: {message}")
    
    def _create_fallback_view_button(self) -> pn.viewable.Viewable:
        """Create a fallback view button when access controls fail."""
        try:
            # Create simple view document button
            view_btn = pn.widgets.Button(
                name="View Document", 
                button_type="primary", 
                width=200
            )
            view_btn.on_click(self._view_document_fallback)
            
            # Create action buttons row
            action_buttons = pn.Row(
                view_btn,
                sizing_mode='stretch_width',
                align='center'
            )
            
            return pn.Column(
                pn.pane.Markdown("### Document Access"),
                action_buttons,
                sizing_mode='stretch_width'
            )
            
        except Exception as e:
            logger.error(f"Error creating fallback view button: {e}")
            return pn.pane.Markdown("*Error creating document access*")

    def _view_document_fallback(self, event=None):
        """Fallback view document method when access controls are not available."""
        try:
            if not self.document or not hasattr(self, 'current_version') or not self.current_version:
                self.show_error("No document available to view")
                return
            
            logger.info(f"Getting document view URL for document {self.document.uid} (fallback)")
            
            # Try to get document edit URL first
            try:
                from CDocs.controllers.document_controller import get_document_edit_url
                
                result = get_document_edit_url(
                    document_uid=self.document.uid,
                    user=self.current_user,
                    version_uid=self.current_version.uid
                )
                
                if result.get('success'):
                    view_url = result.get('view_url')
                    if view_url:
                        self._open_document_url(view_url)
                        return
            except Exception as e:
                logger.warning(f"Failed to get edit URL, trying download: {e}")
            
            # Fallback to download
            try:
                from CDocs.controllers.document_controller import download_document_version
                
                download_result = download_document_version(
                    user=self.current_user,
                    document_uid=self.document.uid,
                    version_uid=self.current_version.uid
                )
                
                if download_result.get('success'):
                    download_url = download_result.get('download_url')
                    if download_url:
                        self._open_document_url(download_url)
                        return
            except Exception as e:
                logger.warning(f"Failed to get download URL: {e}")
            
            self.show_error("Unable to access document")
            
        except Exception as e:
            logger.error(f"Error in fallback view document: {e}")
            import traceback
            logger.error(f"Traceback: {traceback.format_exc()}")
            self.show_error(f"Error viewing document: {str(e)}")

    def _open_document_url(self, url: str):
        """Open document URL in new tab/window."""
        try:
            notification_html = f"""
            <div class='alert alert-info'>
            <strong>Opening document...</strong><br>
            If the document doesn't open automatically, <a href='{url}' target='_blank'>click here</a>.
            </div>
            <script>
            window.open('{url}', '_blank');
            </script>
            """
            
            if hasattr(self, 'notification_area') and self.notification_area:
                self.notification_area.object = notification_html
            else:
                self.show_info(f"Opening document: {url}")
                
        except Exception as e:
            logger.error(f"Error opening document URL: {e}")
            self.show_error(f"Error opening document: {str(e)}")

Parameters

Name Type Default Kind
bases BaseUIComponent -

Parameter Details

bases: Parameter of type BaseUIComponent

Return Value

Returns unspecified type

Class Interface

Methods

__init__(self, parent_app, document_uid)

Purpose: Internal method: init

Parameters:

  • parent_app: Parameter
  • document_uid: Type: str

Returns: None

_build_ui(self)

Purpose: Build the training completion UI.

Returns: None

set_user_and_document(self, user, document_uid)

Purpose: Set the current user and document for training.

Parameters:

  • user: Type: DocUser
  • document_uid: Type: str

Returns: None

_load_training_content(self)

Purpose: Load the document and training configuration.

Returns: None

_build_training_interface(self)

Purpose: Build the main training interface.

Returns: None

_build_document_content(self) -> pn.viewable.Viewable

Purpose: Build document content display similar to document detail view.

Returns: Returns pn.viewable.Viewable

_create_document_preview(self) -> pn.viewable.Viewable

Purpose: Create document preview section.

Returns: Returns pn.viewable.Viewable

_view_document(self, event)

Purpose: View the current document version using the same method as document detail view.

Parameters:

  • event: Parameter

Returns: None

_build_quiz_section(self)

Purpose: Build the quiz section if required.

Returns: None

_build_completion_form(self)

Purpose: Build the training completion form.

Returns: None

_handle_complete_training(self, event)

Purpose: Handle training completion.

Parameters:

  • event: Parameter

Returns: None

_handle_cancel(self, event)

Purpose: Handle training cancellation.

Parameters:

  • event: Parameter

Returns: None

_validate_quiz(self) -> bool

Purpose: Validate quiz responses.

Returns: Returns bool

get_view(self) -> pn.viewable.Viewable

Purpose: Get the main view component.

Returns: Returns pn.viewable.Viewable

_build_training_instructions(self) -> pn.viewable.Viewable

Purpose: Build training instructions section with enhanced information.

Returns: Returns pn.viewable.Viewable

load_training(self, document_uid, user)

Purpose: Load training data for a specific document and user.

Parameters:

  • document_uid: Type: str
  • user: Type: DocUser

Returns: None

show_error(self, message)

Purpose: Show error message to user.

Parameters:

  • message: Type: str

Returns: None

show_success(self, message)

Purpose: Show success message to user.

Parameters:

  • message: Type: str

Returns: None

show_info(self, message)

Purpose: Show info message to user.

Parameters:

  • message: Type: str

Returns: None

_create_fallback_view_button(self) -> pn.viewable.Viewable

Purpose: Create a fallback view button when access controls fail.

Returns: Returns pn.viewable.Viewable

_view_document_fallback(self, event)

Purpose: Fallback view document method when access controls are not available.

Parameters:

  • event: Parameter

Returns: None

_open_document_url(self, url)

Purpose: Open document URL in new tab/window.

Parameters:

  • url: Type: str

Returns: None

Required Imports

import logging
from typing import Dict
from typing import List
from typing import Any
from typing import Optional

Usage Example

# Example usage:
# result = TrainingCompletion(bases)

Similar Components

AI-powered semantic similarity - components with related functionality:

  • class TrainingManagement 72.7% similar

    UI component for managing document training.

    From: /tf/active/vicechatdev/CDocs/ui/training_management.py
  • class TrainingDashboard 70.8% similar

    Training dashboard for users to view and complete training requirements.

    From: /tf/active/vicechatdev/CDocs/ui/training_dashboard.py
  • function create_training_completion 62.8% similar

    Factory function that instantiates and returns a TrainingCompletion object for managing training completion workflows in a document control system.

    From: /tf/active/vicechatdev/CDocs/ui/training_completion.py
  • function complete_user_training_by_uid 54.1% similar

    Completes a user's training assignment for a controlled document by updating the training relationship status, recording completion date and score, and logging the event to the audit trail.

    From: /tf/active/vicechatdev/CDocs/controllers/training_controller.py
  • class UserTraining 53.5% similar

    A model class representing a user's training status for a specific controlled document, managing training assignments, completion tracking, and expiration dates.

    From: /tf/active/vicechatdev/CDocs/models/training.py
← Back to Browse