← back to centy-io__centy-app

Function bodies 471 total

All specs Real LLM only Function bodies
getTypeLabel function · typescript · L33-L40 (8 LOC)
components/project/PinnedItemCard.tsx
function getTypeLabel(type: PinnedItem['type']): string {
  switch (type) {
    case 'issue':
      return 'Issue'
    case 'doc':
      return 'Doc'
  }
}
PinnedItemCard function · typescript · L42-L87 (46 LOC)
components/project/PinnedItemCard.tsx
export function PinnedItemCard({
  item,
  isDragging,
  onDragStart,
  onDragOver,
  onDragEnd,
  onUnpin,
}: PinnedItemCardProps) {
  const { createLink } = useAppLink()
  const href = getItemHref(item, createLink)

  return (
    <div
      className={`pinned-item-card ${isDragging ? 'dragging' : ''}`}
      draggable
      onDragStart={onDragStart}
      onDragOver={onDragOver}
      onDragEnd={onDragEnd}
    >
      <div className="pinned-item-drag-handle" title="Drag to reorder">
        <span className="drag-handle-line"></span>
        <span className="drag-handle-line"></span>
        <span className="drag-handle-line"></span>
      </div>
      <span className={getTypeBadgeClass(item.type)}>
        {getTypeLabel(item.type)}
      </span>
      <div className="pinned-item-content">
        <Link href={href} className="pinned-item-link">
          {item.title}
        </Link>
        {item.displayNumber != null && (
          <div className="pinned-item-number">#{item.displayN
PinnedItemsSection function · typescript · L13-L68 (56 LOC)
components/project/PinnedItemsSection.tsx
export function PinnedItemsSection({
  items,
  onUnpin,
  onReorder,
}: PinnedItemsSectionProps) {
  const [draggedIndex, setDraggedIndex] = useState<number | null>(null)

  const handleDragStart = (index: number) => {
    setDraggedIndex(index)
  }

  const handleDragOver = (e: React.DragEvent, index: number) => {
    e.preventDefault()
    if (draggedIndex === null || draggedIndex === index) return
    onReorder(draggedIndex, index)
    setDraggedIndex(index)
  }

  const handleDragEnd = () => {
    setDraggedIndex(null)
  }

  return (
    <div className="pinned-items-section">
      <div className="pinned-items-header">
        <h2 className="pinned-items-title">Pinned</h2>
        {items.length > 0 && (
          <span className="pinned-items-count">{items.length}</span>
        )}
      </div>

      {items.length === 0 ? (
        <div className="pinned-items-empty">
          <p className="pinned-items-empty-text">No pinned items yet</p>
          <p className="pinned-items-hi
ProjectDashboard function · typescript · L9-L71 (63 LOC)
components/project/ProjectDashboard.tsx
export function ProjectDashboard() {
  const { projectName, isInitialized, isLoading, displayPath } =
    usePathContext()
  const { createLink } = useAppLink()
  const { pinnedItems, unpinItem, reorderItems } = usePinnedItems()

  if (isLoading) {
    return (
      <div className="project-dashboard-loading">
        <p className="dashboard-loading-text">Loading project...</p>
      </div>
    )
  }

  if (isInitialized === false) {
    return (
      <div className="project-dashboard-not-initialized">
        <p className="not-initialized-text">
          Centy is not initialized in this directory
        </p>
        <Link href={createLink('/')}>Initialize Project</Link>
      </div>
    )
  }

  return (
    <div className="project-dashboard">
      <div className="project-dashboard-header">
        <h1 className="project-dashboard-title">{projectName}</h1>
        {displayPath && (
          <div className="project-dashboard-path">{displayPath}</div>
        )}
      </div>

     
ProjectFlatList function · typescript · L16-L44 (29 LOC)
components/project/ProjectSelector/ProjectFlatList.tsx
export function ProjectFlatList({
  projects,
  projectPath,
  onSelect,
  onToggleFavorite,
  onArchive,
  onFocusSearch,
}: ProjectFlatListProps) {
  return (
    <ul
      id="project-listbox"
      className="project-list"
      role="listbox"
      aria-label="Projects"
      onKeyDown={makeListKeyboardHandler(onFocusSearch)}
    >
      {projects.map(project => (
        <ProjectItem
          key={project.path}
          project={project}
          isSelected={project.path === projectPath}
          onSelect={onSelect}
          onToggleFavorite={onToggleFavorite}
          onArchive={onArchive}
        />
      ))}
    </ul>
  )
}
ProjectGroupList function · typescript · L19-L79 (61 LOC)
components/project/ProjectSelector/ProjectGroupList.tsx
export function ProjectGroupList({
  groupedProjects,
  projectPath,
  collapsedOrgs,
  toggleOrgCollapse,
  onSelect,
  onToggleFavorite,
  onArchive,
  onFocusSearch,
}: ProjectGroupListProps) {
  return (
    <div
      id="project-listbox"
      className="project-list-grouped"
      role="listbox"
      aria-label="Projects"
      onKeyDown={makeListKeyboardHandler(onFocusSearch)}
    >
      {groupedProjects.map(([orgSlug, group]) => {
        const isCollapsed = collapsedOrgs.has(orgSlug)
        return (
          <div key={orgSlug || '__ungrouped'} className="project-group">
            <button
              className="project-group-header"
              onClick={() => toggleOrgCollapse(orgSlug)}
              aria-expanded={!isCollapsed}
            >
              <span
                className={`project-group-chevron ${isCollapsed ? 'collapsed' : ''}`}
              >
                {'\u25BC'}
              </span>
              <span className="project-group-name">
     
ProjectItem function · typescript · L17-L79 (63 LOC)
components/project/ProjectSelector/ProjectItem.tsx
export function ProjectItem({
  project,
  isSelected,
  onSelect,
  onToggleFavorite,
  onArchive,
}: ProjectItemProps) {
  return (
    <li
      id={toOptionId(project.path)}
      role="option"
      aria-selected={isSelected}
      tabIndex={0}
      className={`project-item ${isSelected ? 'selected' : ''}`}
      onClick={() => onSelect(project)}
      onKeyDown={e => {
        if (e.key !== 'Enter' && e.key !== ' ') return
        e.preventDefault()
        onSelect(project)
      }}
    >
      <div className="project-item-main">
        <button
          className={`favorite-btn ${project.isFavorite ? 'active' : ''}`}
          onClick={e => onToggleFavorite(e, project)}
          title={
            project.isFavorite ? 'Remove from favorites' : 'Add to favorites'
          }
        >
          {project.isFavorite ? '\u2605' : '\u2606'}
        </button>
        <span className="project-item-name">{project.name}</span>
        {!project.initialized && (
          <span class
Powered by Repobility — scan your code at https://repobility.com
ProjectSelectorDropdown function · typescript · L33-L103 (71 LOC)
components/project/ProjectSelector/ProjectSelectorDropdown.tsx
export function ProjectSelectorDropdown(props: ProjectSelectorDropdownProps) {
  const {
    loading,
    error,
    searchQuery,
    setSearchQuery,
    searchInputRef,
    visibleProjects,
    groupedProjects,
    projectPath,
    collapsedOrgs,
    manualPath,
    setManualPath,
    fetchProjects,
    setIsOpen,
    handleSelectProject,
    handleManualSubmit,
    handleToggleFavorite,
    handleArchiveProject,
    toggleOrgCollapse,
  } = props

  const focusSearch = () => {
    if (searchInputRef.current) searchInputRef.current.focus()
  }

  return (
    <>
      <ProjectSelectorHeader loading={loading} onRefresh={fetchProjects} />
      <ProjectSelectorSearch
        searchQuery={searchQuery}
        setSearchQuery={setSearchQuery}
        searchInputRef={searchInputRef}
      />
      {error && <div className="project-selector-error">{error}</div>}
      <div className="project-selector-list-area">
        {loading ? (
          <div className="project-selector-loading">Loading
ProjectSelectorEmptyState function · typescript · L7-L27 (21 LOC)
components/project/ProjectSelector/ProjectSelectorEmptyState.tsx
export function ProjectSelectorEmptyState({
  searchQuery,
}: ProjectSelectorEmptyStateProps) {
  return (
    <div className="project-selector-empty">
      {searchQuery ? (
        <>
          <p className="empty-state-text">
            No projects match &quot;{searchQuery}&quot;
          </p>
          <p className="hint">Try a different search term</p>
        </>
      ) : (
        <>
          <p className="empty-state-text">No tracked projects found</p>
          <p className="hint">Initialize a project with Centy to see it here</p>
        </>
      )}
    </div>
  )
}
ProjectSelectorFooter function · typescript · L13-L57 (45 LOC)
components/project/ProjectSelector/ProjectSelectorFooter.tsx
export function ProjectSelectorFooter({
  manualPath,
  setManualPath,
  onManualSubmit,
  setIsOpen,
}: ProjectSelectorFooterProps) {
  return (
    <>
      <div className="project-selector-actions">
        <Link
          href={route({ pathname: '/' })}
          className="init-project-btn"
          onClick={() => setIsOpen(false)}
        >
          {'\u2728'} Init Project
        </Link>
        <Link
          href={route({ pathname: '/archived' })}
          className="view-archived-link"
          onClick={() => setIsOpen(false)}
        >
          View Archived Projects
        </Link>
      </div>
      <div className="project-selector-manual">
        <form className="manual-path-form" onSubmit={onManualSubmit}>
          <input
            type="text"
            value={manualPath}
            onChange={e => setManualPath(e.target.value)}
            placeholder="Or enter path manually..."
            className="manual-path-input"
          />
          <button
       
ProjectSelectorHeader function · typescript · L8-L25 (18 LOC)
components/project/ProjectSelector/ProjectSelectorHeader.tsx
export function ProjectSelectorHeader({
  loading,
  onRefresh,
}: ProjectSelectorHeaderProps) {
  return (
    <div className="project-selector-header">
      <h3 className="project-selector-title">Select Project</h3>
      <button
        className="refresh-btn"
        onClick={onRefresh}
        disabled={loading}
        title="Refresh project list"
      >
        {'\u21BB'}
      </button>
    </div>
  )
}
ProjectSelectorSearch function · typescript · L11-L52 (42 LOC)
components/project/ProjectSelector/ProjectSelectorSearch.tsx
export function ProjectSelectorSearch({
  searchQuery,
  setSearchQuery,
  searchInputRef,
}: ProjectSelectorSearchProps) {
  const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
    if (e.key !== 'ArrowDown') return
    e.preventDefault()
    const firstItem = document.querySelector<HTMLElement>(
      '#project-listbox [role="option"]'
    )
    if (firstItem) firstItem.focus()
  }

  return (
    <div className="project-selector-search">
      <input
        ref={searchInputRef}
        role="combobox"
        aria-expanded="true"
        aria-controls="project-listbox"
        aria-autocomplete="list"
        aria-label="Search projects"
        type="text"
        value={searchQuery}
        onChange={e => setSearchQuery(e.target.value)}
        onKeyDown={handleKeyDown}
        placeholder="Search projects..."
        className="search-input"
      />
      {searchQuery && (
        <button
          className="search-clear-btn"
          onClick={() => setSearchQuery(
ProjectSelector function · typescript · L12-L66 (55 LOC)
components/project/ProjectSelector/ProjectSelector.tsx
export function ProjectSelector() {
  const state = useProjectSelector()

  return (
    <PopoverRoot open={state.isOpen} onOpenChange={state.setIsOpen}>
      <PopoverTrigger asChild>
        <button
          className="project-selector-trigger"
          aria-haspopup="listbox"
          aria-expanded={state.isOpen}
          aria-controls="project-listbox"
        >
          <span className="project-icon">{'\uD83D\uDCC1'}</span>
          <span className="project-name">{state.getCurrentProjectName()}</span>
          <span className="dropdown-arrow">
            {state.isOpen ? '\u25B2' : '\u25BC'}
          </span>
        </button>
      </PopoverTrigger>
      <PopoverPortal>
        <PopoverContent
          className="project-selector-dropdown"
          align="start"
          sideOffset={4}
          onOpenAutoFocus={e => {
            e.preventDefault()
            if (state.searchInputRef.current)
              state.searchInputRef.current.focus()
          }}
        >
 
makeListKeyboardHandler function · typescript · L9-L31 (23 LOC)
components/project/ProjectSelector/useListKeyboardNav.ts
export function makeListKeyboardHandler(onFocusSearch: () => void) {
  return (e: KeyboardEvent<HTMLElement>) => {
    const items = Array.from(
      e.currentTarget.querySelectorAll<HTMLElement>('[role="option"]')
    )
    const activeEl = document.activeElement
    const idx = activeEl instanceof HTMLElement ? items.indexOf(activeEl) : -1

    if (e.key === 'ArrowDown') {
      e.preventDefault()
      const next = items[idx === -1 ? 0 : Math.min(idx + 1, items.length - 1)]
      if (next) next.focus()
    } else if (e.key === 'ArrowUp') {
      e.preventDefault()
      if (idx <= 0) {
        onFocusSearch()
      } else {
        const prev = items[idx - 1]
        if (prev) prev.focus()
      }
    }
  }
}
useProjectActions function · typescript · L31-L135 (105 LOC)
components/project/ProjectSelector/useProjectActions.ts
export function useProjectActions(params: UseProjectActionsParams) {
  const router = useRouter()
  const routeParams = useParams()
  const pathname = usePathname()
  const { projectPath, setProjectPath, setIsInitialized } = useProject()
  const { archiveProject } = useArchivedProjects()

  const getCurrentPage = useCallback(() => {
    const orgP = routeParams ? routeParams.organization : undefined
    const org = typeof orgP === 'string' ? orgP : undefined
    const projP = routeParams ? routeParams.project : undefined
    const proj = typeof projP === 'string' ? projP : undefined
    const segments = pathname.split('/').filter(Boolean)
    if (org && proj) return segments[2] || 'issues'
    if (segments.length >= 2 && !ROOT_ROUTES.has(segments[0]))
      return segments[2] || 'issues'
    return segments[0] || 'issues'
  }, [routeParams, pathname])

  const handleSelectProject = (project: ProjectInfo) => {
    const orgSlug = project.organizationSlug || UNGROUPED_ORG_MARKER
    cons
Open data scored by Repobility · https://repobility.com
useProjectSelector function · typescript · L17-L141 (125 LOC)
components/project/ProjectSelector/useProjectSelector.ts
export function useProjectSelector() {
  const { isArchived } = useArchivedProjects()
  const { selectedOrgSlug, organizations } = useOrganization()
  const [projects, setProjects] = useState<ProjectInfo[]>([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [isOpen, setIsOpen] = useState(false)
  const [manualPath, setManualPath] = useState('')
  const [searchQuery, setSearchQuery] = useState('')
  const [collapsedOrgs, setCollapsedOrgs] = useState<Set<string>>(() => {
    if (typeof window === 'undefined') return new Set()
    try {
      const s = localStorage.getItem(COLLAPSED_ORGS_KEY)
      return s ? new Set(JSON.parse(s)) : new Set()
    } catch {
      return new Set()
    }
  })
  const searchInputRef = useRef<HTMLInputElement>(null)

  const actions = useProjectActions({
    projects,
    setProjects,
    setIsOpen,
    setSearchQuery,
    setManualPath,
    manualPath,
  })

  const fetchProjects = useCallbac
groupProjects function · typescript · L7-L45 (39 LOC)
components/project/ProjectsGrid/groupProjects.ts
export function groupProjects(
  projects: ProjectInfo[],
  organizations: Organization[]
): GroupedProject[] {
  const groups: Map<string, { name: string; projects: ProjectInfo[] }> =
    new Map()

  groups.set('', { name: 'Ungrouped', projects: [] })

  for (const project of projects) {
    const orgSlug = project.organizationSlug || ''
    if (!groups.has(orgSlug)) {
      const org = organizations.find(o => o.slug === orgSlug)
      groups.set(orgSlug, {
        name: (org ? org.name : '') || orgSlug,
        projects: [],
      })
    }
    groups.get(orgSlug)!.projects.push(project)
  }

  const sortedGroups = Array.from(groups.entries())
    .filter(([, g]) => g.projects.length > 0)
    .sort(([slugA], [slugB]) => {
      if (slugA === '' && slugB !== '') return 1
      if (slugA !== '' && slugB === '') return -1
      return slugA.localeCompare(slugB)
    })

  sortedGroups.forEach(([, group]) => {
    group.projects.sort((a, b) => {
      if (a.isFavorite && !b.isFavorite) re
OrgGroup function · typescript · L14-L54 (41 LOC)
components/project/ProjectsGrid/OrgGroup.tsx
export function OrgGroup({
  orgSlug,
  groupName,
  projects,
  onProjectClick,
  onToggleFavorite,
}: OrgGroupProps) {
  return (
    <div className="project-org-group">
      <div className="org-group-header">
        <h2 className="org-group-title">
          {orgSlug ? (
            <>
              <span className="org-icon">{'\uD83C\uDFE2'}</span>
              {groupName}
            </>
          ) : (
            <>
              <span className="org-icon">{'\uD83D\uDCC1'}</span>
              {groupName}
            </>
          )}
        </h2>
        <span className="org-project-count">{projects.length}</span>
      </div>

      <div className="projects-grid">
        {projects.map(project => (
          <ProjectCard
            key={project.path}
            project={project}
            orgSlug={orgSlug}
            orgName={groupName}
            onClick={() => onProjectClick(project)}
            onToggleFavorite={onToggleFavorite}
          />
        ))}
      </d
ProjectCard function · typescript · L13-L69 (57 LOC)
components/project/ProjectsGrid/ProjectCard.tsx
export function ProjectCard({
  project,
  orgSlug,
  orgName,
  onClick,
  onToggleFavorite,
}: ProjectCardProps) {
  return (
    <div className="project-card" onClick={onClick}>
      <div className="project-card-header">
        <h3 className="project-name">{project.name}</h3>
        <button
          className={`favorite-btn ${project.isFavorite ? 'active' : ''}`}
          onClick={e => onToggleFavorite(e, project)}
          title={
            project.isFavorite ? 'Remove from favorites' : 'Add to favorites'
          }
        >
          {project.isFavorite ? '\u2605' : '\u2606'}
        </button>
      </div>

      <div className="project-badges">
        {orgSlug && (
          <span
            className="project-badge org-badge"
            title={`Organization: ${orgName}`}
          >
            {'\uD83C\uDFE2'} {orgName}
          </span>
        )}
        {!project.initialized && (
          <span className="project-badge not-initialized">Not initialized</span>
  
ProjectsGridContent function · typescript · L16-L66 (51 LOC)
components/project/ProjectsGrid/ProjectsGridContent.tsx
export function ProjectsGridContent({
  fetchData,
  groupedProjects,
  onProjectClick,
  onToggleFavorite,
}: ProjectsGridContentProps) {
  return (
    <div className="projects-grid-container">
      <div className="projects-grid-header">
        <h1 className="projects-grid-title">Projects</h1>
        <div className="projects-grid-actions">
          <button onClick={fetchData} className="refresh-btn">
            Refresh
          </button>
          <Link
            href={route({ pathname: '/project/init' })}
            className="init-project-btn"
          >
            + Init Project
          </Link>
          <Link
            href={route({ pathname: '/organizations/new' })}
            className="create-org-btn"
          >
            + New Organization
          </Link>
        </div>
      </div>

      {groupedProjects.map(([orgSlug, group]) => (
        <OrgGroup
          key={orgSlug || '__ungrouped'}
          orgSlug={orgSlug}
          groupName={group.name}
   
ProjectsGrid function · typescript · L11-L80 (70 LOC)
components/project/ProjectsGrid/ProjectsGrid.tsx
export function ProjectsGrid() {
  const router = useRouter()
  const {
    projects,
    loading,
    error,
    fetchData,
    handleToggleFavorite,
    groupedProjects,
  } = useProjectsData()

  const handleProjectClick = (project: ProjectInfo) => {
    const orgSlug = project.organizationSlug || UNGROUPED_ORG_MARKER
    router.push(
      route({
        pathname: '/[organization]/[project]/issues',
        query: {
          organization: orgSlug,
          project: project.name,
        },
      })
    )
  }

  if (loading) {
    return (
      <div className="projects-grid-loading">
        <p className="projects-grid-loading-text">Loading projects...</p>
      </div>
    )
  }

  if (error) {
    return (
      <div className="projects-grid-error">
        <p className="projects-grid-error-text">Error: {error}</p>
        <button onClick={fetchData} className="retry-btn">
          Retry
        </button>
      </div>
    )
  }

  if (projects.length === 0) {
    return (
    
useProjectsData function · typescript · L17-L95 (79 LOC)
components/project/ProjectsGrid/useProjectsData.ts
export function useProjectsData() {
  const { selectedOrgSlug } = useOrganization()
  const [projects, setProjects] = useState<ProjectInfo[]>([])
  const [organizations, setOrganizations] = useState<Organization[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  const fetchData = useCallback(async () => {
    setLoading(true)
    setError(null)

    try {
      const [projectsResponse, orgsResponse] = await Promise.all([
        centyClient.listProjects(
          create(ListProjectsRequestSchema, {
            includeStale: false,
          })
        ),
        centyClient.listOrganizations(
          create(ListOrganizationsRequestSchema, {})
        ),
      ])

      setProjects(projectsResponse.projects)
      setOrganizations(orgsResponse.organizations)
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load data')
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(()
AutoFieldRenderer function · typescript · L20-L89 (70 LOC)
components/proto-form/AutoFieldRenderer.tsx
export function AutoFieldRenderer({
  field,
  label,
  description,
  value,
  onChange,
  ProtoFormRenderer,
}: AutoFieldRendererProps) {
  if (field.fieldKind === 'scalar') {
    return (
      <ScalarFieldRenderer
        scalar={field.scalar}
        label={label}
        description={description}
        value={value}
        onChange={onChange}
      />
    )
  }

  if (field.fieldKind === 'map') {
    return (
      <MapFieldRenderer
        label={label}
        description={description}
        value={value}
        onChange={onChange}
      />
    )
  }

  if (field.fieldKind === 'list') {
    return renderListField(field, {
      label,
      description,
      value,
      onChange,
      ProtoFormRenderer,
    })
  }

  if (field.fieldKind === 'message') {
    return (
      <MessageFieldRenderer
        messageDesc={field.message}
        label={label}
        description={description}
        value={value}
        onChange={onChange}
        ProtoFormRenderer={ProtoForm
Repobility analyzer · published findings · https://repobility.com
ProtoFormRenderer function · typescript · L17-L80 (64 LOC)
components/proto-form/ProtoFormRenderer.tsx
export function ProtoFormRenderer({
  schema,
  value,
  onChange,
  fieldGroups,
  fieldOverrides,
}: ProtoFormRendererProps) {
  const groups =
    fieldGroups !== null && fieldGroups !== undefined ? fieldGroups : []
  const overrides =
    fieldOverrides !== null && fieldOverrides !== undefined
      ? fieldOverrides
      : {}

  const claimedFields = new Set<string>()
  for (const group of groups) {
    for (const f of group.claimedFields) {
      claimedFields.add(f)
    }
  }
  for (const [localName, override] of Object.entries(overrides)) {
    if (override.hidden === true) claimedFields.add(localName)
  }

  const sortedGroups = [...groups].sort((a, b) => a.order - b.order)
  const unclaimedFields = schema.fields.filter(
    f => !claimedFields.has(f.localName)
  )

  return (
    <>
      {sortedGroups.map(group => (
        <section key={group.key} className="settings-section">
          <h3 className="settings-section-title">{group.title}</h3>
          <div className="sett
ListFieldRenderer function · typescript · L8-L81 (74 LOC)
components/proto-form/renderers/ListFieldRenderer.tsx
export function ListFieldRenderer({
  label,
  description,
  value,
  onChange,
}: ListFieldProps) {
  const rawItems = value !== null && value !== undefined ? value : []
  const items = Array.isArray(rawItems) ? rawItems : []
  const [newItem, setNewItem] = useState('')

  const handleAdd = () => {
    if (!newItem.trim()) return
    onChange([...items, newItem.trim()])
    setNewItem('')
  }

  const handleRemove = (index: number) => {
    onChange(items.filter((_, i) => i !== index))
  }

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key !== 'Enter') return
    e.preventDefault()
    handleAdd()
  }

  return (
    <div className="proto-form-field">
      <label className="proto-form-field-label">{label}</label>
      {description && (
        <p className="proto-form-field-description">{description}</p>
      )}

      {items.length > 0 && (
        <div className="proto-form-tags">
          {items.map((item, i) => (
            <span key={i} className="proto-fo
MapAddRow function · typescript · L13-L50 (38 LOC)
components/proto-form/renderers/MapAddRow.tsx
export function MapAddRow({
  newKey,
  newValue,
  isKeyTaken,
  onKeyChange,
  onValueChange,
  onKeyDown,
  onAdd,
}: MapAddRowProps) {
  return (
    <div className="proto-form-add-row">
      <input
        type="text"
        className="proto-form-input proto-form-map-key-input"
        value={newKey}
        onChange={e => onKeyChange(e.target.value)}
        onKeyDown={onKeyDown}
        placeholder="Key"
      />
      <input
        type="text"
        className="proto-form-input proto-form-map-add-value-input"
        value={newValue}
        onChange={e => onValueChange(e.target.value)}
        onKeyDown={onKeyDown}
        placeholder="Value"
      />
      <button
        type="button"
        className="proto-form-add-btn"
        onClick={onAdd}
        disabled={!newKey.trim() || isKeyTaken}
      >
        Add
      </button>
    </div>
  )
}
MapEntriesTable function · typescript · L9-L50 (42 LOC)
components/proto-form/renderers/MapEntriesTable.tsx
export function MapEntriesTable({
  entries,
  onValueChange,
  onRemove,
}: MapEntriesTableProps) {
  return (
    <table className="proto-form-map-table">
      <thead className="proto-form-map-thead">
        <tr className="proto-form-map-header-row">
          <th className="proto-form-map-th">Key</th>
          <th className="proto-form-map-th">Value</th>
          <th className="proto-form-map-th-action" />
        </tr>
      </thead>
      <tbody className="proto-form-map-tbody">
        {entries.map(([k, v]) => (
          <tr key={k} className="proto-form-map-row">
            <td className="proto-form-map-key">{k}</td>
            <td className="proto-form-map-value-cell">
              <input
                type="text"
                className="proto-form-input proto-form-map-value-input"
                value={String(v !== null && v !== undefined ? v : '')}
                onChange={e => onValueChange(k, e.target.value)}
              />
            </td>
            <td
toMap function · typescript · L13-L25 (13 LOC)
components/proto-form/renderers/MapFieldRenderer.tsx
function toMap(v: unknown): Record<string, unknown> {
  if (
    v !== null &&
    v !== undefined &&
    typeof v === 'object' &&
    !Array.isArray(v)
  ) {
    const result: Record<string, unknown> = {}
    Object.assign(result, v)
    return result
  }
  return {}
}
MapFieldRenderer function · typescript · L27-L81 (55 LOC)
components/proto-form/renderers/MapFieldRenderer.tsx
export function MapFieldRenderer({
  label,
  description,
  value,
  onChange,
}: MapFieldProps) {
  const map = toMap(value)
  const entries = Object.entries(map)
  const [newKey, setNewKey] = useState('')
  const [newValue, setNewValue] = useState('')

  const handleAdd = () => {
    if (!newKey.trim() || map[newKey.trim()] !== undefined) return
    onChange({ ...map, [newKey.trim()]: newValue })
    setNewKey('')
    setNewValue('')
  }

  const handleRemove = (key: string) => {
    const entries = Object.entries(map).filter(([k]) => k !== key)
    onChange(Object.fromEntries(entries))
  }

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key !== 'Enter') return
    e.preventDefault()
    handleAdd()
  }

  return (
    <div className="proto-form-field">
      <label className="proto-form-field-label">{label}</label>
      {description && (
        <p className="proto-form-field-description">{description}</p>
      )}
      {entries.length > 0 && (
        <MapEntrie
toRecord function · typescript · L16-L28 (13 LOC)
components/proto-form/renderers/MessageFieldRenderer.tsx
function toRecord(v: unknown): Record<string, unknown> {
  if (
    v !== null &&
    v !== undefined &&
    typeof v === 'object' &&
    !Array.isArray(v)
  ) {
    const result: Record<string, unknown> = {}
    Object.assign(result, v)
    return result
  }
  return {}
}
MessageFieldRenderer function · typescript · L30-L60 (31 LOC)
components/proto-form/renderers/MessageFieldRenderer.tsx
export function MessageFieldRenderer({
  messageDesc,
  label,
  description,
  value,
  onChange,
  ProtoFormRenderer,
}: MessageFieldProps) {
  const msgValue = toRecord(value)

  return (
    <div className="proto-form-field">
      <label className="proto-form-field-label">{label}</label>
      {description && (
        <p className="proto-form-field-description">{description}</p>
      )}
      <div className="proto-form-nested">
        <ProtoFormRenderer
          schema={messageDesc}
          value={msgValue}
          onChange={updates =>
            onChange({
              ...msgValue,
              ...updates,
            })
          }
        />
      </div>
    </div>
  )
}
About: code-quality intelligence by Repobility · https://repobility.com
MessageItem function · typescript · L21-L65 (45 LOC)
components/proto-form/renderers/MessageItem.tsx
export function MessageItem({
  item,
  index,
  messageName,
  isExpanded,
  onToggle,
  onRemove,
  onItemChange,
  messageDesc,
  ProtoFormRenderer,
}: MessageItemProps) {
  return (
    <div className="proto-form-message-item">
      <div className="proto-form-message-item-header">
        <button
          type="button"
          className="proto-form-message-item-toggle"
          onClick={() => onToggle(index)}
        >
          <span className="proto-form-message-item-arrow">
            {isExpanded ? '▾' : '▸'}
          </span>
          {`${messageName} ${index + 1}`}
        </button>
        <button
          type="button"
          className="proto-form-remove-btn"
          onClick={() => onRemove(index)}
          aria-label={`Remove item ${index + 1}`}
        >
          ×
        </button>
      </div>
      {isExpanded && (
        <div className="proto-form-message-item-body">
          <ProtoFormRenderer
            schema={messageDesc}
            value={item}
toRecordArray function · typescript · L8-L19 (12 LOC)
components/proto-form/renderers/MessageListFieldRenderer.tsx
function toRecordArray(v: unknown): Record<string, unknown>[] {
  if (Array.isArray(v)) {
    return v.filter(
      item =>
        item !== null &&
        item !== undefined &&
        typeof item === 'object' &&
        !Array.isArray(item)
    )
  }
  return []
}
MessageListFieldRenderer function · typescript · L22-L105 (84 LOC)
components/proto-form/renderers/MessageListFieldRenderer.tsx
export function MessageListFieldRenderer({
  messageDesc,
  label,
  description,
  value,
  onChange,
  ProtoFormRenderer,
}: MessageListFieldProps) {
  const items = toRecordArray(value)
  const [expanded, setExpanded] = useState<Set<number>>(new Set())

  const handleAdd = () => {
    const newItem: Record<string, unknown> = {}
    Object.assign(newItem, create(messageDesc))
    const next = [...items, newItem]
    onChange(next)
    setExpanded(prev => new Set([...prev, next.length - 1]))
  }

  const handleRemove = (index: number) => {
    onChange(items.filter((_, i) => i !== index))
    setExpanded(
      prev =>
        new Set(
          Array.from(prev)
            .filter(i => i !== index)
            .map(i => (i > index ? i - 1 : i))
        )
    )
  }

  const handleItemChange = (
    index: number,
    updates: Record<string, unknown>
  ) => {
    onChange(
      items.map((item, i) => (i === index ? { ...item, ...updates } : item))
    )
  }

  const toggleExpanded = (
NumericField function · typescript · L11-L45 (35 LOC)
components/proto-form/renderers/NumericField.tsx
export function NumericField({
  label,
  description,
  value,
  is64bit,
  onChange,
}: NumericFieldProps) {
  const displayValue = is64bit
    ? String(value !== null && value !== undefined ? value : '')
    : value !== null && value !== undefined
      ? value
      : ''
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const raw = e.target.value
    if (is64bit) {
      onChange(raw === '' ? BigInt(0) : BigInt(raw))
    } else {
      onChange(raw === '' ? 0 : Number(raw))
    }
  }
  return (
    <div className="proto-form-field">
      <label className="proto-form-field-label">{label}</label>
      {description && (
        <p className="proto-form-field-description">{description}</p>
      )}
      <input
        type="number"
        className="proto-form-input"
        value={String(displayValue)}
        onChange={handleChange}
      />
    </div>
  )
}
ScalarFieldRenderer function · typescript · L11-L81 (71 LOC)
components/proto-form/renderers/ScalarFieldRenderer.tsx
export function ScalarFieldRenderer({
  scalar,
  label,
  description,
  value,
  onChange,
}: ScalarFieldProps) {
  if (scalar === ScalarType.BOOL) {
    return (
      <label className="proto-form-checkbox-label">
        <input
          type="checkbox"
          className="proto-form-checkbox"
          checked={Boolean(value)}
          onChange={e => onChange(e.target.checked)}
        />
        <span className="proto-form-checkbox-text">
          <strong className="proto-form-field-label">{label}</strong>
          {description && (
            <span className="proto-form-field-description">{description}</span>
          )}
        </span>
      </label>
    )
  }

  const is64bit =
    scalar === ScalarType.INT64 ||
    scalar === ScalarType.UINT64 ||
    scalar === ScalarType.SINT64 ||
    scalar === ScalarType.FIXED64 ||
    scalar === ScalarType.SFIXED64

  const isNumeric =
    is64bit ||
    scalar === ScalarType.INT32 ||
    scalar === ScalarType.UINT32 ||
    scalar =
renderListField function · typescript · L20-L45 (26 LOC)
components/proto-form/renderListField.tsx
export function renderListField(
  field: Extract<FieldRenderProps['field'], { fieldKind: 'list' }>,
  shared: RenderListSharedProps
) {
  const { label, description, value, onChange, ProtoFormRenderer } = shared
  if (field.listKind === 'message') {
    return (
      <MessageListFieldRenderer
        messageDesc={field.message}
        label={label}
        description={description}
        value={value}
        onChange={onChange}
        ProtoFormRenderer={ProtoFormRenderer}
      />
    )
  }
  return (
    <ListFieldRenderer
      label={label}
      description={description}
      value={value}
      onChange={onChange}
    />
  )
}
applyDemoState function · typescript · L11-L19 (9 LOC)
components/providers/applyDemoState.ts
export function applyDemoState(
  setStatus: SetState<DaemonStatus>,
  setVscode: SetState<boolean | null>,
  setEds: SetState<EditorInfo[]>
) {
  setStatus('demo')
  setVscode(resolveVscodeAvailable(true))
  setEds(createDemoEditors())
}
buildAggregateContext function · typescript · L5-L19 (15 LOC)
components/providers/buildAggregateContext.ts
export function buildAggregateContext(
  navigateToProject: NavigateFn
): PathContextType {
  return {
    orgSlug: null,
    projectName: null,
    projectPath: '',
    isInitialized: null,
    displayPath: '',
    isAggregateView: true,
    isLoading: false,
    error: null,
    navigateToProject,
  }
}
Powered by Repobility — scan your code at https://repobility.com
buildDemoRedirectUrl function · typescript · L4-L9 (6 LOC)
components/providers/buildDemoRedirectUrl.ts
export function buildDemoRedirectUrl(
  orgSlug: string,
  projectPath: string
): string {
  return `/?org=${orgSlug}&project=${encodeURIComponent(projectPath)}`
}
buildPendingContext function · typescript · L6-L29 (24 LOC)
components/providers/buildPendingContext.ts
export function buildPendingContext(
  urlOrg: string | undefined,
  urlProject: string | undefined,
  isLoading: boolean,
  error: string | null,
  navigateToProject: NavigateFn
): PathContextType {
  return {
    orgSlug:
      urlOrg === UNGROUPED_ORG_MARKER
        ? null
        : urlOrg !== undefined
          ? urlOrg
          : null,
    projectName: urlProject !== undefined ? urlProject : null,
    projectPath: '',
    isInitialized: null,
    displayPath: '',
    isAggregateView: false,
    isLoading,
    error,
    navigateToProject,
  }
}
buildResolvedContext function · typescript · L6-L23 (18 LOC)
components/providers/buildResolvedContext.ts
export function buildResolvedContext(
  resolution: ProjectResolution,
  isLoading: boolean,
  error: string | null,
  navigateToProject: NavigateFn
): PathContextType {
  return {
    orgSlug: resolution.orgSlug,
    projectName: resolution.projectName,
    projectPath: resolution.projectPath,
    isInitialized: resolution.initialized,
    displayPath: resolution.displayPath,
    isAggregateView: false,
    isLoading,
    error,
    navigateToProject,
  }
}
createDemoEditors function · typescript · L6-L27 (22 LOC)
components/providers/createDemoEditors.ts
export function createDemoEditors(): EditorInfo[] {
  return [
    {
      $typeName: 'centy.v1.EditorInfo',
      editorType: EditorType.VSCODE,
      name: 'VS Code',
      description: 'Open in temporary VS Code workspace',
      available: true,
      editorId: 'vscode',
      terminalWrapper: false,
    },
    {
      $typeName: 'centy.v1.EditorInfo',
      editorType: EditorType.TERMINAL,
      name: 'Terminal',
      description: 'Open in terminal',
      available: true,
      editorId: 'terminal',
      terminalWrapper: true,
    },
  ]
}
createFallbackEditors function · typescript · L6-L27 (22 LOC)
components/providers/createFallbackEditors.ts
export function createFallbackEditors(vscodeAvailable: boolean): EditorInfo[] {
  return [
    {
      $typeName: 'centy.v1.EditorInfo',
      editorType: EditorType.VSCODE,
      name: 'VS Code',
      description: 'Open in temporary VS Code workspace',
      available: vscodeAvailable,
      editorId: 'vscode',
      terminalWrapper: false,
    },
    {
      $typeName: 'centy.v1.EditorInfo',
      editorType: EditorType.TERMINAL,
      name: 'Terminal',
      description: 'Open in terminal',
      available: true,
      editorId: 'terminal',
      terminalWrapper: true,
    },
  ]
}
useDaemonStatusState function · typescript · L23-L97 (75 LOC)
components/providers/DaemonStatusProvider.hooks.ts
export function useDaemonStatusState() {
  const [status, setStatus] = useState<DaemonStatus>('checking')
  const [lastChecked, setLastChecked] = useState<Date | null>(null)
  const [hasMounted, setHasMounted] = useState(false)
  const [vscodeAvailable, setVscodeAvailable] = useState<boolean | null>(null)
  const [editors, setEditors] = useState<EditorInfo[]>([])

  useEffect(() => {
    const timeoutId = setTimeout(() => {
      initializeDemoFromUrl(setStatus, setVscodeAvailable, setEditors)
      setHasMounted(true)
    }, 0)
    return () => clearTimeout(timeoutId)
  }, [])

  const checkDaemonStatus = useCallback(async () => {
    if (isDemoMode()) {
      applyDemoState(setStatus, setVscodeAvailable, setEditors)
      return
    }
    setStatus('checking')
    try {
      const daemonInfo = await centyClient.getDaemonInfo({})
      setStatus('connected')
      setVscodeAvailable(daemonInfo.vscodeAvailable)
      trackDaemonConnection(true, false)
      const resp = await centyCli
DaemonStatusProvider function · typescript · L11-L38 (28 LOC)
components/providers/DaemonStatusProvider.tsx
export function DaemonStatusProvider({ children }: { children: ReactNode }) {
  const {
    status,
    lastChecked,
    checkDaemonStatus,
    enterDemoMode,
    exitDemoMode,
    vscodeAvailable,
    editors,
  } = useDaemonStatusState()

  return (
    <DaemonStatusContext.Provider
      value={{
        status,
        lastChecked,
        checkNow: checkDaemonStatus,
        enterDemoMode,
        exitDemoMode,
        demoProjectPath: DEMO_PROJECT_PATH,
        vscodeAvailable,
        editors,
      }}
    >
      {children}
    </DaemonStatusContext.Provider>
  )
}
useDaemonStatus function · typescript · L40-L46 (7 LOC)
components/providers/DaemonStatusProvider.tsx
export function useDaemonStatus() {
  const context = useContext(DaemonStatusContext)
  if (!context) {
    throw new DaemonStatusProviderError()
  }
  return context
}
Open data scored by Repobility · https://repobility.com
initializeDemoFromUrl function · typescript · L12-L26 (15 LOC)
components/providers/initializeDemoFromUrl.ts
export function initializeDemoFromUrl(
  setStatus: SetState<DaemonStatus>,
  setVscodeAvailable: SetState<boolean | null>,
  setEditors: SetState<EditorInfo[]>
) {
  const urlParams = new URLSearchParams(window.location.search)
  if (urlParams.get('demo') === 'true' && !isDemoMode()) {
    enableDemoMode()
    applyDemoState(setStatus, setVscodeAvailable, setEditors)
    const newUrl = buildDemoUrl(DEMO_ORG_SLUG, DEMO_PROJECT_PATH)
    window.history.replaceState({}, '', newUrl)
  } else if (isDemoMode()) {
    applyDemoState(setStatus, setVscodeAvailable, setEditors)
  }
}
OrganizationProvider function · typescript · L24-L87 (64 LOC)
components/providers/OrganizationProvider.tsx
export function OrganizationProvider({ children }: { children: ReactNode }) {
  const { urlOrg } = useUrlParams()
  // Derive selected org from URL; allow local override without persistence
  // undefined = not yet selected (initial), null = all orgs, string = specific org or ''
  const [selectedOrgSlug, setSelectedOrgSlugState] = useState<
    string | null | undefined
  >(urlOrg)

  const [organizations, setOrganizations] = useState<Organization[]>([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  // Sync selected org from URL whenever the URL org changes
  useEffect(() => {
    setSelectedOrgSlugState(urlOrg)
  }, [urlOrg])

  const refreshOrganizations = useCallback(async () => {
    setLoading(true)
    setError(null)

    try {
      const request = create(ListOrganizationsRequestSchema, {})
      const response = await centyClient.listOrganizations(request)
      setOrganizations(response.organizations)
    } catch (
useOrganization function · typescript · L89-L95 (7 LOC)
components/providers/OrganizationProvider.tsx
export function useOrganization() {
  const context = useContext(OrganizationContext)
  if (!context) {
    throw new OrganizationProviderError()
  }
  return context
}
‹ prevpage 4 / 10next ›