/** * Admin Pages Styles * * Common styles for all admin pages using FormGeneratorTable */ .adminPage { padding: 1.5rem; /* Default: grow with content → scroll on MainLayout .outletShell (expandable panels, long pages). */ flex: 0 0 auto; width: 100%; box-sizing: border-box; display: flex; flex-direction: column; } /* * FormGeneratorTable expects a bounded height chain (height:100% / flex:1). * With default .adminPage (flex:0 0 auto), .tableContainer flex:1 collapses → empty table. * Use together: className={`${styles.adminPage} ${styles.adminPageFill}`} */ .adminPage.adminPageFill { flex: 1 1 auto; min-height: 0; overflow: hidden; } .pageHeader { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; flex-shrink: 0; min-height: 0; } .pageTitle { font-size: 1.5rem; font-weight: 600; color: var(--text-primary); margin: 0; } .pageSubtitle { font-size: 0.875rem; color: var(--text-secondary); margin: 0.25rem 0 0 0; } .headerActions { display: flex; gap: 0.75rem; } .primaryButton { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 1rem; background: var(--primary-color, #f25843); color: white; border: none; border-radius: 6px; font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: background 0.2s, transform 0.1s; } .primaryButton:hover { background: var(--primary-dark, #d94d3a); } .primaryButton:active { transform: scale(0.98); } .primaryButton:disabled { opacity: 0.6; cursor: not-allowed; } .secondaryButton { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 1rem; background: var(--surface-color); color: var(--text-primary); border: 1px solid var(--border-color); border-radius: 6px; font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: background 0.2s, border-color 0.2s; } .secondaryButton:hover { background: var(--bg-secondary); border-color: var(--text-secondary); } .googleButton { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 1rem; background: #4285f4; color: white; border: none; border-radius: 6px; font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: background 0.2s, transform 0.1s; } .googleButton:hover { background: #3367d6; } .googleButton:active { transform: scale(0.98); } .googleButton:disabled { opacity: 0.6; cursor: not-allowed; } .clickupButton { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 1rem; background: #7b68ee; color: white; border: none; border-radius: 6px; font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: background 0.2s, transform 0.1s; } .clickupButton:hover { background: #6a5acd; } .clickupButton:active { transform: scale(0.98); } .clickupButton:disabled { opacity: 0.6; cursor: not-allowed; } /* Filter Section Styles */ .filterSection { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-bottom: 1rem; flex-wrap: wrap; flex-shrink: 0; } .filterGroup { display: flex; align-items: center; gap: 0.75rem; } .filterLabel { display: flex; align-items: center; font-size: 0.875rem; font-weight: 500; color: var(--text-secondary); } .filterSelect { padding: 0.5rem 0.75rem; font-size: 0.875rem; border: 1px solid var(--border-color); border-radius: 6px; background: var(--bg-primary); color: var(--text-primary); min-width: 200px; cursor: pointer; } .filterSelect:focus { outline: none; border-color: var(--primary-color, #f25843); } /* Info Box */ .infoBox { display: flex; align-items: center; padding: 0.75rem 1rem; background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 6px; font-size: 0.875rem; color: var(--text-secondary); margin-bottom: 1rem; flex-shrink: 0; } .tableContainer { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; } .loadingContainer { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 3rem; color: var(--text-secondary); } .spinner { width: 32px; height: 32px; border: 3px solid var(--border-color); border-top-color: var(--primary-color, #f25843); border-radius: 50%; animation: spin 1s linear infinite; margin-bottom: 1rem; } @keyframes spin { to { transform: rotate(360deg); } } .errorContainer { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 3rem; color: var(--danger-color, #e53e3e); text-align: center; } .errorIcon { font-size: 2rem; margin-bottom: 0.75rem; } .errorMessage { margin: 0 0 1rem 0; } .emptyState { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 4rem 2rem; color: var(--text-secondary); text-align: center; } .emptyIcon { font-size: 3rem; margin-bottom: 1rem; opacity: 0.5; } .emptyTitle { font-size: 1.125rem; font-weight: 500; color: var(--text-primary); margin: 0 0 0.5rem 0; } .emptyDescription { margin: 0; max-width: 400px; } /* Modal Styles */ .modalOverlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; z-index: 1000; } .modal { background: var(--surface-color); border-radius: 12px; width: 90%; max-width: 600px; max-height: 90vh; overflow: hidden; display: flex; flex-direction: column; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); } .modalHeader { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.5rem; border-bottom: 1px solid var(--border-color); } .modalTitle { font-size: 1.125rem; font-weight: 600; color: var(--text-primary); margin: 0; } .modalClose { background: none; border: none; font-size: 1.25rem; color: var(--text-secondary); cursor: pointer; padding: 0.25rem; line-height: 1; transition: color 0.2s; } .modalClose:hover { color: var(--text-primary); } .modalContent { padding: 1.5rem; overflow-y: auto; flex: 1; } .modalFooter { display: flex; justify-content: flex-end; gap: 0.75rem; padding: 1rem 1.5rem; border-top: 1px solid var(--border-color); } /* Form Styles */ .formGroup { margin-bottom: 1.25rem; } .formLabel { display: block; font-size: 0.875rem; font-weight: 500; color: var(--text-primary); margin-bottom: 0.5rem; } .formInput { width: 100%; padding: 0.625rem 0.75rem; font-size: 0.875rem; border: 1px solid var(--border-color); border-radius: 6px; background: var(--bg-primary); color: var(--text-primary); transition: border-color 0.2s, box-shadow 0.2s; } .formInput:focus { outline: none; border-color: var(--primary-color, #f25843); box-shadow: 0 0 0 3px rgba(242, 88, 67, 0.1); } .formInput::placeholder { color: var(--text-tertiary); } .required::after { content: " *"; color: var(--danger-color, #e53e3e); } /* Badge */ .badge { display: inline-flex; align-items: center; padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.75rem; font-weight: 500; } /* Checkbox Label */ .checkboxLabel { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: var(--text-secondary); cursor: pointer; } .checkboxLabel input[type="checkbox"] { width: 1rem; height: 1rem; cursor: pointer; } /* URL Box */ .urlBox { display: flex; gap: 0.5rem; align-items: center; } .urlInput { flex: 1; padding: 0.75rem; font-size: 0.875rem; font-family: monospace; border: 1px solid var(--border-color); border-radius: 6px; background: var(--bg-secondary); color: var(--text-primary); } .urlInput:focus { outline: none; border-color: var(--primary-color, #f25843); } .copyButton { display: flex; align-items: center; gap: 0.375rem; padding: 0.75rem 1rem; background: var(--primary-color, #f25843); color: white; border: none; border-radius: 6px; font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: background 0.2s; white-space: nowrap; } .copyButton:hover { background: var(--primary-dark, #d94d3a); } /* Dark theme adjustments */ :global(.dark-theme) .modal { box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); } :global(.dark-theme) .modalOverlay { background: rgba(0, 0, 0, 0.7); } /* Danger button */ .dangerButton { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 1rem; background: #dc3545; color: white; border: none; border-radius: 6px; font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: background 0.2s; } .dangerButton:hover { background: #c82333; } /* Template list */ .templateList { display: flex; flex-direction: column; gap: 1rem; } .templateItem { border: 1px solid var(--border-color, #e0e0e0); padding: 1rem; border-radius: 8px; background: var(--bg-secondary, #f9f9f9); } .templateHeader { margin-bottom: 0.5rem; } .templateTitle { margin: 0; font-size: 1rem; font-weight: 600; color: var(--text-primary); } .templateDescription { margin: 0 0 1rem 0; font-size: 0.875rem; color: var(--text-secondary); } /* Execution status */ .executionStatus { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; padding: 0.75rem; background: var(--bg-secondary, #f9f9f9); border-radius: 6px; } .statusBadge { padding: 0.25rem 0.75rem; border-radius: 12px; font-size: 0.75rem; font-weight: 500; text-transform: uppercase; } .statusBadge.starting, .statusBadge.running { background: var(--primary-dark-bg, rgba(242, 88, 67, 0.12)); color: var(--primary-color, #F25843); } .statusBadge.completed { background: #e8f5e9; color: #388e3c; } .statusBadge.stopped { background: #fff3e0; color: #f57c00; } .statusBadge.error, .statusBadge.failed { background: #ffebee; color: #d32f2f; } .workflowId { font-size: 0.75rem; color: var(--text-secondary); } .workflowId code { background: var(--bg-tertiary, #eee); padding: 0.125rem 0.375rem; border-radius: 4px; font-family: monospace; } /* Execution logs */ .executionLogs { background: var(--bg-tertiary, #f5f5f5); border: 1px solid var(--border-color, #e0e0e0); border-radius: 6px; padding: 1rem; width: 100%; box-sizing: border-box; overflow-x: auto; } .logEntry { display: flex; flex-direction: row; flex-wrap: wrap; align-items: flex-start; gap: 0.5rem; padding: 0.25rem 0; border-bottom: 1px solid var(--border-color, #e0e0e0); width: 100%; min-width: 100%; box-sizing: border-box; } .logEntry:last-child { border-bottom: none; } .logTime { color: var(--text-secondary); flex: 0 0 auto; white-space: nowrap; } .logStatus { color: var(--primary-color, #F25843); } .logEntryError .logStatus, .logEntryError .logMessage { color: #d32f2f; } .logMessage { flex: 1 1 auto; min-width: 0; word-wrap: break-word; overflow-wrap: break-word; white-space: pre-wrap; } .logProgress { color: var(--text-secondary); flex: 0 0 auto; white-space: nowrap; } /* Logs history */ .logsHistory { display: flex; flex-direction: column; gap: 0.75rem; } .logHistoryItem { border: 1px solid var(--border-color, #e0e0e0); border-radius: 6px; padding: 0.75rem; background: var(--bg-secondary, #f9f9f9); } .logHistoryItem.completed { border-left: 3px solid #388e3c; } .logHistoryItem.error, .logHistoryItem.failed { border-left: 3px solid #d32f2f; } .logHistoryItem.stopped { border-left: 3px solid #f57c00; } .logHistoryHeader { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.5rem; flex-wrap: wrap; } .logHistoryDate { font-size: 0.875rem; color: var(--text-primary); font-weight: 500; } .logHistoryMessages { font-size: 0.8125rem; color: var(--text-secondary); } .logHistoryMessage { padding: 0.125rem 0; } /* Status icons */ .successIcon { color: #388e3c; } .errorIcon { color: #d32f2f; } .warningIcon { color: #f57c00; } .spinningIcon { animation: spin 1s linear infinite; } /* Empty actions */ .emptyActions { display: flex; gap: 0.75rem; margin-top: 1rem; } /* Spinning animation */ @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } :global(.spinning) { animation: spin 1s linear infinite; } @media (max-width: 1024px) { .pageHeader { align-items: flex-start; flex-direction: column; gap: 0.75rem; } .headerActions { width: 100%; flex-wrap: wrap; justify-content: flex-start; } .primaryButton, .secondaryButton, .dangerButton, .googleButton, .clickupButton { min-height: 40px; white-space: normal; } } /* ============================================== */ /* Role Permissions Page Styles */ /* ============================================== */ /* Scrollable Content Container */ .scrollableContent { flex: 1; overflow-y: auto; min-height: 0; display: flex; flex-direction: column; } /* Filter Bar */ .filterBar { display: flex; flex-wrap: wrap; gap: 1rem; margin-bottom: 1rem; flex-shrink: 0; } .filterGroup { display: flex; align-items: center; gap: 0.5rem; } .filterLabel { font-size: 0.875rem; color: var(--text-secondary); display: flex; align-items: center; } .filterSelect { padding: 0.5rem 0.75rem; border: 1px solid var(--border-color); border-radius: 6px; background: var(--bg-primary); color: var(--text-primary); font-size: 0.875rem; min-width: 150px; } .filterSelect:focus { outline: none; border-color: var(--primary-color); } /* ============================================== */ /* Chatbot Configuration Styles */ /* ============================================== */ .chatbotConfigSection { margin-top: 0; } .configSectionTitle { font-size: 1.125rem; font-weight: 600; color: var(--text-primary); margin: 0 0 1.5rem 0; } .configField { margin-bottom: 1.5rem; } .configLabel { display: block; font-size: 0.875rem; font-weight: 500; color: var(--text-primary); margin-bottom: 0.5rem; } .configSelect { width: 100%; max-width: 400px; } .configTextArea { width: 100%; min-height: 150px; font-family: 'Courier New', monospace; font-size: 0.875rem; line-height: 1.5; resize: vertical; } .configHelpText { font-size: 0.75rem; color: var(--text-secondary); margin-top: 0.5rem; font-style: italic; } /* Multiselect styles for chatbot connectors */ .multiselectContainer { padding: 0.75rem; border: 1px solid var(--border-color); border-radius: 6px; } .multiselectOption { display: flex; align-items: center; gap: 0.5rem; cursor: pointer; } .multiselectCheckbox { width: 18px; height: 18px; cursor: pointer; } .multiselectLabel { font-size: 0.875rem; user-select: none; } .rolesList { display: flex; flex-direction: column; gap: 1rem; flex: 1; overflow-y: auto; min-height: 0; padding-bottom: 1rem; } .roleCard { background: var(--bg-secondary, #ffffff); border: 1px solid var(--border-color, #e0e0e0); border-radius: 8px; overflow: hidden; } .roleHeader { display: flex; align-items: center; justify-content: space-between; padding: 1rem 1.25rem; cursor: pointer; transition: background-color 0.2s ease; } .roleHeader:hover { background: var(--bg-tertiary, #f8f9fa); } .roleInfo { display: flex; align-items: center; gap: 0.75rem; } .expandIcon { color: var(--text-secondary, #666); font-size: 0.75rem; } .roleLabel { font-weight: 600; color: var(--text-primary, #1a1a1a); } .roleDescription { color: var(--text-secondary, #666); font-size: 0.875rem; } .roleBadges { display: flex; gap: 0.5rem; } .roleContent { padding: 1rem 1.25rem; border-top: 1px solid var(--border-color, #e0e0e0); background: var(--bg-tertiary, #f8f9fa); } .accessOverviewSubheading { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-secondary, #666); margin: 1rem 0 0.5rem; } .accessOverviewSubheading:first-child { margin-top: 0; } .accessOverviewRoleBullets { margin: 0.25rem 0 0.85rem; padding-left: 1.25rem; font-size: 0.875rem; line-height: 1.55; } .accessOverviewInstanceStack { display: flex; flex-direction: column; gap: 0.5rem; } .accessOverviewInstanceBlock { padding: 0.75rem 1rem; background: var(--bg-secondary, #f5f5f5); border-radius: 6px; border: 1px solid var(--border-color, #e0e0e0); } .accessOverviewInstanceTitle { font-weight: 600; font-size: 0.9375rem; color: var(--text-primary, #1a1a1a); margin-bottom: 0.35rem; } .accessOverviewInstanceFeature { font-weight: 500; color: var(--text-secondary, #666); } .emptyHint { font-size: 0.875rem; color: var(--text-tertiary, #999); margin-top: 0.5rem; }