Skip to content

Commit

Permalink
Feat(annotation): Add support for annotations on graphs and subresources
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanarnault committed Jan 30, 2025
1 parent 5323755 commit 81f7e2e
Show file tree
Hide file tree
Showing 15 changed files with 427 additions and 175 deletions.
171 changes: 120 additions & 51 deletions cypress/e2e/phase_4/annotation.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,72 +34,147 @@ describe('Annotation', () => {
datasetImportPage.goToPublishedResources();
});

describe('createAnnotation', () => {
it('should create an annotation on resource field', () => {
cy.findByText('Search').click();
searchDrawer.search('Terminator 2');
searchDrawer.waitForLoading();
cy.findAllByText('Terminator 2').eq(1).click();
describe('homepage', () => {
it('should support annotations on home page', () => {
annotation.createAnnotation({
fieldLabel: 'actors',
fieldLabel: 'Dataset Description',
comment: 'This is a comment',
authorName: 'John Doe',
authorEmail: '[email protected]',
});

cy.findByText('Search').click();
searchDrawer.search('RoboCop');
searchDrawer.waitForLoading();
cy.findAllByText('RoboCop').eq(0).click();
annotation.createAnnotation({
fieldLabel: 'rating',
comment: 'This is another comment',
authorName: 'Jane Smith',
authorEmail: '[email protected]',
});
cy.findByText('More').click();
menu.goToAdminDashboard();
cy.findByText('Annotations').click();

cy.findAllByRole('columnheader').then((headers) => {
cy.findAllByRole('cell').then((cells) => {
expect(
headers.toArray().map((header) => header.textContent),
cells.toArray().map((cell) => cell.textContent),
).to.deep.equal([
'Resource URI',
'Resource title',
'Field label',
'Field Id',
'Field Icons',
'Field Internal Name',
'Contributor',
'Comment',
'Submission date',
'Home page',
'',
'Dataset Description',
'[Doay]',
'',
'n/a',
'John Doe',
'This is a comment',
new Date().toLocaleDateString(),
]);
});
});
});

cy.findAllByRole('cell').then((cells) => {
const firstUri = cells[0].textContent;
const secondUri = cells[9].textContent;
describe('resources', () => {
describe('createAnnotation', () => {
it('should create an annotation on resource field', () => {
cy.findByText('Search').click();
searchDrawer.search('Terminator 2');
searchDrawer.waitForLoading();
cy.findAllByText('Terminator 2').eq(1).click();
annotation.createAnnotation({
fieldLabel: 'actors',
comment: 'This is a comment',
authorName: 'John Doe',
authorEmail: '[email protected]',
});

cy.findByText('Search').click();
searchDrawer.search('RoboCop');
searchDrawer.waitForLoading();
cy.findAllByText('RoboCop').eq(0).click();
annotation.createAnnotation({
fieldLabel: 'rating',
comment: 'This is another comment',
authorName: 'Jane Smith',
authorEmail: '[email protected]',
});
cy.findByText('More').click();
menu.goToAdminDashboard();
cy.findByText('Annotations').click();

cy.findAllByRole('columnheader').then((headers) => {
expect(
headers.toArray().map((header) => header.textContent),
).to.deep.equal([
'Resource URI',
'Resource title',
'Field label',
'Field Id',
'Field Icons',
'Field Internal Name',
'Contributor',
'Comment',
'Submission date',
]);
});

cy.findAllByRole('cell').then((cells) => {
const firstUri = cells[0].textContent;
const secondUri = cells[9].textContent;

expect(firstUri).to.match(/uid:\//);
expect(secondUri).to.match(/uid:\//);

expect(
cells.toArray().map((cell) => cell.textContent),
).to.deep.equal([
firstUri,
'RoboCop',
'rating',
'[bZE+]',
'',
'n/a',
'Jane Smith',
'This is another comment',
new Date().toLocaleDateString(),
secondUri,
'Terminator 2',
'actors',
'[K8Lu]',
'',
'n/a',
'John Doe',
'This is a comment',
new Date().toLocaleDateString(),
]);
});
});

expect(firstUri).to.match(/uid:\//);
expect(secondUri).to.match(/uid:\//);
it('should hide annotation button when field does not support annotations', () => {
cy.findByRole('button', {
name: `Add an annotation to Liste des films field`,
}).should('not.exist');
});
});
});

describe('charts', () => {
it('should support annotations on charts', () => {
cy.findByRole('link', { name: 'Graphs' }).click();
cy.findByRole('link', {
name: 'Répartition par réalisateurs uniques',
}).click();

annotation.createAnnotation({
fieldLabel: 'Répartition par réalisateurs uniques',
comment: 'This is a comment',
authorName: 'John Doe',
authorEmail: '[email protected]',
});

cy.findByText('More').click();
menu.goToAdminDashboard();
cy.findByText('Annotations').click();

cy.findAllByRole('cell').then((cells) => {
expect(
cells.toArray().map((cell) => cell.textContent),
).to.deep.equal([
firstUri,
'RoboCop',
'rating',
'[bZE+]',
'Chart page',
'',
'n/a',
'Jane Smith',
'This is another comment',
new Date().toLocaleDateString(),
secondUri,
'Terminator 2',
'actors',
'[K8Lu]',
'Répartition par réalisateurs uniques',
'[xkoP]',
'',
'n/a',
'John Doe',
Expand All @@ -108,11 +183,5 @@ describe('Annotation', () => {
]);
});
});

it('should hide annotation button when field does not support annotations', () => {
cy.findByRole('button', {
name: `Add an annotation to Liste des films field`,
}).should('not.exist');
});
});
});
2 changes: 1 addition & 1 deletion docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ services:
resources:
limits:
cpus: '2'
memory: 2G
memory: 4G

dev-server: ## Enable hot-reload in development
image: node:22.12-bookworm
Expand Down
30 changes: 19 additions & 11 deletions src/api/controller/api/annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import Koa from 'koa';
import koaBodyParser from 'koa-bodyparser';
import route from 'koa-route';

import { uniq } from 'lodash';
import { ObjectId } from 'mongodb';
import { createDiacriticSafeContainRegex } from '../../services/createDiacriticSafeContainRegex';
import {
annotationSchema,
getAnnotationsQuerySchema,
} from './../../../common/validator/annotation.validator';
import { uniq } from 'lodash';
import { ObjectId } from 'mongodb';

/**
* @param {Koa.Context} ctx
Expand Down Expand Up @@ -180,7 +180,10 @@ export async function getAnnotations(ctx) {
} = validation.data;

const skip = page * limit;
const titleField = await ctx.field.findTitle();
const [titleField, subResourceTitleFields] = await Promise.all([
ctx.field.findResourceTitle(),
ctx.field.findSubResourceTitles(),
]);

const query = await buildQuery({
filterBy,
Expand All @@ -205,18 +208,23 @@ export async function getAnnotations(ctx) {
uniq(annotations.map(({ resourceUri }) => resourceUri)),
);

const resourceByUri = (resources || []).reduce(
(acc, resource) => ({
const resourceByUri = (resources || []).reduce((acc, resource) => {
const lastVersion = resource.versions[resource.versions.length - 1];
const currentResourceTitleField = resource.subresourceId
? subResourceTitleFields.find(
({ subresourceId }) =>
subresourceId === resource.subresourceId,
)
: titleField;

return {
...acc,
[resource.uri]: {
uri: resource.uri,
title: resource.versions[resource.versions.length - 1][
titleField.name
],
title: lastVersion[currentResourceTitleField?.name],
},
}),
{},
);
};
}, {});

const fieldById = await ctx.field.findManyByIds(
uniq(
Expand Down
Loading

0 comments on commit 81f7e2e

Please sign in to comment.