Skip to content

Add prefix and namespace manager #161

@aadorian

Description

@aadorian

Description

Stanford Protégé allows managing ontology prefixes and namespaces. Users should be able to add/edit/remove prefix mappings.

What to implement

Add a namespace manager panel showing:

  • List of all prefix:namespace mappings
  • Add new prefix
  • Edit existing prefix
  • Remove prefix
  • Common prefixes (rdf, rdfs, owl, xsd) pre-populated

Difficulty: Easy

Skills: React, RDF

Tasks

  • Create NamespaceManager component
  • Display current prefixes in a table
  • Add/edit/remove prefix functionality
  • Pre-populate common prefixes for new ontologies

Acceptance Criteria

  • Shows all prefix mappings
  • Can add new prefix
  • Can edit prefix
  • Can remove prefix (with warning if in use)

Implementation Pseudocode

// 1. Define common prefixes as defaults
const DEFAULT_PREFIXES: Record<string, string> = {
  'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
  'rdfs': 'http://www.w3.org/2000/01/rdf-schema#',
  'owl': 'http://www.w3.org/2002/07/owl#',
  'xsd': 'http://www.w3.org/2001/XMLSchema#',
  'dc': 'http://purl.org/dc/elements/1.1/',
  'skos': 'http://www.w3.org/2004/02/skos/core#',
};

// 2. Store prefixes in ontology state
interface Ontology {
  // ... existing fields
  prefixes: Map<string, string>;  // prefix -> namespace IRI
}

// 3. Create NamespaceManager component
function NamespaceManager() {
  const { ontology, updatePrefixes } = useOntology();
  const [editingPrefix, setEditingPrefix] = useState<string | null>(null);
  const [newPrefix, setNewPrefix] = useState({ prefix: '', namespace: '' });

  const prefixes = ontology.prefixes || new Map(Object.entries(DEFAULT_PREFIXES));

  const handleAddPrefix = () => {
    if (!newPrefix.prefix || !newPrefix.namespace) {
      toast.error('Both prefix and namespace are required');
      return;
    }
    if (prefixes.has(newPrefix.prefix)) {
      toast.error('Prefix already exists');
      return;
    }
    // Validate namespace is a valid IRI
    if (!isValidIRI(newPrefix.namespace)) {
      toast.error('Invalid namespace IRI');
      return;
    }

    const updated = new Map(prefixes);
    updated.set(newPrefix.prefix, newPrefix.namespace);
    updatePrefixes(updated);
    setNewPrefix({ prefix: '', namespace: '' });
  };

  const handleDeletePrefix = (prefix: string) => {
    // Check if prefix is in use
    const inUse = checkPrefixUsage(prefix, ontology);
    if (inUse) {
      toast.warning(`Prefix '${prefix}' is in use. Remove usages first.`);
      return;
    }

    const updated = new Map(prefixes);
    updated.delete(prefix);
    updatePrefixes(updated);
  };

  return (
    <div className="namespace-manager">
      <h3>Namespace Prefixes</h3>
      <Table>
        <TableHeader>
          <TableRow>
            <TableHead>Prefix</TableHead>
            <TableHead>Namespace IRI</TableHead>
            <TableHead>Actions</TableHead>
          </TableRow>
        </TableHeader>
        <TableBody>
          {Array.from(prefixes.entries()).map(([prefix, namespace]) => (
            <TableRow key={prefix}>
              <TableCell className="font-mono">{prefix}:</TableCell>
              <TableCell>
                <span className="font-mono text-sm">{namespace}</span>
              </TableCell>
              <TableCell>
                <Button variant="ghost" size="icon" onClick={() => setEditingPrefix(prefix)}>
                  <Pencil className="h-4 w-4" />
                </Button>
                <Button variant="ghost" size="icon" onClick={() => handleDeletePrefix(prefix)}>
                  <Trash className="h-4 w-4" />
                </Button>
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </div>
  );
}

Files to modify

  • Create: src/components/NamespaceManager.tsx
  • Modify: src/types/ontology.ts (add prefixes field)
  • Modify: src/context/OntologyContext.tsx (add updatePrefixes function)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    Status

    To triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions