export function KnowledgeBaseTab()

in x-pack/platform/plugins/private/observability_ai_assistant_management/public/routes/components/knowledge_base_tab.tsx [62:397]


export function KnowledgeBaseTab() {
  const { uiSettings } = useKibana().services;
  const dateFormat = uiSettings.get('dateFormat');

  const knowledgeBase = useKnowledgeBase();
  const { euiTheme } = useEuiTheme();

  const columns: Array<EuiBasicTableColumn<KnowledgeBaseEntryCategory>> = [
    {
      align: 'right',
      width: '40px',
      isExpander: true,
      name: (
        <EuiScreenReaderOnly>
          <span>
            {i18n.translate('xpack.observabilityAiAssistantManagement.span.expandRowLabel', {
              defaultMessage: 'Expand row',
            })}
          </span>
        </EuiScreenReaderOnly>
      ),
      render: (category: KnowledgeBaseEntryCategory) => {
        return (
          <EuiButtonIcon
            data-test-subj="pluginsColumnsButton"
            onClick={() => setSelectedCategory(category)}
            aria-label={
              category.categoryKey === selectedCategory?.categoryKey ? 'Collapse' : 'Expand'
            }
            iconType={
              category.categoryKey === selectedCategory?.categoryKey ? 'minimize' : 'expand'
            }
          />
        );
      },
    },
    {
      field: '',
      name: '',
      render: (category: KnowledgeBaseEntryCategory) => {
        if (category.entries.length === 1 && category.entries[0].role === 'user_entry') {
          return <EuiIcon type="documentation" color="primary" />;
        }
        if (
          category.entries.length === 1 &&
          category.entries[0].role === 'assistant_summarization'
        ) {
          return <EuiIcon type="sparkles" color="primary" />;
        }

        return <EuiIcon type="logoElastic" />;
      },
      width: '40px',
    },
    {
      'data-test-subj': 'knowledgeBaseTableTitleCell',
      field: 'title',
      name: i18n.translate('xpack.observabilityAiAssistantManagement.kbTab.columns.name', {
        defaultMessage: 'Name',
      }),
      sortable: true,
    },
    {
      name: i18n.translate(
        'xpack.observabilityAiAssistantManagement.kbTab.columns.numberOfEntries',
        {
          defaultMessage: 'Number of entries',
        }
      ),
      width: '140px',
      render: (category: KnowledgeBaseEntryCategory) => {
        if (category.entries.length > 1 && category.entries[0].role === 'elastic') {
          return <EuiBadge>{category.entries.length}</EuiBadge>;
        }
        return null;
      },
    },
    {
      'data-test-subj': 'knowledgeBaseTableAuthorCell',
      name: i18n.translate('xpack.observabilityAiAssistantManagement.kbTab.columns.author', {
        defaultMessage: 'Author',
      }),
      width: '140px',
      render: (category: KnowledgeBaseEntryCategory) => {
        return category.entries[0]?.user?.name;
      },
    },
    {
      field: '@timestamp',
      name: i18n.translate('xpack.observabilityAiAssistantManagement.kbTab.columns.dateCreated', {
        defaultMessage: 'Date created',
      }),
      width: '140px',
      sortable: true,
      render: (timestamp: KnowledgeBaseEntry['@timestamp']) => (
        <EuiBadge color="hollow">{moment(timestamp).format(dateFormat)}</EuiBadge>
      ),
    },
    {
      name: i18n.translate('xpack.observabilityAiAssistantManagement.kbTab.columns.type', {
        defaultMessage: 'Type',
      }),
      width: '140px',
      render: (category: KnowledgeBaseEntryCategory) => {
        if (category.entries.length === 1 && category.entries[0].role === 'user_entry') {
          return (
            <EuiBadge color="hollow">
              {i18n.translate(
                'xpack.observabilityAiAssistantManagement.kbTab.columns.manualBadgeLabel',
                {
                  defaultMessage: 'Manual',
                }
              )}
            </EuiBadge>
          );
        }

        if (
          category.entries.length === 1 &&
          category.entries[0].role === 'assistant_summarization'
        ) {
          return (
            <EuiBadge color="hollow">
              {i18n.translate(
                'xpack.observabilityAiAssistantManagement.kbTab.columns.assistantSummarization',
                {
                  defaultMessage: 'Assistant',
                }
              )}
            </EuiBadge>
          );
        }

        return (
          <EuiBadge>
            {i18n.translate('xpack.observabilityAiAssistantManagement.columns.systemBadgeLabel', {
              defaultMessage: 'System',
            })}
          </EuiBadge>
        );
      },
    },
  ];

  const [selectedCategory, setSelectedCategory] = useState<
    KnowledgeBaseEntryCategory | undefined
  >();

  const [newEntryFlyoutType, setNewEntryFlyoutType] = useState<
    'singleEntry' | 'bulkImport' | undefined
  >();

  const [isNewEntryPopoverOpen, setIsNewEntryPopoverOpen] = useState(false);
  const [isEditUserInstructionFlyoutOpen, setIsEditUserInstructionFlyoutOpen] = useState(false);
  const [query, setQuery] = useState('');
  const [sortBy, setSortBy] = useState<keyof KnowledgeBaseEntryCategory>('title');
  const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc');

  const {
    entries = [],
    isLoading,
    refetch,
  } = useGetKnowledgeBaseEntries({
    query,
    sortBy,
    sortDirection,
    kbState: knowledgeBase.status.value?.kbState,
  });

  const categorizedEntries = categorizeEntries({ entries });

  const handleChangeSort = ({ sort }: Criteria<KnowledgeBaseEntryCategory>) => {
    if (sort) {
      const { field, direction } = sort;
      setSortBy(field);
      setSortDirection(direction);
    }
  };

  const handleChangeQuery = (e: React.ChangeEvent<HTMLInputElement> | undefined) => {
    setQuery(e?.currentTarget.value || '');
  };

  if (knowledgeBase.status.loading && !knowledgeBase.isPolling) {
    return (
      <EuiFlexGroup alignItems="center" direction="column">
        <EuiFlexItem grow>
          <EuiLoadingSpinner size="xl" data-test-subj="knowledgeBaseTabLoader" />
        </EuiFlexItem>
      </EuiFlexGroup>
    );
  }

  if (knowledgeBase.status.value?.kbState === KnowledgeBaseState.READY) {
    return (
      <>
        <EuiFlexGroup direction="column">
          <EuiFlexItem grow={false}>
            <EuiFlexGroup gutterSize="s">
              <EuiFlexItem grow>
                <EuiFieldSearch
                  data-test-subj="knowledgeBaseTabFieldSearch"
                  fullWidth
                  placeholder={i18n.translate(
                    'xpack.observabilityAiAssistantManagement.knowledgeBaseTab.euiFieldSearch.searchThisLabel',
                    { defaultMessage: 'Search for an entry' }
                  )}
                  value={query}
                  onChange={handleChangeQuery}
                  isClearable
                  aria-label={i18n.translate(
                    'xpack.observabilityAiAssistantManagement.knowledgeBaseTab.euiFieldSearch.searchEntriesLabel',
                    { defaultMessage: 'Search entries' }
                  )}
                />
              </EuiFlexItem>

              <EuiFlexItem grow={false}>
                <EuiButton
                  data-test-subj="knowledgeBaseTabReloadButton"
                  color="success"
                  iconType="refresh"
                  onClick={() => refetch()}
                >
                  {i18n.translate(
                    'xpack.observabilityAiAssistantManagement.knowledgeBaseTab.reloadButtonLabel',
                    { defaultMessage: 'Reload' }
                  )}
                </EuiButton>
              </EuiFlexItem>
              <EuiFlexItem grow={false}>
                <EuiButton
                  data-test-subj="observabilityAiAssistantManagementKnowledgeBaseTabEditInstructionsButton"
                  color="text"
                  onClick={() => setIsEditUserInstructionFlyoutOpen(true)}
                >
                  {i18n.translate(
                    'xpack.observabilityAiAssistantManagement.knowledgeBaseTab.editInstructionsButtonLabel',
                    { defaultMessage: 'Edit User-specific Prompt' }
                  )}
                </EuiButton>
              </EuiFlexItem>

              <EuiFlexItem grow={false}>
                <EuiPopover
                  isOpen={isNewEntryPopoverOpen}
                  closePopover={() => setIsNewEntryPopoverOpen(false)}
                  button={
                    <EuiButton
                      fill
                      data-test-subj="knowledgeBaseNewEntryButton"
                      iconSide="right"
                      iconType="arrowDown"
                      onClick={() => setIsNewEntryPopoverOpen((prevValue) => !prevValue)}
                    >
                      {i18n.translate(
                        'xpack.observabilityAiAssistantManagement.knowledgeBaseTab.newEntryButtonLabel',
                        {
                          defaultMessage: 'New entry',
                        }
                      )}
                    </EuiButton>
                  }
                >
                  <EuiContextMenuPanel
                    size="s"
                    items={[
                      <EuiContextMenuItem
                        key="singleEntry"
                        icon="document"
                        data-test-subj="knowledgeBaseSingleEntryContextMenuItem"
                        onClick={() => {
                          setIsNewEntryPopoverOpen(false);
                          setNewEntryFlyoutType('singleEntry');
                        }}
                        size="s"
                      >
                        {i18n.translate(
                          'xpack.observabilityAiAssistantManagement.knowledgeBaseTab.singleEntryContextMenuItemLabel',
                          { defaultMessage: 'Single entry' }
                        )}
                      </EuiContextMenuItem>,
                      <EuiContextMenuItem
                        key="bulkImport"
                        icon="documents"
                        data-test-subj="knowledgeBaseBulkImportContextMenuItem"
                        onClick={() => {
                          setIsNewEntryPopoverOpen(false);
                          setNewEntryFlyoutType('bulkImport');
                        }}
                      >
                        {i18n.translate(
                          'xpack.observabilityAiAssistantManagement.knowledgeBaseTab.bulkImportContextMenuItemLabel',
                          { defaultMessage: 'Bulk import' }
                        )}
                      </EuiContextMenuItem>,
                    ]}
                  />
                </EuiPopover>
              </EuiFlexItem>
            </EuiFlexGroup>
          </EuiFlexItem>

          <EuiFlexItem grow={false}>
            <EuiBasicTable<KnowledgeBaseEntryCategory>
              data-test-subj="knowledgeBaseTable"
              columns={columns}
              items={categorizedEntries}
              loading={isLoading}
              sorting={{
                sort: {
                  field: sortBy,
                  direction: sortDirection,
                },
              }}
              rowProps={(row) => ({
                onClick: () => setSelectedCategory(row),
              })}
              onChange={handleChangeSort}
            />
          </EuiFlexItem>
        </EuiFlexGroup>

        {isEditUserInstructionFlyoutOpen ? (
          <KnowledgeBaseEditUserInstructionFlyout
            onClose={() => setIsEditUserInstructionFlyoutOpen(false)}
          />
        ) : null}

        {newEntryFlyoutType === 'singleEntry' ? (
          <KnowledgeBaseEditManualEntryFlyout onClose={() => setNewEntryFlyoutType(undefined)} />
        ) : null}

        {newEntryFlyoutType === 'bulkImport' ? (
          <KnowledgeBaseBulkImportFlyout onClose={() => setNewEntryFlyoutType(undefined)} />
        ) : null}