Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions jig-core/src/main/resources/templates/assets/glossary.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,25 @@ function updateArticleVisibility(controls) {

}

// 文字列の比較は日本語を優先しつつ大小を無視する
const termCollator = new Intl.Collator("ja", {numeric: true, sensitivity: "base"});

function sortTerms(terms, sortKey) {
const keyMap = {
name: "title",
fqn: "fqn",
simple: "simpleText",
};
const key = keyMap[sortKey] ?? "title";
return [...terms].sort((left, right) => {
const leftValue = left?.[key] ?? "";
const rightValue = right?.[key] ?? "";
const primary = termCollator.compare(leftValue, rightValue);
if (primary !== 0) return primary;
return termCollator.compare(left?.fqn ?? "", right?.fqn ?? "");
});
}

function getFilteredTerms(terms, controls) {
if (!controls) return terms;
const showEmptyDescription = controls.showEmptyDescription.checked;
Expand Down Expand Up @@ -167,13 +186,18 @@ function renderMarkdownDescriptions() {
.forEach(node => node.innerHTML = marked.parse(node.innerHTML));
}

function renderFilteredTerms(terms, controls) {
const filteredTerms = getFilteredTerms(terms, controls);
const sortedTerms = sortTerms(filteredTerms, controls.sortOrder?.value);
renderGlossaryTerms(sortedTerms);
renderMarkdownDescriptions();
}

if (typeof document !== "undefined") {
document.addEventListener("DOMContentLoaded", function () {
if (!document.body.classList.contains("glossary")) return;

const terms = getGlossaryData();
renderGlossaryTerms(terms);
renderMarkdownDescriptions();

const controls = {
searchInput: document.getElementById("search-input"),
Expand All @@ -182,16 +206,20 @@ if (typeof document !== "undefined") {
showClass: document.getElementById("show-class"),
showMethod: document.getElementById("show-method"),
showField: document.getElementById("show-field"),
sortOrder: document.getElementById("sort-order"),
};

const updateArticles = () => updateArticleVisibility(controls);
const updateArticles = () => renderFilteredTerms(terms, controls);

controls.searchInput.addEventListener("input", updateArticles);
controls.showEmptyDescription.addEventListener("change", updateArticles);
controls.showPackage.addEventListener("change", updateArticles);
controls.showClass.addEventListener("change", updateArticles);
controls.showMethod.addEventListener("change", updateArticles);
controls.showField.addEventListener("change", updateArticles);
if (controls.sortOrder) {
controls.sortOrder.addEventListener("change", updateArticles);
}
const exportButton = document.getElementById("export-csv");
if (exportButton) {
exportButton.addEventListener("click", () => {
Expand All @@ -209,11 +237,13 @@ if (typeof document !== "undefined") {
if (typeof module !== "undefined" && module.exports) {
module.exports = {
updateArticleVisibility,
sortTerms,
getFilteredTerms,
getGlossaryData,
escapeCsvValue,
buildGlossaryCsv,
renderGlossaryTerms,
renderFilteredTerms,
renderMarkdownDescriptions,
};
}
8 changes: 8 additions & 0 deletions jig-core/src/main/resources/templates/glossary.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@
<label><input type="checkbox" id="show-method" checked>メソッド</label>
<label><input type="checkbox" id="show-field" checked>フィールド</label>
</div>
<div>
<label for="sort-order">並び順:</label>
<select id="sort-order">
<option value="name" selected>名前</option>
<option value="fqn">完全修飾名</option>
<option value="simple">単純名</option>
</select>
</div>
<div>
<button id="export-csv" type="button">CSV出力</button>
</div>
Expand Down
18 changes: 18 additions & 0 deletions jig-core/src/test/js/glossary.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,24 @@ test.describe('glossary.js', () => {
});
});

test.describe('ソート', () => {
test('名前・完全修飾名・単純名で並び替える', () => {
const terms = [
{title: 'Order', simpleText: 'Order', fqn: 'app.Order'},
{title: 'Account', simpleText: 'Account', fqn: 'app.Account'},
{title: 'User', simpleText: 'User', fqn: 'app.domain.User'},
];

const byName = glossary.sortTerms(terms, 'name').map(term => term.title);
const byFqn = glossary.sortTerms(terms, 'fqn').map(term => term.fqn);
const bySimple = glossary.sortTerms(terms, 'simple').map(term => term.simpleText);

assert.deepEqual(byName, ['Account', 'Order', 'User']);
assert.deepEqual(byFqn, ['app.Account', 'app.domain.User', 'app.Order']);
assert.deepEqual(bySimple, ['Account', 'Order', 'User']);
});
});

test.describe('データ読み込み', () => {
test('glossary-dataから用語一覧を取得する', () => {
const doc = setupDocument();
Expand Down