-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add utils for ranking and finding labels
- Loading branch information
1 parent
f93f0c0
commit eae5b95
Showing
6 changed files
with
184 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Changelog | ||
|
||
All notable changes to this project will be documented in this file. | ||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
||
## [Unreleased] | ||
|
||
### Added | ||
- Add utils for ranking and finding labels | ||
|
||
### Deprecated | ||
|
||
### Removed | ||
|
||
### Security |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const PREF_LABEL = "prefLabel"; | ||
export const ALT_LABEL = "altLabel"; | ||
export const HIDDEN_LABEL = "hiddenLabel"; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
export interface Language { | ||
code: string; | ||
default_direction: "ltr" | "rtl"; | ||
id: number; | ||
isdefault: boolean; | ||
name: string; | ||
scope: string; | ||
} | ||
|
||
export interface Label { | ||
value: string; | ||
languageCode: string; | ||
valuetype: "prefLabel" | "altLabel" | "hiddenLabel"; | ||
} | ||
|
||
export interface Labellable { | ||
labels: Label[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { | ||
ALT_LABEL, | ||
HIDDEN_LABEL, | ||
PREF_LABEL, | ||
} from "@/arches_vue_utils/constants.ts"; | ||
import { getItemLabel, rankLabel } from "@/arches_vue_utils/utils.ts"; | ||
|
||
import type { Label } from "@/arches_vue_utils/types"; | ||
|
||
// Test utils | ||
const asLabel = ( | ||
valuetype: "prefLabel" | "altLabel" | "hiddenLabel", | ||
languageCode: string, | ||
): Label => { | ||
return { | ||
value: "arbitrary", | ||
valuetype, | ||
languageCode, | ||
}; | ||
}; | ||
|
||
const systemLanguageCode = "en-ZA"; // arbitrary | ||
|
||
describe("rankLabel() util", () => { | ||
const rank = ( | ||
valuetype: "prefLabel" | "altLabel" | "hiddenLabel", | ||
labelLanguageCode: string, | ||
desiredLanguageCode: string, | ||
) => | ||
rankLabel( | ||
asLabel(valuetype, labelLanguageCode), | ||
desiredLanguageCode, | ||
systemLanguageCode, | ||
); | ||
|
||
// Test cases inspired from python module | ||
it("Prefers explicit region", () => { | ||
expect(rank(PREF_LABEL, "fr-CA", "fr-CA")).toBeGreaterThan( | ||
rank(PREF_LABEL, "fr", "fr-CA"), | ||
); | ||
}); | ||
it("Prefers pref over alt", () => { | ||
expect(rank(PREF_LABEL, "fr", "fr-CA")).toBeGreaterThan( | ||
rank(ALT_LABEL, "fr", "fr-CA"), | ||
); | ||
}); | ||
it("Prefers alt over hidden", () => { | ||
expect(rank(ALT_LABEL, "fr", "fr-CA")).toBeGreaterThan( | ||
rank(HIDDEN_LABEL, "fr", "fr-CA"), | ||
); | ||
}); | ||
it("Prefers alt label in system language to anything else", () => { | ||
expect(rank(ALT_LABEL, systemLanguageCode, "en")).toBeGreaterThan( | ||
rank(PREF_LABEL, "de", "en"), | ||
); | ||
}); | ||
it("Prefers region-insensitive match in system language", () => { | ||
expect(rank(PREF_LABEL, "en", "de")).toBeGreaterThan( | ||
rank(PREF_LABEL, "fr", "de"), | ||
); | ||
}); | ||
}); | ||
|
||
describe("getItemLabel() util", () => { | ||
it("Errors if no labels", () => { | ||
expect(() => | ||
getItemLabel( | ||
{ labels: [] }, | ||
systemLanguageCode, | ||
systemLanguageCode, | ||
), | ||
).toThrow(); | ||
}); | ||
it("Falls back to system language", () => { | ||
expect( | ||
getItemLabel( | ||
{ | ||
labels: [ | ||
asLabel(PREF_LABEL, "de"), | ||
asLabel(PREF_LABEL, systemLanguageCode), | ||
], | ||
}, | ||
"fr", | ||
systemLanguageCode, | ||
).languageCode, | ||
).toEqual(systemLanguageCode); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { ALT_LABEL, PREF_LABEL } from "@/arches_vue_utils/constants.ts"; | ||
|
||
import type { Label, Labellable } from "@/arches_vue_utils/types"; | ||
|
||
/* Port of rank_label in arches.app.utils.i18n python module */ | ||
export const rankLabel = ( | ||
label: Label, | ||
preferredLanguageCode: string, | ||
systemLanguageCode: string, | ||
): number => { | ||
let rank = 1; | ||
if (label.valuetype === PREF_LABEL) { | ||
rank = 10; | ||
} else if (label.valuetype === ALT_LABEL) { | ||
rank = 4; | ||
} | ||
|
||
// Some arches deployments may not have standardized capitalizations. | ||
const labelLanguageFull = label.languageCode.toLowerCase(); | ||
const labelLanguageNoRegion = label.languageCode | ||
.split(/[-_]/)[0] | ||
.toLowerCase(); | ||
const preferredLanguageFull = preferredLanguageCode.toLowerCase(); | ||
const preferredLanguageNoRegion = preferredLanguageCode | ||
.split(/[-_]/)[0] | ||
.toLowerCase(); | ||
const systemLanguageFull = systemLanguageCode.toLowerCase(); | ||
const systemLanguageNoRegion = systemLanguageCode | ||
.split(/[-_]/)[0] | ||
.toLowerCase(); | ||
|
||
if (labelLanguageFull === preferredLanguageFull) { | ||
rank *= 10; | ||
} else if (labelLanguageNoRegion === preferredLanguageNoRegion) { | ||
rank *= 5; | ||
} else if (labelLanguageFull === systemLanguageFull) { | ||
rank *= 3; | ||
} else if (labelLanguageNoRegion === systemLanguageNoRegion) { | ||
rank *= 2; | ||
} | ||
|
||
return rank; | ||
}; | ||
|
||
export const getItemLabel = ( | ||
item: Labellable, | ||
preferredLanguageCode: string, | ||
systemLanguageCode: string, | ||
): Label => { | ||
if (!item.labels.length) { | ||
throw new Error(); | ||
} | ||
return item.labels.sort( | ||
(a, b) => | ||
rankLabel(b, preferredLanguageCode, systemLanguageCode) - | ||
rankLabel(a, preferredLanguageCode, systemLanguageCode), | ||
)[0]; | ||
}; |