From c7dab5e502ac0037d74f42b0d9b3c8024c06c253 Mon Sep 17 00:00:00 2001
From: Patrick Jentsch
Date: Tue, 10 Oct 2023 11:06:44 +0200
Subject: [PATCH 1/8] intermediate update on displays and forms 1/2
---
app/static/js/ResourceLists/ResourceList.js | 54 ++++---
app/static/js/forms/base-form.js | 138 +++++++++++++++++
app/static/js/forms/index.js | 139 ------------------
app/static/js/resource-displays/index.js | 47 ------
.../js/resource-displays/resource-display.js | 46 ++++++
app/templates/_scripts.html.j2 | 2 +
6 files changed, 216 insertions(+), 210 deletions(-)
create mode 100644 app/static/js/forms/base-form.js
create mode 100644 app/static/js/resource-displays/resource-display.js
diff --git a/app/static/js/ResourceLists/ResourceList.js b/app/static/js/ResourceLists/ResourceList.js
index 6bc6ac1f..97e65d70 100644
--- a/app/static/js/ResourceLists/ResourceList.js
+++ b/app/static/js/ResourceLists/ResourceList.js
@@ -1,31 +1,37 @@
-class ResourceList {
+var ResourceLists = {};
+
+ResourceLists.autoInit = () => {
+ for (let propertyName in ResourceLists) {
+ let property = ResourceLists[propertyName];
+ // Call autoInit of all properties that are subclasses of `ResourceLists.BaseList`.
+ // This does not include `ResourceLists.BaseList` itself.
+ if (property.prototype instanceof ResourceLists.BaseList) {
+ // Check if the static `htmlClass` property is defined.
+ if (property.htmlClass === undefined) {return;}
+ // Gather all HTML elements that have the `this.htmlClass` class
+ // and do not have the `no-autoinit` class.
+ let listElements = document.querySelectorAll(`.${property.htmlClass}:not(.no-autoinit)`);
+ // Create an instance of this class for each display element.
+ for (let listElement of listElements) {new property(listElement);}
+ }
+ }
+};
+
+ResourceLists.defaultOptions = {
+ page: 5,
+ pagination: {
+ innerWindow: 2,
+ outerWindow: 2
+ }
+};
+
+ResourceLists.BaseList = class BaseList {
/* A wrapper class for the list.js list.
* This class is not meant to be used directly, instead it should be used as
* a base class for concrete resource list implementations.
*/
- static autoInit() {
- CorpusList.autoInit();
- CorpusFileList.autoInit();
- JobList.autoInit();
- JobInputList.autoInit();
- JobResultList.autoInit();
- SpaCyNLPPipelineModelList.autoInit();
- TesseractOCRPipelineModelList.autoInit();
- UserList.autoInit();
- AdminUserList.autoInit();
- CorpusFollowerList.autoInit();
- CorpusTextInfoList.autoInit();
- CorpusTokenList.autoInit();
- }
-
- static defaultOptions = {
- page: 5,
- pagination: {
- innerWindow: 2,
- outerWindow: 2
- }
- };
+ static htmlClass;
constructor(listContainerElement, options = {}) {
if ('items' in options) {
@@ -36,7 +42,7 @@ class ResourceList {
}
let _options = Utils.mergeObjectsDeep(
{item: this.item, valueNames: this.valueNames},
- ResourceList.defaultOptions,
+ ResourceLists.defaultOptions,
options
);
this.listContainerElement = listContainerElement;
diff --git a/app/static/js/forms/base-form.js b/app/static/js/forms/base-form.js
new file mode 100644
index 00000000..b8560485
--- /dev/null
+++ b/app/static/js/forms/base-form.js
@@ -0,0 +1,138 @@
+Forms.BaseForm = class BaseForm {
+ static htmlClass;
+
+ constructor(formElement) {
+ this.formElement = formElement;
+ this.eventListeners = {
+ 'requestLoad': []
+ };
+ this.afterRequestListeners = [];
+
+ for (let selectElement of this.formElement.querySelectorAll('select')) {
+ selectElement.removeAttribute('required');
+ }
+
+ this.formElement.addEventListener('submit', (event) => {
+ event.preventDefault();
+ this.submit(event);
+ });
+ }
+
+ addEventListener(eventType, listener) {
+ if (eventType in this.eventListeners) {
+ this.eventListeners[eventType].push(listener);
+ } else {
+ throw `Unknown event type ${eventType}`;
+ }
+ }
+
+ submit(event) {
+ let request = new XMLHttpRequest();
+ let modalElement = Utils.HTMLToElement(
+ `
+
+
+
file_uploadSubmitting...
+
+
+
+
+ `
+ );
+ document.querySelector('#modals').appendChild(modalElement);
+ let modal = M.Modal.init(
+ modalElement,
+ {
+ dismissible: false,
+ onCloseEnd: () => {
+ modal.destroy();
+ modalElement.remove();
+ }
+ }
+ );
+ modal.open();
+
+ // Remove all previous helper text elements that indicate errors
+ let errorHelperTextElements = this.formElement
+ .querySelectorAll('.helper-text[data-helper-text-type="error"]');
+ for (let errorHelperTextElement of errorHelperTextElements) {
+ errorHelperTextElement.remove();
+ }
+
+ // Check if select elements are filled out properly
+ for (let selectElement of this.formElement.querySelectorAll('select')) {
+ if (selectElement.value === '') {
+ let inputFieldElement = selectElement.closest('.input-field');
+ let errorHelperTextElement = Utils.HTMLToElement(
+ 'Please select an option.'
+ );
+ inputFieldElement.appendChild(errorHelperTextElement);
+ inputFieldElement.querySelector('.select-dropdown').classList.add('invalid');
+ modal.close();
+ return;
+ }
+ }
+
+ // Setup abort handling
+ let cancelElement = modalElement.querySelector('.action-button[data-action="cancel"]');
+ cancelElement.addEventListener('click', (event) => {request.abort();});
+
+ // Setup load handling (after the request completed)
+ request.addEventListener('load', (event) => {
+ for (let listener of this.eventListeners['requestLoad']) {
+ listener(event);
+ }
+ if (request.status === 400) {
+ let responseJson = JSON.parse(request.responseText);
+ for (let [inputName, inputErrors] of Object.entries(responseJson.errors)) {
+ let inputFieldElement = this.formElement
+ .querySelector(`input[name$="${inputName}"], select[name$="${inputName}"]`)
+ .closest('.input-field');
+ for (let inputError of inputErrors) {
+ let errorHelperTextElement = Utils.HTMLToElement(
+ `${inputError}`
+ );
+ inputFieldElement.appendChild(errorHelperTextElement);
+ }
+ }
+ }
+ if (request.status === 500) {
+ app.flash('Internal Server Error', 'error');
+ }
+ modal.close();
+ });
+
+ // Setup progress handling
+ let progressBarElement = modalElement.querySelector('.progress > .determinate');
+ request.upload.addEventListener('progress', (event) => {
+ let progress = Math.floor(100 * event.loaded / event.total);
+ progressBarElement.style.width = `${progress}%`;
+ });
+
+ request.open(this.formElement.method, this.formElement.action);
+ request.setRequestHeader('Accept', 'application/json');
+ let formData = new FormData(this.formElement);
+ switch (this.formElement.enctype) {
+ case 'application/x-www-form-urlencoded': {
+ let urlSearchParams = new URLSearchParams(formData);
+ request.send(urlSearchParams);
+ break;
+ }
+ case 'multipart/form-data': {
+ request.send(formData);
+ break;
+ }
+ case 'text/plain': {
+ throw 'enctype "text/plain" is not supported';
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+};
diff --git a/app/static/js/forms/index.js b/app/static/js/forms/index.js
index 0e7529f6..02909448 100644
--- a/app/static/js/forms/index.js
+++ b/app/static/js/forms/index.js
@@ -16,142 +16,3 @@ Forms.autoInit = () => {
}
}
};
-
-Forms.BaseForm = class BaseForm {
- static htmlClass;
-
- constructor(formElement) {
- this.formElement = formElement;
- this.eventListeners = {
- 'requestLoad': []
- };
- this.afterRequestListeners = [];
-
- for (let selectElement of this.formElement.querySelectorAll('select')) {
- selectElement.removeAttribute('required');
- }
-
- this.formElement.addEventListener('submit', (event) => {
- event.preventDefault();
- this.submit(event);
- });
- }
-
- addEventListener(eventType, listener) {
- if (eventType in this.eventListeners) {
- this.eventListeners[eventType].push(listener);
- } else {
- throw `Unknown event type ${eventType}`;
- }
- }
-
- submit(event) {
- let request = new XMLHttpRequest();
- let modalElement = Utils.HTMLToElement(
- `
-
-
-
file_uploadSubmitting...
-
-
-
-
- `
- );
- document.querySelector('#modals').appendChild(modalElement);
- let modal = M.Modal.init(
- modalElement,
- {
- dismissible: false,
- onCloseEnd: () => {
- modal.destroy();
- modalElement.remove();
- }
- }
- );
- modal.open();
-
- // Remove all previous helper text elements that indicate errors
- let errorHelperTextElements = this.formElement
- .querySelectorAll('.helper-text[data-helper-text-type="error"]');
- for (let errorHelperTextElement of errorHelperTextElements) {
- errorHelperTextElement.remove();
- }
-
- // Check if select elements are filled out properly
- for (let selectElement of this.formElement.querySelectorAll('select')) {
- if (selectElement.value === '') {
- let inputFieldElement = selectElement.closest('.input-field');
- let errorHelperTextElement = Utils.HTMLToElement(
- 'Please select an option.'
- );
- inputFieldElement.appendChild(errorHelperTextElement);
- inputFieldElement.querySelector('.select-dropdown').classList.add('invalid');
- modal.close();
- return;
- }
- }
-
- // Setup abort handling
- let cancelElement = modalElement.querySelector('.action-button[data-action="cancel"]');
- cancelElement.addEventListener('click', (event) => {request.abort();});
-
- // Setup load handling (after the request completed)
- request.addEventListener('load', (event) => {
- for (let listener of this.eventListeners['requestLoad']) {
- listener(event);
- }
- if (request.status === 400) {
- let responseJson = JSON.parse(request.responseText);
- for (let [inputName, inputErrors] of Object.entries(responseJson.errors)) {
- let inputFieldElement = this.formElement
- .querySelector(`input[name$="${inputName}"], select[name$="${inputName}"]`)
- .closest('.input-field');
- for (let inputError of inputErrors) {
- let errorHelperTextElement = Utils.HTMLToElement(
- `${inputError}`
- );
- inputFieldElement.appendChild(errorHelperTextElement);
- }
- }
- }
- if (request.status === 500) {
- app.flash('Internal Server Error', 'error');
- }
- modal.close();
- });
-
- // Setup progress handling
- let progressBarElement = modalElement.querySelector('.progress > .determinate');
- request.upload.addEventListener('progress', (event) => {
- let progress = Math.floor(100 * event.loaded / event.total);
- progressBarElement.style.width = `${progress}%`;
- });
-
- request.open(this.formElement.method, this.formElement.action);
- request.setRequestHeader('Accept', 'application/json');
- let formData = new FormData(this.formElement);
- switch (this.formElement.enctype) {
- case 'application/x-www-form-urlencoded': {
- let urlSearchParams = new URLSearchParams(formData);
- request.send(urlSearchParams);
- break;
- }
- case 'multipart/form-data': {
- request.send(formData);
- break;
- }
- case 'text/plain': {
- throw 'enctype "text/plain" is not supported';
- break;
- }
- default: {
- break;
- }
- }
- }
-};
diff --git a/app/static/js/resource-displays/index.js b/app/static/js/resource-displays/index.js
index 1f795c44..4ec7e997 100644
--- a/app/static/js/resource-displays/index.js
+++ b/app/static/js/resource-displays/index.js
@@ -16,50 +16,3 @@ ResourceDisplays.autoInit = () => {
}
}
}
-
-ResourceDisplays.BaseDisplay = class BaseDisplay {
- static htmlClass;
-
- constructor(displayElement) {
- this.displayElement = displayElement;
- this.userId = this.displayElement.dataset.userId;
- this.isInitialized = false;
- if (this.userId) {
- app.subscribeUser(this.userId)
- .then((response) => {
- app.socket.on('PATCH', (patch) => {
- if (this.isInitialized) {this.onPatch(patch);}
- });
- });
- app.getUser(this.userId)
- .then((user) => {
- this.init(user);
- this.isInitialized = true;
- });
- }
- }
-
- init(user) {throw 'Not implemented';}
-
- onPatch(patch) {throw 'Not implemented';}
-
- setElement(element, value) {
- switch (element.tagName) {
- case 'INPUT': {
- element.value = value;
- M.updateTextFields();
- break;
- }
- default: {
- element.innerText = value;
- break;
- }
- }
- }
-
- setElements(elements, value) {
- for (let element of elements) {
- this.setElement(element, value);
- }
- }
-};
diff --git a/app/static/js/resource-displays/resource-display.js b/app/static/js/resource-displays/resource-display.js
new file mode 100644
index 00000000..81fcda5d
--- /dev/null
+++ b/app/static/js/resource-displays/resource-display.js
@@ -0,0 +1,46 @@
+ResourceDisplays.BaseDisplay = class BaseDisplay {
+ static htmlClass;
+
+ constructor(displayElement) {
+ this.displayElement = displayElement;
+ this.userId = this.displayElement.dataset.userId;
+ this.isInitialized = false;
+ if (this.userId) {
+ app.subscribeUser(this.userId)
+ .then((response) => {
+ app.socket.on('PATCH', (patch) => {
+ if (this.isInitialized) {this.onPatch(patch);}
+ });
+ });
+ app.getUser(this.userId)
+ .then((user) => {
+ this.init(user);
+ this.isInitialized = true;
+ });
+ }
+ }
+
+ init(user) {throw 'Not implemented';}
+
+ onPatch(patch) {throw 'Not implemented';}
+
+ setElement(element, value) {
+ switch (element.tagName) {
+ case 'INPUT': {
+ element.value = value;
+ M.updateTextFields();
+ break;
+ }
+ default: {
+ element.innerText = value;
+ break;
+ }
+ }
+ }
+
+ setElements(elements, value) {
+ for (let element of elements) {
+ this.setElement(element, value);
+ }
+ }
+};
diff --git a/app/templates/_scripts.html.j2 b/app/templates/_scripts.html.j2
index 6213e3df..6d3495c9 100644
--- a/app/templates/_scripts.html.j2
+++ b/app/templates/_scripts.html.j2
@@ -36,6 +36,7 @@
filters='rjsmin',
output='gen/Forms.%(version)s.js',
'js/forms/index.js',
+ 'js/forms/form.js'
'js/forms/create-contribution-form.js',
'js/forms/create-corpus-file-form.js',
'js/forms/create-job-form.js'
@@ -47,6 +48,7 @@
filters='rjsmin',
output='gen/resource-displays.%(version)s.js',
'js/resource-displays/index.js',
+ 'js/resource-displays/base-display.js',
'js/resource-displays/corpus-display.js',
'js/resource-displays/job-display.js'
%}
From 78dd375ef842de9fe43e6fa1495ee19339087c92 Mon Sep 17 00:00:00 2001
From: Patrick Jentsch
Date: Tue, 10 Oct 2023 15:28:10 +0200
Subject: [PATCH 2/8] Performance update for the docker entrypoint script
---
docker-entrypoint.sh | 92 +++++++++++++++++++++++++++++++-------------
1 file changed, 65 insertions(+), 27 deletions(-)
diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh
index 49d6e4f0..5507f26c 100755
--- a/docker-entrypoint.sh
+++ b/docker-entrypoint.sh
@@ -6,50 +6,88 @@ NO_COLOR="\033[0m"
CHECK_MARK="\xE2\x9C\x93"
CROSS_MARK="\xE2\x9D\x8C"
-echo -n "Set container UID and GIDs to match the host system..."
-if [[ "${NOPAQUE_UID}" == 0 ]]; then
+if [[ "${NOPAQUE_UID}" == "0" ]]; then
echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
echo "Running as root is not allowed"
exit 1
-else
- echo ""
fi
-echo -n "- Updating docker GID ($(getent group docker | cut -d: -f3) -> ${DOCKER_GID})... "
-groupmod --gid "${DOCKER_GID}" docker > /dev/null
-if [[ "${?}" == "0" ]]; then
+
+echo "Set container UID and GIDs to match the host system..."
+
+
+##############################################################################
+# docker GID #
+##############################################################################
+if [[ "${DOCKER_GID}" == "$(getent group docker | cut -d: -f3)" ]]; then
+ echo -n "- docker GID is already matching..."
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
else
- echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
- exit 1
+ echo -n "- Updating docker GID ($(getent group docker | cut -d: -f3) -> ${DOCKER_GID})... "
+ groupmod --gid "${DOCKER_GID}" docker > /dev/null
+ if [[ "${?}" == "0" ]]; then
+ echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
+ else
+ echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
+ exit 1
+ fi
fi
-echo -n "- Updating nopaque GID ($(id -g nopaque) -> ${NOPAQUE_GID})... "
-groupmod --gid "${NOPAQUE_GID}" nopaque > /dev/null
-if [[ "${?}" == "0" ]]; then
+
+##############################################################################
+# nopaque GID #
+##############################################################################
+if [[ "${NOPAQUE_GID}" == "$(id -g nopaque)" ]]; then
+ echo -n "- nopaque GID is already matching..."
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
else
- echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
- exit 1
+ echo -n "- Updating nopaque GID ($(id -g nopaque) -> ${NOPAQUE_GID})... "
+ groupmod --gid "${NOPAQUE_GID}" nopaque > /dev/null
+ if [[ "${?}" == "0" ]]; then
+ HAS_NOPAQUE_GID_CHANGED=true
+ echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
+ else
+ echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
+ exit 1
+ fi
+
+ echo -n "- Updating nopaque directory group... "
+ chown -R :nopaque /home/nopaque
+ if [[ "${?}" == "0" ]]; then
+ echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
+ else
+ echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
+ exit 1
+ fi
fi
-echo -n "- Updating nopaque UID ($(id -u nopaque) -> ${NOPAQUE_UID})... "
-usermod --uid "${NOPAQUE_UID}" nopaque > /dev/null
-if [[ "${?}" == "0" ]]; then
+
+##############################################################################
+# nopaque UID #
+##############################################################################
+if [[ "${NOPAQUE_UID}" == "$(id -u nopaque)" ]]; then
+ echo -n "- nopaque UID is already matching..."
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
else
- echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
- exit 1
+ echo -n "- Updating nopaque UID ($(id -u nopaque) -> ${NOPAQUE_UID})... "
+ usermod --uid "${NOPAQUE_UID}" nopaque > /dev/null
+ if [[ "${?}" == "0" ]]; then
+ echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
+ else
+ echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
+ exit 1
+ fi
+
+ echo -n "- Updating nopaque directory owner... "
+ chown -R nopaque /home/nopaque
+ if [[ "${?}" == "0" ]]; then
+ echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
+ else
+ echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
+ exit 1
+ fi
fi
-echo -n "- Updating nopaque directory owner and group... "
-chown -R nopaque:nopaque /home/nopaque
-if [[ "${?}" == "0" ]]; then
- echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
-else
- echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
- exit 1
-fi
exec gosu nopaque ./boot.sh ${@}
From a9203cc40979caebed49f3014b1b412f1c422d5f Mon Sep 17 00:00:00 2001
From: Patrick Jentsch
Date: Wed, 11 Oct 2023 14:26:07 +0200
Subject: [PATCH 3/8] Fix forms and displays
---
app/static/js/resource-displays/corpus-display.js | 2 +-
app/static/js/resource-displays/job-display.js | 2 +-
app/static/js/resource-displays/resource-display.js | 2 +-
app/templates/_scripts.html.j2 | 4 ++--
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/app/static/js/resource-displays/corpus-display.js b/app/static/js/resource-displays/corpus-display.js
index 906b17ac..bf6d2589 100644
--- a/app/static/js/resource-displays/corpus-display.js
+++ b/app/static/js/resource-displays/corpus-display.js
@@ -1,4 +1,4 @@
-ResourceDisplays.CorpusDisplay = class CorpusDisplay extends ResourceDisplays.BaseDisplay {
+ResourceDisplays.CorpusDisplay = class CorpusDisplay extends ResourceDisplays.ResourceDisplay {
static htmlClass = 'corpus-display';
constructor(displayElement) {
diff --git a/app/static/js/resource-displays/job-display.js b/app/static/js/resource-displays/job-display.js
index 4ab370e2..78ebc22c 100644
--- a/app/static/js/resource-displays/job-display.js
+++ b/app/static/js/resource-displays/job-display.js
@@ -1,4 +1,4 @@
-ResourceDisplays.JobDisplay = class JobDisplay extends ResourceDisplays.BaseDisplay {
+ResourceDisplays.JobDisplay = class JobDisplay extends ResourceDisplays.ResourceDisplay {
static htmlClass = 'job-display';
constructor(displayElement) {
diff --git a/app/static/js/resource-displays/resource-display.js b/app/static/js/resource-displays/resource-display.js
index 81fcda5d..39401d2b 100644
--- a/app/static/js/resource-displays/resource-display.js
+++ b/app/static/js/resource-displays/resource-display.js
@@ -1,4 +1,4 @@
-ResourceDisplays.BaseDisplay = class BaseDisplay {
+ResourceDisplays.ResourceDisplay = class ResourceDisplay {
static htmlClass;
constructor(displayElement) {
diff --git a/app/templates/_scripts.html.j2 b/app/templates/_scripts.html.j2
index 6d3495c9..31088634 100644
--- a/app/templates/_scripts.html.j2
+++ b/app/templates/_scripts.html.j2
@@ -36,7 +36,7 @@
filters='rjsmin',
output='gen/Forms.%(version)s.js',
'js/forms/index.js',
- 'js/forms/form.js'
+ 'js/forms/base-form.js',
'js/forms/create-contribution-form.js',
'js/forms/create-corpus-file-form.js',
'js/forms/create-job-form.js'
@@ -48,7 +48,7 @@
filters='rjsmin',
output='gen/resource-displays.%(version)s.js',
'js/resource-displays/index.js',
- 'js/resource-displays/base-display.js',
+ 'js/resource-displays/resource-display.js',
'js/resource-displays/corpus-display.js',
'js/resource-displays/job-display.js'
%}
From 067318bb89422b909069d808c674a73c95611622 Mon Sep 17 00:00:00 2001
From: Patrick Jentsch
Date: Wed, 11 Oct 2023 16:20:17 +0200
Subject: [PATCH 4/8] Huge List class update
---
.../CorpusAnalysisStaticVisualization.js | 4 +-
app/static/js/resource-displays/index.js | 8 ++--
.../admin-user-list.js} | 10 ++---
.../corpus-file-list.js} | 10 ++---
.../corpus-follower-list.js} | 10 ++---
.../corpus-list.js} | 10 ++---
.../corpus-text-info-list.js} | 13 ++-----
.../corpus-token-list.js} | 12 ++----
.../detailed-public-corpus-list.js} | 6 ++-
app/static/js/resource-lists/index.js | 18 +++++++++
.../job-input-list.js} | 10 ++---
.../JobList.js => resource-lists/job-list.js} | 10 ++---
.../job-result-list.js} | 10 ++---
.../public-corpus-list.js} | 6 ++-
.../resource-list.js} | 39 +++++--------------
.../spacy-nlp-pipeline-model-list.js} | 10 ++---
.../tesseract-ocr-pipeline-model-list.js} | 10 ++---
.../user-list.js} | 10 ++---
app/templates/_scripts.html.j2 | 35 +++++++++--------
app/templates/admin/corpora.html.j2 | 2 +-
app/templates/admin/users.html.j2 | 2 +-
app/templates/corpora/public_corpus.html.j2 | 4 +-
app/templates/main/social_area.html.j2 | 4 +-
app/templates/users/user.html.j2 | 4 +-
24 files changed, 106 insertions(+), 151 deletions(-)
rename app/static/js/{ResourceLists/AdminUserList.js => resource-lists/admin-user-list.js} (93%)
rename app/static/js/{ResourceLists/CorpusFileList.js => resource-lists/corpus-file-list.js} (98%)
rename app/static/js/{ResourceLists/CorpusFollowerList.js => resource-lists/corpus-follower-list.js} (96%)
rename app/static/js/{ResourceLists/CorpusList.js => resource-lists/corpus-list.js} (98%)
rename app/static/js/{ResourceLists/CorpusTextInfoList.js => resource-lists/corpus-text-info-list.js} (93%)
rename app/static/js/{ResourceLists/CorpusTokenList.js => resource-lists/corpus-token-list.js} (94%)
rename app/static/js/{ResourceLists/DetailledPublicCorpusList.js => resource-lists/detailed-public-corpus-list.js} (93%)
create mode 100644 app/static/js/resource-lists/index.js
rename app/static/js/{ResourceLists/JobInputList.js => resource-lists/job-input-list.js} (92%)
rename app/static/js/{ResourceLists/JobList.js => resource-lists/job-list.js} (98%)
rename app/static/js/{ResourceLists/JobResultList.js => resource-lists/job-result-list.js} (93%)
rename app/static/js/{ResourceLists/PublicCorpusList.js => resource-lists/public-corpus-list.js} (93%)
rename app/static/js/{ResourceLists/ResourceList.js => resource-lists/resource-list.js} (61%)
rename app/static/js/{ResourceLists/SpacyNLPPipelineModelList.js => resource-lists/spacy-nlp-pipeline-model-list.js} (96%)
rename app/static/js/{ResourceLists/TesseractOCRPipelineModelList.js => resource-lists/tesseract-ocr-pipeline-model-list.js} (96%)
rename app/static/js/{ResourceLists/UserList.js => resource-lists/user-list.js} (93%)
diff --git a/app/static/js/CorpusAnalysis/CorpusAnalysisStaticVisualization.js b/app/static/js/CorpusAnalysis/CorpusAnalysisStaticVisualization.js
index 38c48c3c..4d51b014 100644
--- a/app/static/js/CorpusAnalysis/CorpusAnalysisStaticVisualization.js
+++ b/app/static/js/CorpusAnalysis/CorpusAnalysisStaticVisualization.js
@@ -104,7 +104,7 @@ class CorpusAnalysisStaticVisualization {
renderTextInfoList() {
let corpusData = this.data.corpus.o.staticData;
let corpusTextInfoListElement = document.querySelector('.corpus-text-info-list');
- let corpusTextInfoList = new CorpusTextInfoList(corpusTextInfoListElement);
+ let corpusTextInfoList = new ResourceLists.CorpusTextInfoList(corpusTextInfoListElement);
let texts = corpusData.s_attrs.text.lexicon;
let textData = [];
for (let i = 0; i < Object.entries(texts).length; i++) {
@@ -213,7 +213,7 @@ class CorpusAnalysisStaticVisualization {
async renderTokenList() {
let corpusTokenListElement = document.querySelector('.corpus-token-list');
- let corpusTokenList = new CorpusTokenList(corpusTokenListElement);
+ let corpusTokenList = new ResourceLists.CorpusTokenList(corpusTokenListElement);
let filteredData = this.filterData();
let stopwords = this.data.stopwords;
if (this.data.stopwords === undefined) {
diff --git a/app/static/js/resource-displays/index.js b/app/static/js/resource-displays/index.js
index 4ec7e997..8cc8809e 100644
--- a/app/static/js/resource-displays/index.js
+++ b/app/static/js/resource-displays/index.js
@@ -3,9 +3,9 @@ var ResourceDisplays = {};
ResourceDisplays.autoInit = () => {
for (let propertyName in ResourceDisplays) {
let property = ResourceDisplays[propertyName];
- // Call autoInit of all properties that are subclasses of `ResourceDisplays.BaseDisplay`.
- // This does not include `ResourceDisplays.BaseDisplay` itself.
- if (property.prototype instanceof ResourceDisplays.BaseDisplay) {
+ // Call autoInit of all properties that are subclasses of `ResourceDisplays.ResourceDisplay`.
+ // This does not include `ResourceDisplays.ResourceDisplay` itself.
+ if (property.prototype instanceof ResourceDisplays.ResourceDisplay) {
// Check if the static `htmlClass` property is defined.
if (property.htmlClass === undefined) {return;}
// Gather all HTML elements that have the `this.htmlClass` class
@@ -15,4 +15,4 @@ ResourceDisplays.autoInit = () => {
for (let displayElement of displayElements) {new property(displayElement);}
}
}
-}
+};
diff --git a/app/static/js/ResourceLists/AdminUserList.js b/app/static/js/resource-lists/admin-user-list.js
similarity index 93%
rename from app/static/js/ResourceLists/AdminUserList.js
rename to app/static/js/resource-lists/admin-user-list.js
index 0b8f0c16..40feab27 100644
--- a/app/static/js/ResourceLists/AdminUserList.js
+++ b/app/static/js/resource-lists/admin-user-list.js
@@ -1,9 +1,5 @@
-class AdminUserList extends ResourceList {
- static autoInit() {
- for (let adminUserListElement of document.querySelectorAll('.admin-user-list:not(.no-autoinit)')) {
- new AdminUserList(adminUserListElement);
- }
- }
+ResourceLists.AdminUserList = class AdminUserList extends ResourceLists.ResourceList {
+ static htmlClass = 'admin-user-list';
constructor(listContainerElement, options = {}) {
super(listContainerElement, options);
@@ -108,4 +104,4 @@ class AdminUserList extends ResourceList {
}
}
}
-}
+};
diff --git a/app/static/js/ResourceLists/CorpusFileList.js b/app/static/js/resource-lists/corpus-file-list.js
similarity index 98%
rename from app/static/js/ResourceLists/CorpusFileList.js
rename to app/static/js/resource-lists/corpus-file-list.js
index 9997b061..7e6a5da9 100644
--- a/app/static/js/ResourceLists/CorpusFileList.js
+++ b/app/static/js/resource-lists/corpus-file-list.js
@@ -1,9 +1,5 @@
-class CorpusFileList extends ResourceList {
- static autoInit() {
- for (let corpusFileListElement of document.querySelectorAll('.corpus-file-list:not(.no-autoinit)')) {
- new CorpusFileList(corpusFileListElement);
- }
- }
+ResourceLists.CorpusFileList = class CorpusFileList extends ResourceLists.ResourceList {
+ static htmlClass = 'corpus-file-list';
constructor(listContainerElement, options = {}) {
super(listContainerElement, options);
@@ -369,4 +365,4 @@ class CorpusFileList extends ResourceList {
}
}
}
-}
+};
diff --git a/app/static/js/ResourceLists/CorpusFollowerList.js b/app/static/js/resource-lists/corpus-follower-list.js
similarity index 96%
rename from app/static/js/ResourceLists/CorpusFollowerList.js
rename to app/static/js/resource-lists/corpus-follower-list.js
index ca70a6c7..b8a4c255 100644
--- a/app/static/js/ResourceLists/CorpusFollowerList.js
+++ b/app/static/js/resource-lists/corpus-follower-list.js
@@ -1,9 +1,5 @@
-class CorpusFollowerList extends ResourceList {
- static autoInit() {
- for (let corpusFollowerListElement of document.querySelectorAll('.corpus-follower-list:not(.no-autoinit)')) {
- new CorpusFollowerList(corpusFollowerListElement);
- }
- }
+ResourceLists.CorpusFollowerList = class CorpusFollowerList extends ResourceLists.ResourceList {
+ static htmlClass = 'corpus-follower-list';
constructor(listContainerElement, options = {}) {
super(listContainerElement, options);
@@ -196,4 +192,4 @@ class CorpusFollowerList extends ResourceList {
}
}
}
-}
+};
diff --git a/app/static/js/ResourceLists/CorpusList.js b/app/static/js/resource-lists/corpus-list.js
similarity index 98%
rename from app/static/js/ResourceLists/CorpusList.js
rename to app/static/js/resource-lists/corpus-list.js
index 985ff1d1..f4289d8b 100644
--- a/app/static/js/ResourceLists/CorpusList.js
+++ b/app/static/js/resource-lists/corpus-list.js
@@ -1,9 +1,5 @@
-class CorpusList extends ResourceList {
- static autoInit() {
- for (let corpusListElement of document.querySelectorAll('.corpus-list:not(.no-autoinit)')) {
- new CorpusList(corpusListElement);
- }
- }
+ResourceLists.CorpusList = class CorpusList extends ResourceLists.ResourceList {
+ static htmlClass = 'corpus-list';
constructor(listContainerElement, options = {}) {
super(listContainerElement, options);
@@ -370,4 +366,4 @@ class CorpusList extends ResourceList {
}
}
}
-}
+};
diff --git a/app/static/js/ResourceLists/CorpusTextInfoList.js b/app/static/js/resource-lists/corpus-text-info-list.js
similarity index 93%
rename from app/static/js/ResourceLists/CorpusTextInfoList.js
rename to app/static/js/resource-lists/corpus-text-info-list.js
index f1545d70..00c5467c 100644
--- a/app/static/js/ResourceLists/CorpusTextInfoList.js
+++ b/app/static/js/resource-lists/corpus-text-info-list.js
@@ -1,10 +1,5 @@
-class CorpusTextInfoList extends ResourceList {
-
- static autoInit() {
- for (let corpusTextInfoListElement of document.querySelectorAll('.corpus-text-info-list:not(.no-autoinit)')) {
- new CorpusTextInfoList(corpusTextInfoListElement);
- }
- }
+ResourceLists.CorpusTextInfoList = class CorpusTextInfoList extends ResourceLists.ResourceList {
+ static htmlClass = 'corpus-text-info-list';
static defaultOptions = {
page: 5
@@ -12,7 +7,7 @@ class CorpusTextInfoList extends ResourceList {
constructor(listContainerElement, options = {}) {
let _options = Utils.mergeObjectsDeep(
- CorpusTextInfoList.defaultOptions,
+ ResourceLists.CorpusTextInfoList.defaultOptions,
options
);
super(listContainerElement, _options);
@@ -109,4 +104,4 @@ class CorpusTextInfoList extends ResourceList {
clickedSortElement.style.color = '#aa9cc9';
clickedSortElement.innerHTML = clickedSortElement.classList.contains('asc') ? 'arrow_drop_down' : 'arrow_drop_up';
}
-}
+};
diff --git a/app/static/js/ResourceLists/CorpusTokenList.js b/app/static/js/resource-lists/corpus-token-list.js
similarity index 94%
rename from app/static/js/ResourceLists/CorpusTokenList.js
rename to app/static/js/resource-lists/corpus-token-list.js
index cc16692b..eddd82ea 100644
--- a/app/static/js/ResourceLists/CorpusTokenList.js
+++ b/app/static/js/resource-lists/corpus-token-list.js
@@ -1,9 +1,5 @@
-class CorpusTokenList extends ResourceList {
- static autoInit() {
- for (let corpusTokenListElement of document.querySelectorAll('.corpus-token-list:not(.no-autoinit)')) {
- new CorpusTokenList(corpusTokenListElement);
- }
- }
+ResourceLists.CorpusTokenList = class CorpusTokenList extends ResourceLists.ResourceList {
+ static htmlClass = 'corpus-token-list';
static defaultOptions = {
page: 7
@@ -11,7 +7,7 @@ class CorpusTokenList extends ResourceList {
constructor(listContainerElement, options = {}) {
let _options = Utils.mergeObjectsDeep(
- CorpusTokenList.defaultOptions,
+ ResourceLists.CorpusTokenList.defaultOptions,
options
);
super(listContainerElement, _options);
@@ -138,4 +134,4 @@ class CorpusTokenList extends ResourceList {
}
}
-}
+};
diff --git a/app/static/js/ResourceLists/DetailledPublicCorpusList.js b/app/static/js/resource-lists/detailed-public-corpus-list.js
similarity index 93%
rename from app/static/js/ResourceLists/DetailledPublicCorpusList.js
rename to app/static/js/resource-lists/detailed-public-corpus-list.js
index 5bfc59ff..e855e07b 100644
--- a/app/static/js/ResourceLists/DetailledPublicCorpusList.js
+++ b/app/static/js/resource-lists/detailed-public-corpus-list.js
@@ -1,4 +1,6 @@
-class DetailledPublicCorpusList extends CorpusList {
+ResourceLists.DetailedPublicCorpusList = class DetailedPublicCorpusList extends ResourceLists.ResourceList {
+ static htmlClass = 'detailed-public-corpus-list';
+
get item() {
return (values) => {
return `
@@ -68,4 +70,4 @@ class DetailledPublicCorpusList extends CorpusList {
'current-user-is-following': Object.values(corpus.corpus_follower_associations).some(association => association.follower.id === currentUserId)
};
}
-}
+};
diff --git a/app/static/js/resource-lists/index.js b/app/static/js/resource-lists/index.js
new file mode 100644
index 00000000..513da46b
--- /dev/null
+++ b/app/static/js/resource-lists/index.js
@@ -0,0 +1,18 @@
+var ResourceLists = {};
+
+ResourceLists.autoInit = () => {
+ for (let propertyName in ResourceLists) {
+ let property = ResourceLists[propertyName];
+ // Call autoInit of all properties that are subclasses of `ResourceLists.ResourceList`.
+ // This does not include `ResourceLists.ResourceList` itself.
+ if (property.prototype instanceof ResourceLists.ResourceList) {
+ // Check if the static `htmlClass` property is defined.
+ if (property.htmlClass === undefined) {return;}
+ // Gather all HTML elements that have the `this.htmlClass` class
+ // and do not have the `no-autoinit` class.
+ let listElements = document.querySelectorAll(`.${property.htmlClass}:not(.no-autoinit)`);
+ // Create an instance of this class for each display element.
+ for (let listElement of listElements) {new property(listElement);}
+ }
+ }
+};
diff --git a/app/static/js/ResourceLists/JobInputList.js b/app/static/js/resource-lists/job-input-list.js
similarity index 92%
rename from app/static/js/ResourceLists/JobInputList.js
rename to app/static/js/resource-lists/job-input-list.js
index 97a8dd14..609702b5 100644
--- a/app/static/js/ResourceLists/JobInputList.js
+++ b/app/static/js/resource-lists/job-input-list.js
@@ -1,9 +1,5 @@
-class JobInputList extends ResourceList {
- static autoInit() {
- for (let jobInputListElement of document.querySelectorAll('.job-input-list:not(.no-autoinit)')) {
- new JobInputList(jobInputListElement);
- }
- }
+ResourceLists.JobInputList = class JobInputList extends ResourceLists.ResourceList {
+ static htmlClass = 'job-input-list';
constructor(listContainerElement, options = {}) {
super(listContainerElement, options);
@@ -90,4 +86,4 @@ class JobInputList extends ResourceList {
}
}
}
-}
+};
diff --git a/app/static/js/ResourceLists/JobList.js b/app/static/js/resource-lists/job-list.js
similarity index 98%
rename from app/static/js/ResourceLists/JobList.js
rename to app/static/js/resource-lists/job-list.js
index 1cb3ea60..c751e705 100644
--- a/app/static/js/ResourceLists/JobList.js
+++ b/app/static/js/resource-lists/job-list.js
@@ -1,9 +1,5 @@
-class JobList extends ResourceList {
- static autoInit() {
- for (let jobListElement of document.querySelectorAll('.job-list:not(.no-autoinit)')) {
- new JobList(jobListElement);
- }
- }
+ResourceLists.JobList = class JobList extends ResourceLists.ResourceList {
+ static htmlClass = 'job-list';
constructor(listContainerElement, options = {}) {
super(listContainerElement, options);
@@ -323,4 +319,4 @@ class JobList extends ResourceList {
}
}
}
-}
+};
diff --git a/app/static/js/ResourceLists/JobResultList.js b/app/static/js/resource-lists/job-result-list.js
similarity index 93%
rename from app/static/js/ResourceLists/JobResultList.js
rename to app/static/js/resource-lists/job-result-list.js
index b0cbc088..e71759a5 100644
--- a/app/static/js/ResourceLists/JobResultList.js
+++ b/app/static/js/resource-lists/job-result-list.js
@@ -1,9 +1,5 @@
-class JobResultList extends ResourceList {
- static autoInit() {
- for (let jobResultListElement of document.querySelectorAll('.job-result-list:not(.no-autoinit)')) {
- new JobResultList(jobResultListElement);
- }
- }
+ResourceLists.JobResultList = class JobResultList extends ResourceLists.ResourceList {
+ static htmlClass = 'job-result-list';
constructor(listContainerElement, options = {}) {
super(listContainerElement, options);
@@ -115,4 +111,4 @@ class JobResultList extends ResourceList {
}
}
}
-}
+};
diff --git a/app/static/js/ResourceLists/PublicCorpusList.js b/app/static/js/resource-lists/public-corpus-list.js
similarity index 93%
rename from app/static/js/ResourceLists/PublicCorpusList.js
rename to app/static/js/resource-lists/public-corpus-list.js
index 1ef98273..659dfd09 100644
--- a/app/static/js/ResourceLists/PublicCorpusList.js
+++ b/app/static/js/resource-lists/public-corpus-list.js
@@ -1,4 +1,6 @@
-class PublicCorpusList extends CorpusList {
+ResourceLists.PublicCorpusList = class PublicCorpusList extends ResourceLists.ResourceList {
+ static htmlClass = 'public-corpus-list';
+
get item() {
return (values) => {
return `
@@ -52,4 +54,4 @@ class PublicCorpusList extends CorpusList {
`.trim();
}
-}
+};
diff --git a/app/static/js/ResourceLists/ResourceList.js b/app/static/js/resource-lists/resource-list.js
similarity index 61%
rename from app/static/js/ResourceLists/ResourceList.js
rename to app/static/js/resource-lists/resource-list.js
index 97e65d70..ba71f03f 100644
--- a/app/static/js/ResourceLists/ResourceList.js
+++ b/app/static/js/resource-lists/resource-list.js
@@ -1,31 +1,4 @@
-var ResourceLists = {};
-
-ResourceLists.autoInit = () => {
- for (let propertyName in ResourceLists) {
- let property = ResourceLists[propertyName];
- // Call autoInit of all properties that are subclasses of `ResourceLists.BaseList`.
- // This does not include `ResourceLists.BaseList` itself.
- if (property.prototype instanceof ResourceLists.BaseList) {
- // Check if the static `htmlClass` property is defined.
- if (property.htmlClass === undefined) {return;}
- // Gather all HTML elements that have the `this.htmlClass` class
- // and do not have the `no-autoinit` class.
- let listElements = document.querySelectorAll(`.${property.htmlClass}:not(.no-autoinit)`);
- // Create an instance of this class for each display element.
- for (let listElement of listElements) {new property(listElement);}
- }
- }
-};
-
-ResourceLists.defaultOptions = {
- page: 5,
- pagination: {
- innerWindow: 2,
- outerWindow: 2
- }
-};
-
-ResourceLists.BaseList = class BaseList {
+ResourceLists.ResourceList = class ResourceList {
/* A wrapper class for the list.js list.
* This class is not meant to be used directly, instead it should be used as
* a base class for concrete resource list implementations.
@@ -33,6 +6,14 @@ ResourceLists.BaseList = class BaseList {
static htmlClass;
+ static defaultOptions = {
+ page: 5,
+ pagination: {
+ innerWindow: 2,
+ outerWindow: 2
+ }
+ };
+
constructor(listContainerElement, options = {}) {
if ('items' in options) {
throw '"items" is not supported as an option, define it as a getter in the list class';
@@ -42,7 +23,7 @@ ResourceLists.BaseList = class BaseList {
}
let _options = Utils.mergeObjectsDeep(
{item: this.item, valueNames: this.valueNames},
- ResourceLists.defaultOptions,
+ ResourceLists.ResourceList.defaultOptions,
options
);
this.listContainerElement = listContainerElement;
diff --git a/app/static/js/ResourceLists/SpacyNLPPipelineModelList.js b/app/static/js/resource-lists/spacy-nlp-pipeline-model-list.js
similarity index 96%
rename from app/static/js/ResourceLists/SpacyNLPPipelineModelList.js
rename to app/static/js/resource-lists/spacy-nlp-pipeline-model-list.js
index 46d3739d..195fa60c 100644
--- a/app/static/js/ResourceLists/SpacyNLPPipelineModelList.js
+++ b/app/static/js/resource-lists/spacy-nlp-pipeline-model-list.js
@@ -1,9 +1,5 @@
-class SpaCyNLPPipelineModelList extends ResourceList {
- static autoInit() {
- for (let spaCyNLPPipelineModelListElement of document.querySelectorAll('.spacy-nlp-pipeline-model-list:not(.no-autoinit)')) {
- new SpaCyNLPPipelineModelList(spaCyNLPPipelineModelListElement);
- }
- }
+ResourceLists.SpaCyNLPPipelineModelList = class SpaCyNLPPipelineModelList extends ResourceLists.ResourceList {
+ static htmlClass = 'spacy-nlp-pipeline-model-list';
constructor(listContainerElement, options = {}) {
super(listContainerElement, options);
@@ -220,4 +216,4 @@ class SpaCyNLPPipelineModelList extends ResourceList {
}
}
}
-}
+};
diff --git a/app/static/js/ResourceLists/TesseractOCRPipelineModelList.js b/app/static/js/resource-lists/tesseract-ocr-pipeline-model-list.js
similarity index 96%
rename from app/static/js/ResourceLists/TesseractOCRPipelineModelList.js
rename to app/static/js/resource-lists/tesseract-ocr-pipeline-model-list.js
index 765f44a6..975bfe5c 100644
--- a/app/static/js/ResourceLists/TesseractOCRPipelineModelList.js
+++ b/app/static/js/resource-lists/tesseract-ocr-pipeline-model-list.js
@@ -1,9 +1,5 @@
-class TesseractOCRPipelineModelList extends ResourceList {
- static autoInit() {
- for (let tesseractOCRPipelineModelListElement of document.querySelectorAll('.tesseract-ocr-pipeline-model-list:not(.no-autoinit)')) {
- new TesseractOCRPipelineModelList(tesseractOCRPipelineModelListElement);
- }
- }
+ResourceLists.TesseractOCRPipelineModelList = class TesseractOCRPipelineModelList extends ResourceLists.ResourceList {
+ static htmlClass = 'tesseract-ocr-pipeline-model-list';
constructor(listContainerElement, options = {}) {
super(listContainerElement, options);
@@ -229,4 +225,4 @@ class TesseractOCRPipelineModelList extends ResourceList {
}
}
}
-}
+};
diff --git a/app/static/js/ResourceLists/UserList.js b/app/static/js/resource-lists/user-list.js
similarity index 93%
rename from app/static/js/ResourceLists/UserList.js
rename to app/static/js/resource-lists/user-list.js
index 2ba4dc19..6ef14e2f 100644
--- a/app/static/js/ResourceLists/UserList.js
+++ b/app/static/js/resource-lists/user-list.js
@@ -1,9 +1,5 @@
-class UserList extends ResourceList {
- static autoInit() {
- for (let userListElement of document.querySelectorAll('.user-list:not(.no-autoinit)')) {
- new UserList(userListElement);
- }
- }
+ResourceLists.UserList = class UserList extends ResourceLists.ResourceList {
+ static htmlClass = 'user-list';
constructor(listContainerElement, options = {}) {
super(listContainerElement, options);
@@ -101,4 +97,4 @@ class UserList extends ResourceList {
}
}
}
-}
+};
diff --git a/app/templates/_scripts.html.j2 b/app/templates/_scripts.html.j2
index 31088634..2b84659a 100644
--- a/app/templates/_scripts.html.j2
+++ b/app/templates/_scripts.html.j2
@@ -57,22 +57,23 @@
{%- assets
filters='rjsmin',
- output='gen/ResourceLists.%(version)s.js',
- 'js/ResourceLists/ResourceList.js',
- 'js/ResourceLists/CorpusFileList.js',
- 'js/ResourceLists/CorpusList.js',
- 'js/ResourceLists/PublicCorpusList.js',
- 'js/ResourceLists/JobList.js',
- 'js/ResourceLists/JobInputList.js',
- 'js/ResourceLists/JobResultList.js',
- 'js/ResourceLists/SpacyNLPPipelineModelList.js',
- 'js/ResourceLists/TesseractOCRPipelineModelList.js',
- 'js/ResourceLists/UserList.js',
- 'js/ResourceLists/AdminUserList.js',
- 'js/ResourceLists/CorpusFollowerList.js',
- 'js/ResourceLists/CorpusTextInfoList.js',
- 'js/ResourceLists/DetailledPublicCorpusList.js',
- 'js/ResourceLists/CorpusTokenList.js'
+ output='gen/resource-lists.%(version)s.js',
+ 'js/resource-lists/index.js',
+ 'js/resource-lists/resource-list.js',
+ 'js/resource-lists/admin-user-list.js',
+ 'js/resource-lists/corpus-file-list.js',
+ 'js/resource-lists/corpus-follower-list.js',
+ 'js/resource-lists/corpus-list.js',
+ 'js/resource-lists/corpus-text-info-list.js',
+ 'js/resource-lists/corpus-token-list.js',
+ 'js/resource-lists/detailed-public-corpus-list.js',
+ 'js/resource-lists/job-input-list.js',
+ 'js/resource-lists/job-list.js',
+ 'js/resource-lists/job-result-list.js',
+ 'js/resource-lists/public-corpus-list.js',
+ 'js/resource-lists/spacy-nlp-pipeline-model-list.js',
+ 'js/resource-lists/tesseract-ocr-pipeline-model-list.js',
+ 'js/resource-lists/user-list.js'
%}
{%- endassets %}
@@ -143,7 +144,7 @@
{alignment: 'right', constrainWidth: false, coverTrigger: false}
);
ResourceDisplays.autoInit();
- ResourceList.autoInit();
+ ResourceLists.autoInit();
Forms.autoInit();
// Display flashed messages
diff --git a/app/templates/admin/corpora.html.j2 b/app/templates/admin/corpora.html.j2
index 90a4b28e..3eeb7981 100644
--- a/app/templates/admin/corpora.html.j2
+++ b/app/templates/admin/corpora.html.j2
@@ -17,7 +17,7 @@
{{ super() }}
+{%- endassets %}
+
+{%- assets
+ filters='rjsmin',
+ output='gen/utils.%(version)s.js',
+ 'js/utils/index.js',
+ 'js/utils/utils.js'
%}
{%- endassets %}
@@ -110,7 +118,7 @@