Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1ba4719
AnnotationView: mark TODO
bwbohl Sep 11, 2025
ca91b00
AnnotationView: use calculated store fields instead of model
bwbohl Sep 11, 2025
68b98cd
AnnotationView: add method for calculating columns
bwbohl Sep 11, 2025
70b4d31
AnnotationView: remove predefined me.list
bwbohl Sep 11, 2025
a8fa7a9
AnnotationView: add method for creating list and store
bwbohl Sep 11, 2025
92de2dd
AnnotationView: add method for loading Annotations and creating compo…
bwbohl Sep 11, 2025
9eb26da
AnnotationView: create method for initializing independent components
bwbohl Sep 11, 2025
06762aa
AnnotationView: add event and property annotationsLoaded
bwbohl Sep 11, 2025
21cae61
AnnotationView: call loadAnnotationsAndCreateComponents afterrender
bwbohl Sep 11, 2025
8b063a8
AnnotationView: remove forgotten event listener
bwbohl Sep 11, 2025
6c69b7b
AnnotationsView: load list store only if defined
bwbohl Sep 11, 2025
2b2d1d2
AnnotationView: showList add check if me.list available
bwbohl Sep 11, 2025
bc5d617
Delete Annotation.js
bwbohl Sep 11, 2025
2616525
AnnotationView: rework column definitions to hide empty columns
bwbohl Sep 12, 2025
6c5a9e3
AnnotationView: getLangString for column headers
bwbohl Sep 12, 2025
63fc0fc
AnnotationView: add default column definition for `id`
bwbohl Sep 12, 2025
8c6885d
AnnotationView: readd default column definition for title
bwbohl Sep 12, 2025
9042669
AnnotationView: improve styling of pos column
bwbohl Sep 12, 2025
ee628c2
AnnotationView controller: remove unneeded AJAXRequest parameters
bwbohl Sep 12, 2025
5c30d00
AnnotationView: improve MVC separation of view and controller
bwbohl Sep 15, 2025
2f8cfe6
AnnotationView: do not set column visible if already hidden in defaul…
bwbohl Sep 16, 2025
80ad822
AnnotationView controller: add debug log
bwbohl Sep 18, 2025
f3e8859
AnnotationView: handle undefined emptyFields
bwbohl Sep 18, 2025
bd504d7
AnnotationView: handle annotation entries/fields with dots in their …
bwbohl Sep 18, 2025
2bad784
annotation.scss: apply text-align tight to .annotationList .pos desce…
bwbohl Sep 19, 2025
88a9ea7
annotationView styling: move todo.css rules to annotation.scss
bwbohl Sep 19, 2025
98f88ed
todo.css: delete unapplied rule for .annotView .contentBox
bwbohl Sep 19, 2025
b265b24
AnnotationView: remove duplicate cls property
bwbohl Sep 19, 2025
2c760a8
Update CITATION.cff commit and date-released [skip ci]
github-actions[bot] Feb 5, 2026
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
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ identifiers:
value: 10.5281/zenodo.17977921
description: Edirom Online Frontend
repository-code: https://github.com/Edirom/Edirom-Online-Frontend
commit: 65d6487474bb360ba17c6c645cd4e2c2f73bb516
commit: b265b241e4fe202ba5189c909390e95aba795b2c
abstract: >-
Edirom Online Frontend is the frontend for the Edirom
Online which is used for the presentation and
analysis of critical musical editions in a digital format,
particularly in the fields of musicology and philology.
license: GPL-3.0
version: v1.2.0
date-released: 2026-01-19
date-released: 2026-02-05
242 changes: 229 additions & 13 deletions app/controller/window/AnnotationView.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ Ext.define('EdiromOnline.controller.window.AnnotationView', {
this.control({
'annotationView': {
afterlayout : this.onAfterLayout,
showAnnotation: this.onShowAnnotation
showAnnotation: this.onShowAnnotation,
loadAnnotations: this.onLoadAnnotations,
loadParticipantSingleContent: this.onLoadParticipantSingleContent
},
'annotationView button[action=openAll]': {
click: this.onOpenAllParticipants
Expand All @@ -51,15 +53,10 @@ Ext.define('EdiromOnline.controller.window.AnnotationView', {

onShowAnnotation: function(view, uri) {

var editionId = this.application.activeEdition;
var lang = getPreference('application_language');

window.doAJAXRequest('data/xql/getAnnotationText.xql',
'GET',
{
uri: uri,
lang: lang,
edition: EdiromOnline.getApplication().activeEdition
uri: uri
},
Ext.bind(function(response){
view.setContent(response.responseText);
Expand All @@ -69,9 +66,7 @@ Ext.define('EdiromOnline.controller.window.AnnotationView', {
window.doAJAXRequest('data/xql/getAnnotationMeta.xql',
'GET',
{
uri: uri,
lang: lang,
edition: EdiromOnline.getApplication().activeEdition
uri: uri
},

Ext.bind(function(response){
Expand All @@ -82,9 +77,7 @@ Ext.define('EdiromOnline.controller.window.AnnotationView', {
window.doAJAXRequest('data/xql/getAnnotationPreviews.xql',
'GET',
{
uri: uri,
lang: lang,
edition: EdiromOnline.getApplication().activeEdition
uri: uri
},
Ext.bind(function(response){
var data = Ext.JSON.decode(response.responseText);
Expand Down Expand Up @@ -140,5 +133,228 @@ Ext.define('EdiromOnline.controller.window.AnnotationView', {
});

btn.windows = null;
},

onLoadAnnotations: function(view) {
this.loadAnnotationsAndCreateComponents(view);
},

onLoadParticipantSingleContent: function(view) {
this.loadParticipantSingleContent(view);
},

loadAnnotationsAndCreateComponents: function(view) {
var me = this;

// Show loading mask while loading data
view.setLoading('Loading annotations...');

window.doAJAXRequest(
'data/xql/getAnnotations.xql',
'GET',
{
uri: view.uri
},
Ext.bind(function(response) {
var data = Ext.JSON.decode(response.responseText);

// Store the loaded data
view.data = data;
view.annotations = data.annotations;
view.annotationsLoaded = true;

if(typeof(debug) !== 'undefined' && debug !== null && debug) {
console.log('view: AnnotationView: ajax callback');
console.log(view);
console.log(data);
console.log(data.annotations);
console.log(data.emptyFields);
}

// Now create the list and store that depend on the loaded data
me.createListAndStore(view, data.annotations, me.getStoreFieldsDefinition(view), data.emptyFields);

// Add the list to the card layout at index 0
view.insert(0, view.list);

// Set the list as the active item initially
view.getLayout().setActiveItem(view.list);

// Hide loading mask
view.setLoading(false);

// Fire the event to notify that annotations are loaded
view.fireEvent('annotationsLoaded', view, view.uri, data);

console.log('Annotations loaded and components created');
console.log(view);
}, me),
Ext.bind(function(response) {
// Error handling
view.setLoading(false);
Ext.Msg.alert('Error', 'Failed to load annotations');
}, me)
);
},

createStore: function(view) {
var me = this;

view.listStore = Ext.create('Ext.data.Store', {
//model: 'EdiromOnline.model.Annotation',
fields: me.getStoreFieldsDefinition(view),
proxy: {
reader: {
type: 'json',
useSimpleAccessors: false
}
},
autoLoad: false
});

view.listStore.getProxy().extraParams = {
uri: view.uri,
lang: getPreference('application_language'),
edition: EdiromOnline.getApplication().activeEdition
};

return view.listStore;
},

createListAndStore: function(view, annotations, storeFields, emptyFields) {
var me = this;

if(typeof(debug) !== 'undefined' && debug !== null && debug) {
console.log('view: AnnotationView: createListAndStore');
console.log(view.annotations);
console.log(storeFields);
console.log(emptyFields);
}

// Create list Store
view.listStore = Ext.create('Ext.data.Store', {
fields: storeFields,
autoLoad: false,
data: annotations
});

// Create the annotation list
view.list = Ext.create('Ext.grid.Panel', {
store: view.listStore,
title: getLangString('view.window.AnnotationView_Title'),
bodyBorder: false,
border: '0 0 0 0',
cls: 'annotationList',
features: [{
ftype: 'filters',
encode: false,
local: true,
filters: []
}],
columns: view.getColumns(storeFields, emptyFields)
});

// Add event listener for double click
view.list.on('itemdblclick', view.onItemDblClicked, view);

if(typeof(debug) !== 'undefined' && debug !== null && debug) {
console.log('view: AnnotationView: createList final');
console.log(view.list);
}
},

getStoreFieldsDefinition: function(view) {
var me = this;

if(typeof(debug) !== 'undefined' && debug !== null && debug) {
console.log('view: AnnotationView: getStoreFieldsDefinition:');
console.log(view);
console.log(view.data);
console.log(view.annotations);
}

// initialise fields variable, setting default fields
var fields = [
'id',
'sigla',
// create an integer field with the name pos for sorting in document-order
{
name: 'pos',
type: 'int'
}//,
//{name: "bazga.annotation", mapping: 'properties["bazga.annotation"]'}
];

// Only proceed if data is loaded
if (!view.data || !view.data.fields) {
return fields; // Return default fields if data not loaded yet
}

// create fields config
// get the existing field names from the above fields array
var existingFieldNames = fields.map(field =>
typeof field === 'string' ? field : field.name
);

// Iterate over data.fields and add missing ones to fields variable
view.data.fields.forEach(fieldName => {
if (!existingFieldNames.includes(fieldName)) {
var fieldDef = {
name: fieldName,
mapping: me.createFieldMapping(fieldName)
};
fields.push(fieldDef);
}
});

if(typeof(debug) !== 'undefined' && debug !== null && debug) {
console.log('view: AnnotationView: getStoreFieldsDefinition: return fields');
console.log(fields);
}

return fields;
},

createFieldMapping: function(fieldName) {
// Handle fields with dots by using a custom mapping function
// ExtJS interprets dots as nested object access, so we need bracket notation
if (fieldName.includes('.')) {
return function(data) {
return data[fieldName];
};
}
return fieldName;
},

loadStore: function(view) {
var me = this;
if(view.listStore) {
view.listStore.load();
}
},

loadParticipantSingleContent: function(view) {
var me = this;

var contEl = view.el.getById(view.id + '_annotationParticipantsSingle');
var previewTxtData = contEl.query('input.previewTxtData');

if (previewTxtData.length == 0) return;

var txtData = previewTxtData[0].value;
var uri = txtData.match(/uri:(.*)__\$\$__/)[1];
var id = txtData.match(/__\$\$__participantId:(.*)/)[1];

window.doAJAXRequest('data/xql/getReducedDocument.xql?uri=' + uri + '&selectionId=' + id + '&subtreeRoot=div&idPrefix=' + view.id + '_',
'GET',
{},
Ext.bind(function(response){
var contEl = view.el.getById(view.id + '_annotationParticipantsSingle');
var txtBox = new Ext.Element(contEl.query('div.txtBox')[0]);
txtBox.update(response.responseText);

contEl.query('#' + view.id + '_' + id)[0].scrollIntoView(txtBox);
}, me)
);
}
});
53 changes: 0 additions & 53 deletions app/model/Annotation.js

This file was deleted.

Loading