diff --git a/README.md b/README.md index 5013343..1b75a34 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,7 @@ ocl concept update OWNER SOURCE CONCEPT_ID [--concept-class CLASS] [--datatype T ocl concept retire OWNER SOURCE CONCEPT_ID ocl concept delete OWNER SOURCE CONCEPT_ID [--yes] # hard delete; staff only ocl concept name-add OWNER SOURCE CONCEPT_ID NAME --locale LOCALE +ocl concept name-update OWNER SOURCE CONCEPT_ID NAME_UUID [--name TEXT] [--locale LOCALE] [--name-type TYPE] [--locale-preferred|--no-locale-preferred] ocl concept description-add OWNER SOURCE CONCEPT_ID TEXT --locale LOCALE ocl concept extra-set OWNER SOURCE CONCEPT_ID KEY VALUE ocl concept extra-del OWNER SOURCE CONCEPT_ID KEY diff --git a/src/ocl_cli/api_client.py b/src/ocl_cli/api_client.py index 83b3d1d..16cef7d 100644 --- a/src/ocl_cli/api_client.py +++ b/src/ocl_cli/api_client.py @@ -1046,6 +1046,36 @@ def add_concept_name( body["locale_preferred"] = True return self.post(endpoint, json=body) + def update_concept_name( + self, + owner: str, + source: str, + concept_id: str, + name_uuid: str, + owner_type: str = "orgs", + name: Optional[str] = None, + locale: Optional[str] = None, + name_type: Optional[str] = None, + locale_preferred: Optional[bool] = None, + external_id: Optional[str] = None, + ) -> dict: + """Update an existing name on a concept by UUID.""" + self._require_auth() + _validate_owner_type(owner_type) + endpoint = f"/{owner_type}/{owner}/sources/{source}/concepts/{concept_id}/names/{name_uuid}/" + body: dict[str, Any] = {} + if name is not None: + body["name"] = name + if locale is not None: + body["locale"] = locale + if name_type is not None: + body["name_type"] = name_type + if locale_preferred is not None: + body["locale_preferred"] = locale_preferred + if external_id is not None: + body["external_id"] = external_id + return self.put(endpoint, json=body) + def add_concept_description( self, owner: str, diff --git a/src/ocl_cli/commands/concept.py b/src/ocl_cli/commands/concept.py index c1d0ebe..514d9e0 100644 --- a/src/ocl_cli/commands/concept.py +++ b/src/ocl_cli/commands/concept.py @@ -313,6 +313,42 @@ def _fmt_name(d): handle_api_error(e) +@concept.command("name-update") +@click.argument("owner") +@click.argument("source") +@click.argument("concept_id") +@click.argument("name_uuid") +@click.option("--name", "name_text", help="New name text") +@click.option("--locale", help="New locale code") +@click.option("--name-type", help="New name type") +@click.option("--locale-preferred/--no-locale-preferred", default=None, help="Set or clear locale preferred flag") +@click.option("--external-id", help="External identifier") +@click.option("--owner-type", type=click.Choice(["users", "orgs"]), default="orgs") +@click.pass_context +def name_update(ctx, owner, source, concept_id, name_uuid, name_text, locale, name_type, + locale_preferred, external_id, owner_type): + """Update a name on a concept. Use 'concept names --verbose' to find the name UUID.""" + client = ctx.obj["client"] + if not any([name_text, locale, name_type, locale_preferred is not None, external_id]): + click.echo("No fields to update. Use --name, --locale, --name-type, --locale-preferred, or --external-id.", err=True) + sys.exit(1) + try: + result = client.update_concept_name( + owner, source, concept_id, name_uuid, + owner_type=owner_type, + name=name_text, + locale=locale, + name_type=name_type, + locale_preferred=locale_preferred, + external_id=external_id, + ) + def _fmt_name(d): + return f"Updated name: {d.get('name', '')} ({d.get('locale', '')}, {d.get('name_type', '')})" + output_result(ctx, result, _fmt_name) + except APIError as e: + handle_api_error(e) + + @concept.command("description-add") @click.argument("owner") @click.argument("source") diff --git a/src/ocl_cli/output.py b/src/ocl_cli/output.py index ed425b7..6a0729b 100644 --- a/src/ocl_cli/output.py +++ b/src/ocl_cli/output.py @@ -517,14 +517,15 @@ def format_names_list(data: dict, verbose: bool = False) -> str: "preferred": "Yes" if name.get("locale_preferred") else "No", } if verbose: + row["uuid"] = name.get("uuid", "") row["external_id"] = name.get("external_id", "") rows.append(row) columns = ["name", "locale", "type", "preferred"] headers = ["Name", "Locale", "Type", "Preferred"] if verbose: - columns.append("external_id") - headers.append("External ID") + columns += ["uuid", "external_id"] + headers += ["UUID", "External ID"] return format_table(rows, columns, headers)