diff --git a/app/assets/javascripts/components/course_labels_search_bar.ts b/app/assets/javascripts/components/course_labels_search_bar.ts
deleted file mode 100644
index 917ddef405..0000000000
--- a/app/assets/javascripts/components/course_labels_search_bar.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import { customElement, property } from "lit/decorators.js";
-import { html, TemplateResult } from "lit";
-import { Option } from "components/datalist_input";
-import "components/datalist_input";
-import { i18n } from "i18n/i18n";
-import { DodonaElement } from "components/meta/dodona_element";
-/**
- * This component represents a list of the selected course labels
- *
- * @element d-course-labels
- * @prop {string[]} Labels - the labels of a user in a certain course
- */
-@customElement("d-course-labels")
-export class CourseLabelTokens extends DodonaElement {
- @property({ type: Array })
- labels: string[];
-
- processClick(e: Event, label: string): void {
- this.labels.splice(this.labels.indexOf(label), 1);
- this.requestUpdate();
- }
-
- render(): TemplateResult {
- if (!this.labels) {
- return html``;
- }
-
- return html`
- ${ this.labels.map( label => html`
-
- ${label}
- this.processClick(e, label)}>×
-
-
- `)}
-
- `;
- }
-}
-
-/**
- * This component represents a search bar for course labels, also showing a list of already selected labels.
- * It allows for searching existing labels, or creating new ones, and adding them to the user of a certain course
- *
- * @element d-course-labels-search-bar
- *
- * @prop {{id: number, name: string}[]} Labels - all the labels already used in a course
- * @prop {string[]} SelectedLabels - the labels that have been added to the user
- */
-@customElement("d-course-labels-search-bar")
-export class CourseLabelsSearchBar extends DodonaElement {
- @property({ type: Array })
- labels: {id: number, name: string}[];
-
- @property({ type: Array })
- selected_labels: string[];
-
- @property({ state: true })
- selected_label: string;
-
- @property({ state: true })
- filter: string;
-
- get options(): Option[] {
- return this.labels.map(i => ({ label: i.name, value: i.id.toString() }));
- }
-
- addLabel(): void {
- const selectedLabel = this.selected_label.trim();
- if (selectedLabel.length > 0) {
- const newSelectedLabels = this.selected_labels.slice();
- if (!this.selected_labels.includes(selectedLabel)) {
- newSelectedLabels.push(selectedLabel);
- this.selected_labels = newSelectedLabels;
- }
- this.filter = "";
- }
- }
-
- handleInput(e: CustomEvent): void {
- this.selected_label = e.detail.label;
- this.filter = e.detail.label;
- if (e.detail.value) {
- this.addLabel();
- }
- }
-
- render(): TemplateResult {
- return html`
-
-
-
-
${i18n.t("js.course_labels_search_bar.edit_explanation")}
-
- `;
- }
-}
diff --git a/app/assets/javascripts/components/labels_search_bar.ts b/app/assets/javascripts/components/labels_search_bar.ts
new file mode 100644
index 0000000000..42bf862777
--- /dev/null
+++ b/app/assets/javascripts/components/labels_search_bar.ts
@@ -0,0 +1,124 @@
+import { customElement, property } from "lit/decorators.js";
+import { html, TemplateResult } from "lit";
+import { Option } from "components/datalist_input";
+import "components/datalist_input";
+import { i18n } from "i18n/i18n";
+import { DodonaElement } from "components/meta/dodona_element";
+/**
+ * This component represents a list of the selected labels
+ *
+ * @element d-course-labels
+ * @prop {string[]} labels - the labels of a user in a certain course
+ * @prop {string} name - the name of the input field (used in form submit)
+ */
+@customElement("d-labels")
+export class LabelTokens extends DodonaElement {
+ @property({ type: Array })
+ labels: string[];
+ @property({ type: String })
+ name: string;
+
+ removeLabel(label: string): void {
+ this.dispatchEvent(new CustomEvent("remove-label", {
+ detail: {
+ value: label,
+ },
+ }));
+ }
+
+ render(): TemplateResult {
+ if (!this.labels) {
+ return html``;
+ }
+
+ return html`
+ ${ this.labels.length > 0 ? html`
+
+ ` : html`` }
+
+ `;
+ }
+}
+
+/**
+ * This component represents a search bar for labels, also showing a list of already selected labels.
+ * It allows for searching existing labels, or creating new ones, and adding them to the user of a certain course
+ *
+ * @element d-labels-search-bar
+ *
+ * @prop {{id: number, name: string}[]} labels - all the labels already used in a course
+ * @prop {string[]} selected_labels - the labels that have been added to the user
+ * @prop {string} Name - the name of the input field (used in form submit)
+ */
+@customElement("d-labels-search-bar")
+export class LabelsSearchBar extends DodonaElement {
+ @property({ type: Array })
+ labels: {id: number, name: string}[];
+ @property({ type: Array })
+ selected_labels: string[];
+ @property({ type: String })
+ name: string;
+
+ @property({ state: true })
+ selected_label: string;
+ @property({ state: true })
+ filter: string;
+
+ get options(): Option[] {
+ return this.labels
+ .filter(i => !this.selected_labels.includes(i.name))
+ .map(i => ({ label: i.name, value: i.id.toString() }));
+ }
+
+ addLabel(): void {
+ const selectedLabel = this.selected_label.trim();
+ if (selectedLabel.length > 0 && !this.selected_labels.includes(selectedLabel)) {
+ this.selected_labels = [...this.selected_labels, selectedLabel];
+ this.filter = "";
+ }
+ }
+
+ handleInput(e: CustomEvent): void {
+ this.selected_label = e.detail.label;
+ this.filter = e.detail.label;
+ }
+
+ handleKeyDown(e: KeyboardEvent): void {
+ if (e.key === "Enter" || e.key === "Tab") {
+ this.addLabel();
+ }
+ }
+
+ removeLabel(label: string): void {
+ this.selected_labels = this.selected_labels.filter(i => i !== label);
+ }
+
+ render(): TemplateResult {
+ return html`
+
+
this.removeLabel(e.detail.value)}
+ >
+
+
${i18n.t("js.labels_search_bar.edit_explanation")}
+
+ `;
+ }
+}
diff --git a/app/assets/javascripts/i18n/translations.json b/app/assets/javascripts/i18n/translations.json
index ed2910a8e5..75631ffce4 100644
--- a/app/assets/javascripts/i18n/translations.json
+++ b/app/assets/javascripts/i18n/translations.json
@@ -181,11 +181,6 @@
"course-removed-failed": "Removing course failed",
"course-removed-success": "Course removed",
"course_labels": "Member labels",
- "course_labels_search_bar": {
- "add": "Add",
- "edit_explanation": "Add an existing userlabel or create a new one.",
- "placeholder": "Label"
- },
"courses": "Courses",
"ctimeseries_desc": "This graph shows the evolution of the percentage of students that correctly solved each exercise.",
"ctimeseries_title": "Users with at least one correct submission",
@@ -241,6 +236,11 @@
"judges": "Judges",
"label-undeletable": "This label can't be deleted because it was set in the dirconfig file of a parent directory of the learning activity.",
"labels": "Labels",
+ "labels_search_bar": {
+ "add": "Add",
+ "edit_explanation": "Add an existing label or create a new one.",
+ "placeholder": "Label"
+ },
"loading": "Loading...",
"machine_annotation": {
"external_url": "more information"
@@ -706,11 +706,6 @@
"course-removed-failed": "Cursus verwijderen mislukt",
"course-removed-success": "Cursus verwijderd",
"course_labels": "Gebruikerlabels",
- "course_labels_search_bar": {
- "add": "Toevoegen",
- "edit_explanation": "Voeg een bestaand gebruikerlabel toe of maak een nieuwe aan.",
- "placeholder": "Label"
- },
"courses": "Cursussen",
"ctimeseries_desc": "Deze grafiek geeft de evolutie weer van het percentage studenten dat een oefening correct had.",
"ctimeseries_title": "Gebruikers met minstens één correcte oplossing",
@@ -766,6 +761,11 @@
"judges": "Judges",
"label-undeletable": "Dit label kan niet verwijderd worden omdat het werd ingesteld in het dirconfig bestand van een bovenliggende map.",
"labels": "Labels",
+ "labels_search_bar": {
+ "add": "Toevoegen",
+ "edit_explanation": "Voeg een bestaand label toe of maak een nieuwe aan.",
+ "placeholder": "Label"
+ },
"loading": "Aan het laden...",
"machine_annotation": {
"external_url": "meer informatie"
diff --git a/app/assets/stylesheets/components/courselabel-edit.css.scss b/app/assets/stylesheets/components/courselabel-edit.css.scss
index de68774da0..8aeea6e609 100644
--- a/app/assets/stylesheets/components/courselabel-edit.css.scss
+++ b/app/assets/stylesheets/components/courselabel-edit.css.scss
@@ -1,6 +1,14 @@
-d-course-labels-search-bar {
- .labels-searchbar-group {
- padding-top: 10px;
+d-labels-search-bar {
+ .labels {
+ margin-bottom: 10px;
+ }
+
+ d-datalist-input {
+ flex: auto;
+
+ input {
+ height: 33.5px;
+ }
}
.add-button {
diff --git a/app/javascript/packs/course_membership.js b/app/javascript/packs/course_membership.js
deleted file mode 100644
index 2d7dd0ade7..0000000000
--- a/app/javascript/packs/course_membership.js
+++ /dev/null
@@ -1 +0,0 @@
-import "components/course_labels_search_bar";
diff --git a/app/javascript/packs/label_search_bar.js b/app/javascript/packs/label_search_bar.js
new file mode 100644
index 0000000000..c307f168a3
--- /dev/null
+++ b/app/javascript/packs/label_search_bar.js
@@ -0,0 +1 @@
+import "components/labels_search_bar";
diff --git a/app/views/activities/_form.html.erb b/app/views/activities/_form.html.erb
index 310f41a821..c931346e67 100644
--- a/app/views/activities/_form.html.erb
+++ b/app/views/activities/_form.html.erb
@@ -1,3 +1,6 @@
+<% content_for :javascripts do %>
+ <% javascript_include_tag 'label_search_bar' %>
+<% end %>
<%= form_for(activity.becomes(Activity), :url => activity_scoped_path(activity: activity, course: @course, series: @series), :html => {:class => 'form-horizontal'}) do |f| %>
<% if activity.errors.any? %>
@@ -23,8 +26,13 @@
diff --git a/config/locales/js/en.yml b/config/locales/js/en.yml
index 9ea3f2d159..d4bab5d56f 100644
--- a/config/locales/js/en.yml
+++ b/config/locales/js/en.yml
@@ -297,10 +297,10 @@ en:
sign_in_search_bar:
institution_search: "Type to search for your institution"
log_in: Sign in
- course_labels_search_bar:
+ labels_search_bar:
placeholder: "Label"
add: "Add"
- edit_explanation: "Add an existing userlabel or create a new one."
+ edit_explanation: "Add an existing label or create a new one."
progress_bar:
series-admin-progress:
key: ".singular |||| .plural"
diff --git a/config/locales/js/nl.yml b/config/locales/js/nl.yml
index 519846d864..81d7882eb9 100644
--- a/config/locales/js/nl.yml
+++ b/config/locales/js/nl.yml
@@ -297,10 +297,10 @@ nl:
sign_in_search_bar:
institution_search: "Typ om jouw school te vinden"
log_in: Aanmelden
- course_labels_search_bar:
+ labels_search_bar:
placeholder: "Label"
add: "Toevoegen"
- edit_explanation: "Voeg een bestaand gebruikerlabel toe of maak een nieuwe aan."
+ edit_explanation: "Voeg een bestaand label toe of maak een nieuwe aan."
progress_bar:
series-admin-progress:
key: ".singular |||| .plural"