Skip to content

Commit 1368997

Browse files
committed
Add version comparer
1 parent e5bb667 commit 1368997

File tree

5 files changed

+387
-38
lines changed

5 files changed

+387
-38
lines changed

gh-pages/src/App.vue

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
import {
33
getAvailableVersions,
44
getVersion,
5-
type LanguageData,
5+
type Language,
66
type Version,
77
} from './Version';
88
import {computed, onMounted, ref, watch} from 'vue';
99
import * as UrlService from './UrlService';
10+
import DifferModal from './components/DifferModal.vue';
1011
1112
type SortBys = 'id' | 'name';
1213
@@ -15,6 +16,7 @@ const availableVersions = ref<string[] | null>(null);
1516
const wantedVersion = ref<string>('');
1617
const version = ref<Version | null>(null);
1718
const sortBy = ref<SortBys>('id');
19+
const differModal = ref<InstanceType<typeof DifferModal> | null>(null);
1820
1921
onMounted(async () => {
2022
availableVersions.value = await getAvailableVersions();
@@ -29,7 +31,7 @@ async function loadVersion(v: string): Promise<void> {
2931
busy.value = true;
3032
try {
3133
const loadedVersion = await getVersion(v);
32-
if (loadedVersion._version !== v) {
34+
if (loadedVersion.version !== v) {
3335
return;
3436
}
3537
UrlService.setVersionInUrl(v);
@@ -42,56 +44,55 @@ async function loadVersion(v: string): Promise<void> {
4244
}
4345
}
4446
watch(wantedVersion, (v) => {
45-
if (v && v !== version.value?._version) {
47+
if (v && v !== version.value?.version) {
4648
loadVersion(v);
4749
}
4850
});
49-
export interface Language extends LanguageData {
50-
id: string;
51-
}
5251
5352
const comparer = new Intl.Collator('en', {sensitivity: 'base'});
5453
5554
const languages = computed<Language[]>(() => {
56-
const result: Language[] = [];
5755
if (!version.value) {
58-
return result;
59-
}
60-
for (const [id, data] of Object.entries(version.value)) {
61-
if (id === '_version') {
62-
continue;
63-
}
64-
result.push({id, ...(<LanguageData>data)});
56+
return [];
6557
}
58+
const result = [...version.value.languages];
6659
result.sort((a, b) => comparer.compare(a[sortBy.value], b[sortBy.value]));
6760
return result;
6861
});
6962
</script>
7063

7164
<template>
72-
<div class="container text-center" v-if="availableVersions !== null">
73-
<div class="row justify-content-center">
74-
<label class="col-sm-2 col-form-label" for="wanted-version"
75-
>Version</label
76-
>
77-
<div class="col-md-2 col-sm-4 col-xs-10">
78-
<select
79-
id="wanted-version"
80-
v-model="wantedVersion"
81-
:disabled="busy"
82-
class="form-control"
83-
>
84-
<option v-for="v in availableVersions" :value="v" :key="v">
85-
{{ v }}
86-
</option>
87-
</select>
65+
<div class="container" v-if="availableVersions !== null">
66+
<div class="row justify-content-center mb-3">
67+
<div class="col-12" style="max-width: 300px">
68+
<div class="input-group input-group-sm">
69+
<label for="wanted-version" class="input-group-text">Version</label>
70+
<select
71+
id="wanted-version"
72+
v-model="wantedVersion"
73+
:disabled="busy"
74+
class="form-control"
75+
>
76+
<option v-for="v in availableVersions" :value="v" :key="v">
77+
{{ v }}
78+
</option>
79+
</select>
80+
<button
81+
v-if="version !== null"
82+
type="button"
83+
class="btn btn-outline-secondary"
84+
@click="differModal?.open(version.version)"
85+
>
86+
Compare
87+
</button>
88+
</div>
8889
</div>
8990
</div>
9091
</div>
9192
<div v-if="version !== null" class="container-fluid">
9293
<table class="table table-sm table-striped table-hover caption-top">
9394
<caption class="text-center">
94-
<h2>gettext plural rules from CLDR {{ version._version }}</h2>
95+
<h2>gettext plural rules from CLDR {{ version.version }}</h2>
9596
</caption>
9697
<thead>
9798
<tr>
@@ -125,7 +126,7 @@ const languages = computed<Language[]>(() => {
125126
<tbody>
126127
<tr
127128
v-for="language in languages"
128-
:key="`${language.id}@${version._version}`"
129+
:key="`${language.id}@${version.version}`"
129130
>
130131
<td>
131132
<code>{{ language.id }}</code>
@@ -156,4 +157,5 @@ const languages = computed<Language[]>(() => {
156157
</tbody>
157158
</table>
158159
</div>
160+
<DifferModal ref="differModal" />
159161
</template>

gh-pages/src/Differ.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import type {Language, Version} from './Version';
2+
3+
interface Diff {
4+
fromLanguage: Language;
5+
toLanguage: Language;
6+
change: string;
7+
}
8+
9+
export interface Diffs {
10+
fromVersion: Version;
11+
toVersion: Version;
12+
added: Language[];
13+
removed: Language[];
14+
changed: Diff[];
15+
}
16+
17+
function diffLanguages(fromVersion: Version, toVersion: Version): Diff[] {
18+
let result: Diff[] = [];
19+
toVersion.languages.forEach((toLanguage) => {
20+
const fromLanguage = fromVersion.languages.find(
21+
(fromLanguage) => fromLanguage.id === toLanguage.id,
22+
);
23+
if (fromLanguage) {
24+
result = result.concat(diffLanguage(fromLanguage, toLanguage));
25+
}
26+
});
27+
return result;
28+
}
29+
30+
function diffLanguage(fromLanguage: Language, toLanguage: Language): Diff[] {
31+
let result: Diff[] = [];
32+
if (fromLanguage.name !== toLanguage.name) {
33+
result.push({
34+
fromLanguage,
35+
toLanguage,
36+
change: `Name changed from ${fromLanguage.name} to ${toLanguage.name}`,
37+
});
38+
}
39+
if (fromLanguage.plurals !== toLanguage.plurals) {
40+
result.push({
41+
fromLanguage,
42+
toLanguage,
43+
change: `Plurals changed from ${fromLanguage.plurals} to ${toLanguage.plurals}`,
44+
});
45+
} else if (fromLanguage.formula !== toLanguage.formula) {
46+
result.push({
47+
fromLanguage,
48+
toLanguage,
49+
change: `Formula changed from\n${fromLanguage.formula}\nto\n${toLanguage.formula}`,
50+
});
51+
}
52+
return result;
53+
}
54+
55+
export function computeDiffs(fromVersion: Version, toVersion: Version): Diffs {
56+
return {
57+
fromVersion,
58+
toVersion,
59+
added: toVersion.languages.filter(
60+
(toLanguage) =>
61+
!fromVersion.languages.some(
62+
(fromLanguage) => toLanguage.id === fromLanguage.id,
63+
),
64+
),
65+
removed: fromVersion.languages.filter(
66+
(fromLanguage) =>
67+
!toVersion.languages.some(
68+
(toLanguage) => toLanguage.id === fromLanguage.id,
69+
),
70+
),
71+
changed: diffLanguages(fromVersion, toVersion),
72+
};
73+
}

gh-pages/src/Version.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
type PluralCases = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';
22

3-
export interface LanguageData {
3+
interface RawLanguage {
44
name: string;
55
formula: string;
66
plurals: number;
77
cases: PluralCases[];
88
examples: Record<PluralCases, string>;
99
}
10-
export type Version = Record<string, LanguageData> & {_version: string};
10+
11+
type RawVersion = Record<string, RawLanguage>;
12+
13+
export interface Language extends RawLanguage {
14+
id: string;
15+
}
16+
export interface Version {
17+
version: string;
18+
languages: Language[];
19+
}
1120

1221
let availableVersions: string[] | undefined;
1322

@@ -27,8 +36,14 @@ export async function getVersion(version: string): Promise<Version> {
2736
return loadedVersions[version];
2837
}
2938
const response = await fetch(`data/versions/${version}.min.json`);
30-
const data = <Version>await response.json();
31-
data._version = version;
32-
loadedVersions[version] = data;
33-
return (loadedVersions[version] = data);
39+
const rawVersion = <RawVersion>await response.json();
40+
const parsedVersion: Version = {
41+
version,
42+
languages: Object.entries(rawVersion).map(([id, rawLanguage]) => ({
43+
id,
44+
...rawLanguage,
45+
})),
46+
};
47+
loadedVersions[version] = parsedVersion;
48+
return parsedVersion;
3449
}

0 commit comments

Comments
 (0)