Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tokens for labels on activity edit page #5385

Merged
merged 4 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
107 changes: 0 additions & 107 deletions app/assets/javascripts/components/course_labels_search_bar.ts

This file was deleted.

124 changes: 124 additions & 0 deletions app/assets/javascripts/components/labels_search_bar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { customElement, property } from "lit/decorators.js";
import { html, TemplateResult } from "lit";

Check warning on line 2 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L1-L2

Added lines #L1 - L2 were not covered by tests
import { Option } from "components/datalist_input";
import "components/datalist_input";
import { i18n } from "i18n/i18n";
import { DodonaElement } from "components/meta/dodona_element";

Check warning on line 6 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L4-L6

Added lines #L4 - L6 were not covered by tests
/**
* 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 {

Check warning on line 15 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L15

Added line #L15 was not covered by tests
@property({ type: Array })
labels: string[];

Check warning on line 17 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L17

Added line #L17 was not covered by tests
@property({ type: String })
name: string;

Check warning on line 19 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L19

Added line #L19 was not covered by tests

removeLabel(label: string): void {
this.dispatchEvent(new CustomEvent("remove-label", {

Check warning on line 22 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L21-L22

Added lines #L21 - L22 were not covered by tests
detail: {
value: label,
},
}));
}

render(): TemplateResult {

Check warning on line 29 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L29

Added line #L29 was not covered by tests
if (!this.labels) {
return html``;

Check warning on line 31 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L31

Added line #L31 was not covered by tests
}

return html`

Check warning on line 34 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L34

Added line #L34 was not covered by tests
${ this.labels.length > 0 ? html`
<div class="labels">
${ this.labels.map( label => html`

Check warning on line 37 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L37

Added line #L37 was not covered by tests
<span class="token accent-orange">${label}
<a href="#" class="close" tabindex="-1" @click=${() => this.removeLabel(label)}>×</a>

Check warning on line 39 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L39

Added line #L39 was not covered by tests
</span>
`)}
</div>
` : html`` }

Check warning on line 43 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L43

Added line #L43 was not covered by tests
<input type="hidden" name="${this.name}" .value="${this.labels.join(",")}">
`;
}
}

/**
* 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 {

Check warning on line 60 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L60

Added line #L60 was not covered by tests
@property({ type: Array })
labels: {id: number, name: string}[];

Check warning on line 62 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L62

Added line #L62 was not covered by tests
@property({ type: Array })
selected_labels: string[];

Check warning on line 64 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L64

Added line #L64 was not covered by tests
@property({ type: String })
name: string;

Check warning on line 66 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L66

Added line #L66 was not covered by tests

@property({ state: true })
selected_label: string;

Check warning on line 69 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L69

Added line #L69 was not covered by tests
@property({ state: true })
filter: string;

Check warning on line 71 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L71

Added line #L71 was not covered by tests

get options(): Option[] {
return this.labels
.filter(i => !this.selected_labels.includes(i.name))
.map(i => ({ label: i.name, value: i.id.toString() }));

Check warning on line 76 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L73-L76

Added lines #L73 - L76 were not covered by tests
}

addLabel(): void {
const selectedLabel = this.selected_label.trim();

Check warning on line 80 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L79-L80

Added lines #L79 - L80 were not covered by tests
if (selectedLabel.length > 0 && !this.selected_labels.includes(selectedLabel)) {
this.selected_labels = [...this.selected_labels, selectedLabel];
this.filter = "";

Check warning on line 83 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L82-L83

Added lines #L82 - L83 were not covered by tests
}
}

handleInput(e: CustomEvent): void {
this.selected_label = e.detail.label;
this.filter = e.detail.label;

Check warning on line 89 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L87-L89

Added lines #L87 - L89 were not covered by tests
}

handleKeyDown(e: KeyboardEvent): void {

Check warning on line 92 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L92

Added line #L92 was not covered by tests
if (e.key === "Enter" || e.key === "Tab") {
this.addLabel();

Check warning on line 94 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L94

Added line #L94 was not covered by tests
}
}

removeLabel(label: string): void {
this.selected_labels = this.selected_labels.filter(i => i !== label);

Check warning on line 99 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L98-L99

Added lines #L98 - L99 were not covered by tests
}

render(): TemplateResult {
return html`

Check warning on line 103 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L102-L103

Added lines #L102 - L103 were not covered by tests
<div>
<d-labels
.labels=${this.selected_labels}
.name=${this.name}
@remove-label=${(e: CustomEvent) => this.removeLabel(e.detail.value)}

Check warning on line 108 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L108

Added line #L108 was not covered by tests
></d-labels>
<div class="labels-searchbar-group input-group autocomplete">
<d-datalist-input
.filter="${this.filter}"
.options=${this.options}
@input=${e => this.handleInput(e)}
@keydown=${e => this.handleKeyDown(e)}

Check warning on line 115 in app/assets/javascripts/components/labels_search_bar.ts

View check run for this annotation

Codecov / codecov/patch

app/assets/javascripts/components/labels_search_bar.ts#L114-L115

Added lines #L114 - L115 were not covered by tests
placeholder="${i18n.t("js.labels_search_bar.placeholder")}"
></d-datalist-input>
<a type="button" class="btn btn-filled add-button" @click="${this.addLabel}">${i18n.t("js.labels_search_bar.add")}</a>
</div>
<span class="help-block">${i18n.t("js.labels_search_bar.edit_explanation")}</span>
</div>
`;
}
}
20 changes: 10 additions & 10 deletions app/assets/javascripts/i18n/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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"
Expand Down
14 changes: 11 additions & 3 deletions app/assets/stylesheets/components/courselabel-edit.css.scss
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
1 change: 0 additions & 1 deletion app/javascript/packs/course_membership.js

This file was deleted.

1 change: 1 addition & 0 deletions app/javascript/packs/label_search_bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "components/labels_search_bar";
12 changes: 10 additions & 2 deletions app/views/activities/_form.html.erb
Original file line number Diff line number Diff line change
@@ -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? %>
<div class="callout callout-danger" id="error_explanation">
Expand All @@ -23,8 +26,13 @@
</div>
<div class="field form-group row">
<%= f.label :labels, :class => "col-sm-3 col-12 col-form-label" %>
<div class="col-sm-6 col-12"><%= f.text_field :labels, class: 'form-control', disable: !f.permission?(:labels), value: activity.labels.map(&:name).join(','), placeholder: t(".labels") %></div>
<span class="help-block offset-sm-3 col-sm-6 col-12"><%= t '.labels_delimiter' %></span>
<div class="col-sm-6 col-12">
<d-labels-search-bar
labels="<%= activity.repository.labels.map{|l| {id: l.id, name: l.name}}.to_json %>"
selected_labels="<%= activity.labels.map(&:name).to_json %>"
name="activity[labels]"
></d-labels-search-bar>
</div>
</div>
<div class="field form-group row">
<label class="col-sm-3 col-12 col-form-label"><%= t ".edit_activity" %></label>
Expand Down
7 changes: 4 additions & 3 deletions app/views/course_members/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<% content_for :javascripts do %>
<% javascript_include_tag 'course_membership' %>
<% javascript_include_tag 'label_search_bar' %>
<% end %>
<%= form_for(course_membership, :url => course_member_path(course, user), :html => {:class => 'form-horizontal'}) do |f| %>
<% if course_membership.errors.any? %>
Expand All @@ -16,10 +16,11 @@
<div class="row">
<%= f.label :course_labels, :class => 'col-sm-2 col-10 col-form-label' %>
<div class="col-sm-10 col-10">
<d-course-labels-search-bar
<d-labels-search-bar
labels="<%= @course_labels.map{|cl| {id: cl.id, name: cl.name}}.to_json %>"
selected_labels="<%= @course_membership.course_labels.map(&:name).to_json %>"
></d-course-labels-search-bar>
name="course_membership[course_labels]"
></d-labels-search-bar>
</div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions config/locales/js/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions config/locales/js/nl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down