mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-11-15 09:15:41 +00:00
first change with new MVCish pattern
This commit is contained in:
parent
dabeb818d1
commit
0507ae4e34
@ -30,7 +30,7 @@ def init_corpus_analysis(corpus_id):
|
|||||||
corpus_id, current_user.id, request.sid)
|
corpus_id, current_user.id, request.sid)
|
||||||
|
|
||||||
|
|
||||||
@socketio.on('corpus_analysis_get_meta_data')
|
@socketio.on('corpus_analysis_meta_data')
|
||||||
@socketio_login_required
|
@socketio_login_required
|
||||||
def corpus_analysis_get_meta_data(corpus_id):
|
def corpus_analysis_get_meta_data(corpus_id):
|
||||||
# get meta data from db
|
# get meta data from db
|
||||||
@ -69,7 +69,7 @@ def corpus_analysis_get_meta_data(corpus_id):
|
|||||||
payload = metadata
|
payload = metadata
|
||||||
response = {'code': 200, 'desc': 'Corpus meta data', 'msg': 'OK',
|
response = {'code': 200, 'desc': 'Corpus meta data', 'msg': 'OK',
|
||||||
'payload': payload}
|
'payload': payload}
|
||||||
socketio.emit('corpus_analysis_send_meta_data', response, room=request.sid)
|
socketio.emit('corpus_analysis_meta_data', response, room=request.sid)
|
||||||
|
|
||||||
|
|
||||||
@socketio.on('corpus_analysis_query')
|
@socketio.on('corpus_analysis_query')
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* This class is used to create a Client object.
|
* This class is used to create a Client object.
|
||||||
* The client handels the client server communication.
|
* The client handels the client server communication.
|
||||||
* It requests data (e.g. the analysis session or query results) from the
|
* It communicates with the server (e.g. connection or query)
|
||||||
* the server and recieves them, if it dynamicMode is true.
|
* and recieves data from it, if dynamicMode is true.
|
||||||
* If dynamicMode is false, the client can also handle data that is already
|
* If dynamicMode is false, the client can also handle data that is already
|
||||||
* loaded and not coming in in chunks.
|
* loaded and is not coming in in chunks.
|
||||||
*/
|
*/
|
||||||
class Client {
|
class Client {
|
||||||
constructor({corpusId = null,
|
constructor({corpusId = null,
|
||||||
@ -12,16 +12,18 @@ class Client {
|
|||||||
logging = true,
|
logging = true,
|
||||||
dynamicMode = true} = {}) {
|
dynamicMode = true} = {}) {
|
||||||
this.corpusId = corpusId;
|
this.corpusId = corpusId;
|
||||||
this.displays = {};
|
|
||||||
this.dynamicMode = dynamicMode;
|
this.dynamicMode = dynamicMode;
|
||||||
this.logging = logging;
|
this.logging = logging;
|
||||||
this.requestQueryProgress = 0;
|
this.requestQueryProgress = 0;
|
||||||
this.results = undefined; // holds the results object later on
|
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
this.socketEventListeners = {};
|
this.socketEventListeners = {};
|
||||||
|
this.recivedMetaData = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable all console logging.
|
* Disable all console logging.
|
||||||
|
* This is global. So every other log message in every other Class or
|
||||||
|
* function used in conjunction with the client either logs or does not
|
||||||
|
* log depending on the logging flag.
|
||||||
* Credits to https://gist.github.com/kmonsoor/0244fdb4ad79a4826371e58a1a5fa984
|
* Credits to https://gist.github.com/kmonsoor/0244fdb4ad79a4826371e58a1a5fa984
|
||||||
*/
|
*/
|
||||||
if (!logging) {
|
if (!logging) {
|
||||||
@ -37,6 +39,7 @@ class Client {
|
|||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
console.info("Client initialized:", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registers one or more SocketEventListeners to the Client.
|
// Registers one or more SocketEventListeners to the Client.
|
||||||
@ -56,10 +59,10 @@ class Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
// TODO: get rid of this disply stuff and send commands to the viewer
|
* This functions sends events to the View to trigger specific functions that
|
||||||
// on what to do/show/hide etc
|
* are handleing the represnetation of data stored in the model.
|
||||||
|
*/
|
||||||
notifyView(SendWhatToDo) {
|
notifyView(SendWhatToDo) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -108,6 +111,12 @@ class Client {
|
|||||||
this.socket.emit('corpus_analysis_init', this.corpusId);
|
this.socket.emit('corpus_analysis_init', this.corpusId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMetaData() {
|
||||||
|
console.info('corpus_analysis_meta_data: Client getting meta data via',
|
||||||
|
'socket.emit.');
|
||||||
|
this.socket.emit('corpus_analysis_meta_data', this.corpusId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emits query to the server via socket.io. Server will send the results
|
* Emits query to the server via socket.io. Server will send the results
|
||||||
* back.
|
* back.
|
||||||
@ -119,80 +128,6 @@ class Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is used to create an CorpusAnalysisDisplay object.
|
|
||||||
* Input is one HTMLElement that can then be hidden or shown depending on
|
|
||||||
* its CSS classes.
|
|
||||||
*/
|
|
||||||
class CorpusAnalysisDisplay {
|
|
||||||
constructor(element) {
|
|
||||||
// with this function initalized modals can also be handeld
|
|
||||||
this.element = (() => {if (element instanceof HTMLElement) {
|
|
||||||
return element;
|
|
||||||
} else {
|
|
||||||
element = element['$el'][0];
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
this.errorContainer = element.querySelector('.error-container');
|
|
||||||
this.showOnError = element.querySelectorAll('.show-on-error');
|
|
||||||
this.showOnSuccess = element.querySelectorAll('.show-on-success');
|
|
||||||
this.showWhileWaiting = element.querySelectorAll('.show-while-waiting');
|
|
||||||
this.hideOnComplete = element.querySelectorAll('.hide-on-complete')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Changes the visibility of its own
|
|
||||||
setVisibilityByStatus(status) {
|
|
||||||
switch (status) {
|
|
||||||
case 'error':
|
|
||||||
for (let element of this.showOnError) {
|
|
||||||
element.classList.remove('hide');
|
|
||||||
}
|
|
||||||
for (let element of this.showOnSuccess) {
|
|
||||||
element.classList.add('hide');
|
|
||||||
}
|
|
||||||
for (let element of this.showWhileWaiting) {
|
|
||||||
element.classList.add('hide');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'success':
|
|
||||||
for (let element of this.showOnError) {
|
|
||||||
element.classList.add('hide');
|
|
||||||
|
|
||||||
}
|
|
||||||
for (let element of this.showOnSuccess) {
|
|
||||||
element.classList.remove('hide');
|
|
||||||
}
|
|
||||||
for (let element of this.showWhileWaiting) {
|
|
||||||
element.classList.add('hide');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'waiting':
|
|
||||||
for (let element of this.showOnError) {
|
|
||||||
element.classList.add('hide');
|
|
||||||
}
|
|
||||||
for (let element of this.showOnSuccess) {
|
|
||||||
element.classList.add('hide');
|
|
||||||
}
|
|
||||||
for (let element of this.showWhileWaiting) {
|
|
||||||
element.classList.remove('hide');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// Hide all
|
|
||||||
for (let element of this.showOnError) {
|
|
||||||
element.classList.add('hide');
|
|
||||||
}
|
|
||||||
for (let element of this.showOnSuccess) {
|
|
||||||
element.classList.add('hide');
|
|
||||||
}
|
|
||||||
for (let element of this.showWhileWaiting) {
|
|
||||||
element.classList.add('hide');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used to create an SocketEventListener.
|
* This class is used to create an SocketEventListener.
|
||||||
* Input are an identifying type string, the listener function and callbacks
|
* Input are an identifying type string, the listener function and callbacks
|
||||||
@ -200,7 +135,7 @@ class CorpusAnalysisDisplay {
|
|||||||
* type string is also used as the socket event event identifier.
|
* type string is also used as the socket event event identifier.
|
||||||
*/
|
*/
|
||||||
class SocketEventListener {
|
class SocketEventListener {
|
||||||
constructor(type, listenerFunction) {
|
constructor(type, listenerFunction, args=null) {
|
||||||
this.listenerCallbacks = {};
|
this.listenerCallbacks = {};
|
||||||
this.listenerFunction = listenerFunction;
|
this.listenerFunction = listenerFunction;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
@ -222,9 +157,10 @@ class SocketEventListener {
|
|||||||
* yield the keys in order of insertion.
|
* yield the keys in order of insertion.
|
||||||
* So all modern Browsers.
|
* So all modern Browsers.
|
||||||
*/
|
*/
|
||||||
executeCallbacks(args) {
|
executeCallbacks(payload) {
|
||||||
for (let [type, listenerCallback] of Object.entries(this.listenerCallbacks)) {
|
for (let [type, listenerCallback] of Object.entries(this.listenerCallbacks)) {
|
||||||
listenerCallback.callbackFunction(...args);
|
listenerCallback.args.unshift(payload);
|
||||||
|
listenerCallback.callbackFunction(...listenerCallback.args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -235,7 +171,8 @@ class SocketEventListener {
|
|||||||
* callback functions.
|
* callback functions.
|
||||||
*/
|
*/
|
||||||
class ListenerCallback {
|
class ListenerCallback {
|
||||||
constructor(type, callbackFunction) {
|
constructor(type, callbackFunction, argsList) {
|
||||||
|
this.args = argsList;
|
||||||
this.callbackFunction = callbackFunction;
|
this.callbackFunction = callbackFunction;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
@ -245,6 +182,5 @@ class ListenerCallback {
|
|||||||
export {
|
export {
|
||||||
Client,
|
Client,
|
||||||
SocketEventListener,
|
SocketEventListener,
|
||||||
CorpusAnalysisDisplay,
|
|
||||||
ListenerCallback,
|
ListenerCallback,
|
||||||
};
|
};
|
@ -1,9 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* This callback is called on a socket.on "corpus_analysis_send_meta_data".
|
||||||
|
* Handels incoming corpus metadata
|
||||||
|
*/
|
||||||
|
function saveMetaData() {
|
||||||
|
let [payload, client, results, rest] = arguments;
|
||||||
|
results.metaData.init(payload)
|
||||||
|
client.recivedMetaData = true;
|
||||||
|
console.info('Metada saved:', results.metaData);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This callback should be registered to the SocketEventListener 'recieveQueryStatus'.
|
* This callback should be registered to the SocketEventListener 'recieveQueryStatus'.
|
||||||
* It just gets the incoming status data of the issued query
|
* It just gets the incoming status data of the issued query
|
||||||
* and does some preperation work like hiding or showing elements and deleting
|
* and does some preperation work like hiding or showing elements and deleting
|
||||||
* the data from the last query.
|
* the data from the last query.
|
||||||
*/
|
*/
|
||||||
|
function prepareQueryData() {
|
||||||
|
// deletes old data from query issued before this new query
|
||||||
|
let [payload, client, results, rest] = arguments;
|
||||||
|
results.init();
|
||||||
|
client.requestQueryProgress = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveQueryData(args) {
|
||||||
|
let [payload, client, results, rest] = arguments;
|
||||||
|
results.data.addData(payload);
|
||||||
|
client.requestQueryProgress = payload.progress;
|
||||||
|
console.info('Query data chunk saved', results.data);
|
||||||
|
}
|
||||||
|
|
||||||
function querySetup(payload, client) {
|
function querySetup(payload, client) {
|
||||||
// deletes old data from query issued before this new query
|
// deletes old data from query issued before this new query
|
||||||
client.results.clearAll();
|
client.results.clearAll();
|
||||||
@ -12,7 +38,6 @@ function querySetup(payload, client) {
|
|||||||
'#recieved-match-count', '#total-match-count',
|
'#recieved-match-count', '#total-match-count',
|
||||||
'#text-lookup-count', '#text-lookup-titles',
|
'#text-lookup-count', '#text-lookup-titles',
|
||||||
'#query-results-create', '#add-to-sub-results']);
|
'#query-results-create', '#add-to-sub-results']);
|
||||||
client.requestQueryProgress = 0;
|
|
||||||
client.recievedMatchCount.textContent = 0;
|
client.recievedMatchCount.textContent = 0;
|
||||||
client.totalMatchCount.textContent = `${payload.match_count}`;
|
client.totalMatchCount.textContent = `${payload.match_count}`;
|
||||||
client.queryResultsUserFeedback.classList.toggle('hide');
|
client.queryResultsUserFeedback.classList.toggle('hide');
|
||||||
@ -117,4 +142,4 @@ function helperQueryRenderResults (payload, client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// export callbacks
|
// export callbacks
|
||||||
export { querySetup, queryRenderResults };
|
export { prepareQueryData, saveMetaData, saveQueryData };
|
@ -1,40 +1,57 @@
|
|||||||
import { querySetup, queryRenderResults } from './nopaque.listenerCallbacks.js'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recieves a corpus analysis session via socket.io.
|
* Recieves a corpus analysis connected signal via socket.io.
|
||||||
* Closes the loading modal that has been opend with requestSession at the
|
|
||||||
* start of the request.
|
|
||||||
*/
|
*/
|
||||||
function recieveSession(type, client) {
|
function recieveConnected(type, client) {
|
||||||
client.socket.on(type, (response) => {
|
client.socket.on(type, (response) => {
|
||||||
/**
|
/**
|
||||||
* Check if request for session was OK.
|
* Check if request for session was OK.
|
||||||
* If OK execute callbacks and hide/show displays.
|
* If OK execute registered callbacks and notify View.
|
||||||
*/
|
*/
|
||||||
console.group('recieve session')
|
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
console.info('corpus_analysis_init: Client recieving session/or error',
|
console.group('Connected!')
|
||||||
|
console.info('corpus_analysis_init: Client recieving connected codes',
|
||||||
'codes via socket.on');
|
'codes via socket.on');
|
||||||
console.info(`corpus_analysis_init: ${response.code} - ${response.msg}`);
|
console.info(`corpus_analysis_init: ${response.code} - ${response.msg}`);
|
||||||
console.info('corpus_analysis_init: Initialization succeeded');
|
console.info('corpus_analysis_init: Initialization succeeded');
|
||||||
console.info(response);
|
console.info(response);
|
||||||
// Handling hide/show of displays
|
console.groupEnd();
|
||||||
if (client.displays.init != undefined) {
|
// get meta data immediately
|
||||||
client.displays.init.element.M_Modal.close();
|
client.getMetaData();
|
||||||
client.displays.init.setVisibilityByStatus('success');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let errorText = `Error ${response.code} - ${response.msg}`;
|
let errorText = `Error ${response.code} - ${response.msg}`;
|
||||||
if (client.displays.init.errorContainer != undefined) {
|
console.group('Connection failed!')
|
||||||
client.displays.init.errorContainer.innerHTML = `<p class="red-text">`
|
|
||||||
+ `<i class="material-icons tiny">error</i>${errorText}</p>`;
|
|
||||||
}
|
|
||||||
if (client.displays.init != undefined) {
|
|
||||||
client.displays.init.setVisibilityByStatus('error');
|
|
||||||
}
|
|
||||||
console.error(`corpus_analysis_init: ${errorText}`);
|
console.error(`corpus_analysis_init: ${errorText}`);
|
||||||
}
|
|
||||||
console.groupEnd();
|
console.groupEnd();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recieves meta data from the server via socket.io.
|
||||||
|
*/
|
||||||
|
function recieveMetaData(type, client) {
|
||||||
|
client.socket.on(type, (response) => {
|
||||||
|
/**
|
||||||
|
* Check if request for session was OK.
|
||||||
|
* If OK execute registered callbacks and notify View.
|
||||||
|
*/
|
||||||
|
if (response.code === 200) {
|
||||||
|
console.group('Client recieving meta data')
|
||||||
|
console.info('corpus_analysis_meta_data: Client recieving meta data',
|
||||||
|
'via socket.on');
|
||||||
|
console.info(`corpus_analysis_meta_data: ${response.code} - ${response.msg}`);
|
||||||
|
console.info(response);
|
||||||
|
// executing the registered callbacks
|
||||||
|
client.socketEventListeners[type].executeCallbacks(response.payload);
|
||||||
|
console.groupEnd();
|
||||||
|
} else {
|
||||||
|
console.group('Failed to recieve meta data.');
|
||||||
|
console.error('corpus_analysis_meta_data: Client failed to recieve',
|
||||||
|
'meta data via socket.on');
|
||||||
|
let errorText = `Error ${response.payload.code} - ${response.payload.msg}`;
|
||||||
|
console.error(`corpus_analysis_meta_data: ${errorText}`);
|
||||||
|
console.groupEnd();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,36 +64,27 @@ function recieveSession(type, client) {
|
|||||||
function recieveQueryStatus(type, client) {
|
function recieveQueryStatus(type, client) {
|
||||||
client.socket.on(type, (response) => {
|
client.socket.on(type, (response) => {
|
||||||
/**
|
/**
|
||||||
* Check if issued query was OK.
|
* Check if request for session was OK.
|
||||||
* If OK execute registered callbacks and hide/show displays.
|
* If OK execute registered callbacks and notify View.
|
||||||
*/
|
*/
|
||||||
|
if (response.code === 200) {
|
||||||
console.group('corpus_analysis_query: Client recieving query process',
|
console.group('corpus_analysis_query: Client recieving query process',
|
||||||
'status via socket.on');
|
'status via socket.on');
|
||||||
if (response.code === 200) {
|
|
||||||
console.info(`corpus_analysis_query: ${response.code} - ${response.msg}`);
|
console.info(`corpus_analysis_query: ${response.code} - ${response.msg}`);
|
||||||
console.info(response);
|
console.info(response);
|
||||||
// Handling hide/show of displays
|
|
||||||
if (client.displays.query != undefined) {
|
|
||||||
client.displays.query.setVisibilityByStatus("success");
|
|
||||||
}
|
|
||||||
// executing the registered callbacks
|
// executing the registered callbacks
|
||||||
client.socketEventListeners[type].executeCallbacks([response.payload, client]);
|
client.socketEventListeners[type].executeCallbacks(response.payload);
|
||||||
|
console.groupEnd();
|
||||||
} else {
|
} else {
|
||||||
|
console.group('corpus_analysis_query: Client failed recieving',
|
||||||
|
'query process status via socket.on');
|
||||||
let errorText = `Error ${response.payload.code} - ${response.payload.msg}`;
|
let errorText = `Error ${response.payload.code} - ${response.payload.msg}`;
|
||||||
if (response.payload.code == 1281) {
|
if (response.payload.code == 1281) {
|
||||||
errorText += ' - Invalid Query';
|
errorText += ' - Invalid Query';
|
||||||
}
|
}
|
||||||
nopaque.flash(errorText, "error");
|
|
||||||
if (client.displays.query.errorContainer != undefined) {
|
|
||||||
client.displays.query.errorContainer.innerHTML = `<p class="red-text">`+
|
|
||||||
`<i class="material-icons tiny">error</i> ${errorText}</p>`;
|
|
||||||
}
|
|
||||||
if (client.displays.query != undefined) {
|
|
||||||
client.displays.query.setVisibilityByStatus("error");
|
|
||||||
}
|
|
||||||
console.error(`corpus_analysis_query: ${errorText}`);
|
console.error(`corpus_analysis_query: ${errorText}`);
|
||||||
}
|
|
||||||
console.groupEnd();
|
console.groupEnd();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,24 +92,43 @@ function recieveQueryStatus(type, client) {
|
|||||||
* Recieves the query data from the request and handles it.
|
* Recieves the query data from the request and handles it.
|
||||||
*/
|
*/
|
||||||
function recieveQueryData(type, client) {
|
function recieveQueryData(type, client) {
|
||||||
console.group('corpus_analysis_query_results: Client recieving or loading',
|
/**
|
||||||
'query data.');
|
* Check if request for session was OK.
|
||||||
|
* If OK execute registered callbacks and notify View.
|
||||||
|
*/
|
||||||
if (client.dynamicMode) {
|
if (client.dynamicMode) {
|
||||||
console.info('Client recieving query data via socket.on');
|
|
||||||
client.socket.on(type, (response) => {
|
client.socket.on(type, (response) => {
|
||||||
|
if (response.code === 200) {
|
||||||
|
console.group('corpus_analysis_query_results: Recieveing query data')
|
||||||
|
console.info('Client recieving query data via socket.on');
|
||||||
console.info('Recieved chunk', response);
|
console.info('Recieved chunk', response);
|
||||||
// executing the registered callbacks
|
/**
|
||||||
client.socketEventListeners[type].executeCallbacks([response.payload, client]);
|
* Execute registered callbacks and notify View.
|
||||||
console.info('Added chunk data to results.data and rendered it with',
|
*/
|
||||||
'results.jsList');
|
client.socketEventListeners[type].executeCallbacks(response.payload);
|
||||||
|
console.info('Added chunk data to results.data.');
|
||||||
|
console.groupEnd();
|
||||||
|
} else {
|
||||||
|
console.group('corpus_analysis_query_results: Client failed recieving',
|
||||||
|
'the results via socket.on');
|
||||||
|
let errorText = `Error ${response.payload.code} - ${response.payload.msg}`;
|
||||||
|
console.error(`corpus_analysis_query: ${errorText}`);
|
||||||
|
console.groupEnd();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
console.group('corpus_analysis_query_results: Loading query data.')
|
||||||
console.info('Client loading imported query data from database.');
|
console.info('Client loading imported query data from database.');
|
||||||
// executing the registered callbacks
|
// executing the registered callbacks
|
||||||
client.socketEventListeners[type].executeCallbacks([client.results.data, client]);
|
client.socketEventListeners[type].executeCallbacks();
|
||||||
}
|
|
||||||
console.groupEnd();
|
console.groupEnd();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// export listeners from this module
|
// export listeners from this module
|
||||||
export { recieveSession, recieveQueryStatus, recieveQueryData };
|
export {
|
||||||
|
recieveConnected,
|
||||||
|
recieveMetaData,
|
||||||
|
recieveQueryStatus,
|
||||||
|
recieveQueryData
|
||||||
|
};
|
@ -5,17 +5,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class Results {
|
class Results {
|
||||||
constructor(data, jsList , metaData) {
|
constructor() {
|
||||||
this.data = data;
|
this.data = new Data();
|
||||||
this.jsList = jsList;
|
this.metaData = new MetaData();
|
||||||
this.metaData = metaData
|
|
||||||
this.resultsData = new Data();
|
this.resultsData = new Data();
|
||||||
this.subResultsData = new Data();
|
this.subResultsData = new Data();
|
||||||
|
console.info('Initialized the Results object.');
|
||||||
}
|
}
|
||||||
|
|
||||||
clearAll() {
|
init() {
|
||||||
this.jsList.clear();
|
|
||||||
this.jsList.update();
|
|
||||||
this.data.init();
|
this.data.init();
|
||||||
this.metaData.init();
|
this.metaData.init();
|
||||||
this.resultsData.init()
|
this.resultsData.init()
|
||||||
|
73
web/app/static/js/modules/corpus_analysis/view/Display.js
Normal file
73
web/app/static/js/modules/corpus_analysis/view/Display.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* This class is used to create an Display object.
|
||||||
|
* Input is one HTMLElement that can then be hidden or shown depending on
|
||||||
|
* its CSS classes.
|
||||||
|
*/
|
||||||
|
class Display {
|
||||||
|
constructor(element) {
|
||||||
|
// with this function initalized modals can also be handeld
|
||||||
|
this.element = (() => {if (element instanceof HTMLElement) {
|
||||||
|
return element;
|
||||||
|
} else {
|
||||||
|
element = element['$el'][0];
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
this.errorContainer = element.querySelector('.error-container');
|
||||||
|
this.showOnError = element.querySelectorAll('.show-on-error');
|
||||||
|
this.showOnSuccess = element.querySelectorAll('.show-on-success');
|
||||||
|
this.showWhileWaiting = element.querySelectorAll('.show-while-waiting');
|
||||||
|
this.hideOnComplete = element.querySelectorAll('.hide-on-complete')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Changes the visibility of its own
|
||||||
|
setVisibilityByStatus(status) {
|
||||||
|
switch (status) {
|
||||||
|
case 'error':
|
||||||
|
for (let element of this.showOnError) {
|
||||||
|
element.classList.remove('hide');
|
||||||
|
}
|
||||||
|
for (let element of this.showOnSuccess) {
|
||||||
|
element.classList.add('hide');
|
||||||
|
}
|
||||||
|
for (let element of this.showWhileWaiting) {
|
||||||
|
element.classList.add('hide');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'success':
|
||||||
|
for (let element of this.showOnError) {
|
||||||
|
element.classList.add('hide');
|
||||||
|
|
||||||
|
}
|
||||||
|
for (let element of this.showOnSuccess) {
|
||||||
|
element.classList.remove('hide');
|
||||||
|
}
|
||||||
|
for (let element of this.showWhileWaiting) {
|
||||||
|
element.classList.add('hide');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'waiting':
|
||||||
|
for (let element of this.showOnError) {
|
||||||
|
element.classList.add('hide');
|
||||||
|
}
|
||||||
|
for (let element of this.showOnSuccess) {
|
||||||
|
element.classList.add('hide');
|
||||||
|
}
|
||||||
|
for (let element of this.showWhileWaiting) {
|
||||||
|
element.classList.remove('hide');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Hide all
|
||||||
|
for (let element of this.showOnError) {
|
||||||
|
element.classList.add('hide');
|
||||||
|
}
|
||||||
|
for (let element of this.showOnSuccess) {
|
||||||
|
element.classList.add('hide');
|
||||||
|
}
|
||||||
|
for (let element of this.showWhileWaiting) {
|
||||||
|
element.classList.add('hide');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -65,7 +65,102 @@
|
|||||||
{% include 'modals/export_query_results.html.j2' %}
|
{% include 'modals/export_query_results.html.j2' %}
|
||||||
{% include 'modals/context_modal.html.j2' %}
|
{% include 'modals/context_modal.html.j2' %}
|
||||||
|
|
||||||
<script type="text/javascript"
|
<!-- import modules -->
|
||||||
src="web/app/static/js/modules/corpus_analysis/main.js">
|
<script type="module">
|
||||||
|
/**
|
||||||
|
* First Phase:
|
||||||
|
* Document content is loaded and scripts are being imported and executed.
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
Client,
|
||||||
|
SocketEventListener,
|
||||||
|
ListenerCallback,
|
||||||
|
} from '../../static/js/modules/corpus_analysis/client/Client.js';
|
||||||
|
import {
|
||||||
|
recieveConnected,
|
||||||
|
recieveMetaData,
|
||||||
|
recieveQueryStatus,
|
||||||
|
recieveQueryData,
|
||||||
|
} from '../../static/js/modules/corpus_analysis/client/listeners.js';
|
||||||
|
import {
|
||||||
|
Results,
|
||||||
|
} from '../../static/js/modules/corpus_analysis/model/Results.js';
|
||||||
|
import {
|
||||||
|
prepareQueryData,
|
||||||
|
saveQueryData,
|
||||||
|
saveMetaData,
|
||||||
|
} from '../../static/js/modules/corpus_analysis/client/callbacks.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Second Phase:
|
||||||
|
* Asynchronus and event driven code
|
||||||
|
*/
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
// Initialize the client for server client communication in dynamic mode
|
||||||
|
let corpusId = {{ corpus_id }}
|
||||||
|
const client = new Client({'corpusId': corpusId,
|
||||||
|
'socket': nopaque.socket,
|
||||||
|
'logging': true,
|
||||||
|
'dynamicMode': true});
|
||||||
|
/**
|
||||||
|
* Initializing the results object as a model holding all the data of a query.
|
||||||
|
* Also holds the metadata of one query.
|
||||||
|
*/
|
||||||
|
let results = new Results();
|
||||||
|
/**
|
||||||
|
* Register listeners listening to socket.io events and their callbacks
|
||||||
|
* Afterwards load them.
|
||||||
|
*/
|
||||||
|
const listenForConnected = new SocketEventListener('corpus_analysis_init',
|
||||||
|
recieveConnected);
|
||||||
|
const listenForMetaData = new SocketEventListener('corpus_analysis_meta_data',
|
||||||
|
recieveMetaData);
|
||||||
|
const metaDataCallback = new ListenerCallback('corpus_analysis_meta_data',
|
||||||
|
saveMetaData,
|
||||||
|
[client, results]);
|
||||||
|
listenForMetaData.setCallbacks([metaDataCallback]);
|
||||||
|
const listenForQueryStatus = new SocketEventListener('corpus_analysis_query',
|
||||||
|
recieveQueryStatus);
|
||||||
|
const queryStatusCallback = new ListenerCallback('corpus_analysis_query',
|
||||||
|
prepareQueryData,
|
||||||
|
[client, results]);
|
||||||
|
listenForQueryStatus.setCallbacks([queryStatusCallback]);
|
||||||
|
const listenForQueryData = new SocketEventListener('corpus_analysis_query_results',
|
||||||
|
recieveQueryData);
|
||||||
|
const queryDataCallback = new ListenerCallback('corpus_analysis_query_results',
|
||||||
|
saveQueryData,
|
||||||
|
[client, results]);
|
||||||
|
listenForQueryData.setCallbacks([queryDataCallback]);
|
||||||
|
client.setSocketEventListeners([listenForConnected,
|
||||||
|
listenForQueryStatus,
|
||||||
|
listenForQueryData,
|
||||||
|
listenForMetaData]);
|
||||||
|
client.loadSocketEventListeners();
|
||||||
|
// Connect client to server
|
||||||
|
client.connect();
|
||||||
|
// Send a query and recieve its answer data
|
||||||
|
let queryFormElement = document.getElementById('query-form');
|
||||||
|
queryFormElement.addEventListener('submit', (event) => {
|
||||||
|
try {
|
||||||
|
/**
|
||||||
|
* Selects first page of result list if pagination is already available
|
||||||
|
* from an query submitted before.
|
||||||
|
* This avoids confusion for the user e.g.: The user was on page 24
|
||||||
|
* reviewing the results and issues a new query. He would not see any
|
||||||
|
* results until the new results reach page 24 or he clicks on another
|
||||||
|
* valid result page element from the new pagination.
|
||||||
|
*/
|
||||||
|
let firstPageElement = document.querySelector('a.page');
|
||||||
|
firstPageElement.click();
|
||||||
|
} catch (e) {
|
||||||
|
// No page element is present if first query is submitted.
|
||||||
|
}
|
||||||
|
// Prevent page from reloading on submit
|
||||||
|
event.preventDefault();
|
||||||
|
// Get query string and send query to server
|
||||||
|
results.data.getQueryStr(queryFormElement);
|
||||||
|
client.query(results.data.query);
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Loading…
Reference in New Issue
Block a user