From 17c9c53304867d5c6ec7911f55e2ad86ff9a8c7a Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Tue, 3 May 2022 17:37:07 +0200 Subject: [PATCH] Factor TooltipModel from TooltipView (#448 #447) --- frontend/src/tooltip/tooltip-model-test.ts | 60 ++++++++++++++++++++++ frontend/src/tooltip/tooltip-model.ts | 40 +++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 frontend/src/tooltip/tooltip-model-test.ts create mode 100644 frontend/src/tooltip/tooltip-model.ts diff --git a/frontend/src/tooltip/tooltip-model-test.ts b/frontend/src/tooltip/tooltip-model-test.ts new file mode 100644 index 00000000..eceb3c0a --- /dev/null +++ b/frontend/src/tooltip/tooltip-model-test.ts @@ -0,0 +1,60 @@ +import { enableI18n, event } from '../test-util'; + +import { readit, rdfs, skos } from '../common-rdf/ns'; +import { FlatLdObject } from '../common-rdf/json'; +import Node from '../common-rdf/node'; +import FlatItem from '../common-adapters/flat-item-model'; + +import toTooltip from './tooltip-model'; + +function getDefaultAttributes(): FlatLdObject { + return { + '@id': readit('test'), + "@type": [rdfs.Class], + [skos.prefLabel]: [ + { '@value': 'Content' }, + ], + [skos.altLabel]: [ + { '@value': 'alternativeLabel' } + ], + [skos.definition]: [ + { '@value': 'This is a test definition' } + ], + [rdfs.comment]: [ + { '@value': 'Also, I have a comment' } + ], + } +} + +function getDefaultItem(): FlatItem { + return new FlatItem(new Node(getDefaultAttributes())); +} + +describe('Tooltip model adapter', function () { + beforeAll(enableI18n); + + beforeEach(function() { + this.item = getDefaultItem(); + }); + + it('uses skos:definition if available', async function () { + const model = toTooltip(this.item); + await event(this.item, 'complete'); + expect(model.get('text')).toEqual('This is a test definition'); + }); + + it('uses rdfs:comment otherwise', async function() { + this.item.underlying.unset(skos.definition); + const model = toTooltip(this.item); + await event(this.item, 'complete'); + expect(model.get('text')).toEqual('Also, I have a comment'); + }); + + it('unsets the text when definition and comment are absent', async function() { + this.item.underlying.unset(skos.definition); + this.item.underlying.unset(rdfs.comment); + const model = toTooltip(this.item); + await event(this.item, 'complete'); + expect(model.has('text')).toBe(false); + }); +}); diff --git a/frontend/src/tooltip/tooltip-model.ts b/frontend/src/tooltip/tooltip-model.ts new file mode 100644 index 00000000..c06a6c04 --- /dev/null +++ b/frontend/src/tooltip/tooltip-model.ts @@ -0,0 +1,40 @@ +import * as i18next from 'i18next'; + +import Model from '../core/model'; +import { rdfs, skos } from '../common-rdf/ns'; +import FlatItem from '../common-adapters/flat-item-model'; + +/** + * Model adapter that lets you feed a `FlatItem` to a `TooltipView`. + * + * `TooltipView` expects a model with just a `text` attribute. The adapter + * extracts either the `skos:definition` or the `rdfs:comment`, depending on + * which is available, from the underlying model, and sets this as the `text` + * attribute. It takes the currently selected language into account. + * + * For optimum convenience, use the `toTooltip` helper function instead of + * instantiating the class directly. + */ +export class FlatAsTooltipAdapter extends Model { + constructor(underlying: FlatItem, options?: any) { + super(null, options); + underlying.when('classLabel', this.adapt, this); + } + + adapt(underlying): void { + const cls = underlying.get('class'); + const languageOption = { '@language': i18next.language }; + const definition = cls.get(skos.definition, languageOption); + const comment = definition || cls.get(rdfs.comment, languageOption); + const text = definition && definition[0] || comment && comment[0]; + this.set({text}); + } +} + +/** + * Helper function to wrap a `FlatItem` in a model with the expected attributes + * for a `TooltipView`. + */ +export default function toTooltip(model: FlatItem) { + return new FlatAsTooltipAdapter(model); +}