Skip to content

Commit

Permalink
Merge pull request #3600 from dodona-edu/feature/annotation-reuse
Browse files Browse the repository at this point in the history
Allow easy re-use of annotations
  • Loading branch information
jorg-vr authored Sep 19, 2022
2 parents f4b1adf + f30982a commit 0b6c1de
Show file tree
Hide file tree
Showing 77 changed files with 2,367 additions and 276 deletions.
3 changes: 0 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,6 @@ gem 'has_scope', '~> 0.8.0'
# generating zip files
gem 'rubyzip', '~> 2.3.2'

# add request server timings to the devtools
gem 'rails_server_timings', '~> 1.0.8'

# bootstrap tokenizer
gem 'bootstrap_tokenfield_rails', '~> 0.12.1'

Expand Down
33 changes: 16 additions & 17 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ GEM
after_commit_everywhere (1.2.2)
activerecord (>= 4.2)
activesupport
airbrussh (1.4.0)
airbrussh (1.4.1)
sshkit (>= 1.6.1, != 1.7.0)
annotate (3.2.0)
activerecord (>= 3.2, < 8.0)
Expand All @@ -91,7 +91,7 @@ GEM
bootstrap_tokenfield_rails (0.12.1)
builder (3.2.4)
byebug (11.1.3)
capistrano (3.17.0)
capistrano (3.17.1)
airbrussh (>= 1.0.0)
i18n
rake (>= 10.0.0)
Expand Down Expand Up @@ -166,7 +166,7 @@ GEM
exception_notification (4.5.0)
actionmailer (>= 5.2, < 8)
activesupport (>= 5.2, < 8)
excon (0.92.3)
excon (0.92.4)
execjs (2.8.1)
factory_bot (6.2.1)
activesupport (>= 5.0.0)
Expand All @@ -175,13 +175,13 @@ GEM
railties (>= 5.0.0)
faker (2.23.0)
i18n (>= 1.8.11, < 2)
faraday (2.3.0)
faraday-net_http (~> 2.0)
faraday (2.5.2)
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
faraday-net_http (2.0.3)
faraday-net_http (3.0.0)
ffi (1.15.5)
flamegraph (0.9.5)
glob (0.3.0)
glob (0.3.1)
globalid (1.0.0)
activesupport (>= 5.0)
has_scope (0.8.0)
Expand Down Expand Up @@ -213,10 +213,11 @@ GEM
jsbundling-rails (1.0.3)
railties (>= 6.0.0)
json (2.6.2)
json-jwt (1.14.0)
json-jwt (1.15.3)
activesupport (>= 4.2)
aes_key_wrap
bindata
httpclient
json-schema (3.0.0)
addressable (>= 2.8)
jwt (2.5.0)
Expand Down Expand Up @@ -283,7 +284,7 @@ GEM
nio4r (2.5.8)
nokogiri (1.13.8-x86_64-linux)
racc (~> 1.4)
oauth2 (1.4.9)
oauth2 (1.4.10)
faraday (>= 0.17.3, < 3.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
Expand All @@ -304,10 +305,11 @@ GEM
addressable (~> 2.5)
omniauth (>= 1.9, < 3)
openid_connect (~> 1.1)
openid_connect (1.3.0)
openid_connect (1.3.1)
activemodel
attr_required (>= 1.0.0)
json-jwt (>= 1.5.0)
net-smtp
rack-oauth2 (>= 1.6.1)
swd (>= 1.0.0)
tzinfo
Expand Down Expand Up @@ -336,7 +338,7 @@ GEM
rack (2.2.4)
rack-mini-profiler (3.0.0)
rack (>= 1.2.0)
rack-oauth2 (1.19.0)
rack-oauth2 (1.21.2)
activesupport
attr_required
httpclient
Expand Down Expand Up @@ -372,8 +374,6 @@ GEM
rails-i18n (7.0.5)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
rails_server_timings (1.0.8)
railties (>= 3.0.0)
railties (7.0.4)
actionpack (= 7.0.4)
activesupport (= 7.0.4)
Expand All @@ -383,7 +383,7 @@ GEM
zeitwerk (~> 2.5)
rainbow (3.1.1)
rake (13.0.6)
rb-fsevent (0.11.1)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
rb-readline (0.5.5)
Expand Down Expand Up @@ -434,14 +434,14 @@ GEM
rack-protection (= 2.2.2)
tilt (~> 2.0)
slack-notifier (2.4.0)
sprockets (4.1.0)
sprockets (4.1.1)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.4.2)
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
sshkit (1.21.2)
sshkit (1.21.3)
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
stackprof (0.2.21)
Expand Down Expand Up @@ -553,7 +553,6 @@ DEPENDENCIES
rails (~> 7.0.4)
rails-controller-testing (~> 1.0.5)
rails-i18n (~> 7.0.5)
rails_server_timings (~> 1.0.8)
rb-readline (~> 0.5.5)
rouge (= 4.0.0)
rubocop-rails (~> 2.16.0)
Expand Down
54 changes: 45 additions & 9 deletions app/assets/javascripts/code_listing/annotation.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { NewSavedAnnotation } from "components/saved_annotations/new_saved_annotation";
import { isBetaCourse } from "saved_annotation_beta";
import { SavedAnnotationIcon } from "components/saved_annotations/saved_annotation_icon";

export type AnnotationType = "error" | "info" | "user" | "warning" | "question";
export type QuestionState = "unanswered" | "answered" | "in_progress";

Expand All @@ -10,6 +14,7 @@ export abstract class Annotation {
public readonly line: number | null;
public readonly text: string;
public readonly type: AnnotationType;
public readonly id: number;

protected constructor(line: number | null, text: string, type: AnnotationType) {
this.__html = null;
Expand Down Expand Up @@ -54,7 +59,7 @@ export abstract class Annotation {

if (!this.visible) {
const icon = document.createElement("i");
icon.classList.add("mdi", "mdi-eye-off", "mdi-18", "annotation-visibility");
icon.classList.add("mdi", "mdi-eye-off", "mdi-18", "annotation-meta-icon");
icon.title = I18n.t("js.user_annotation.not_released");
meta.appendChild(icon);
}
Expand All @@ -81,16 +86,38 @@ export abstract class Annotation {

// Update button.
if (this.modifiable) {
const link = document.createElement("a");
link.addEventListener("click", () => this.edit());
link.classList.add("btn", "btn-icon", "annotation-control-button", "annotation-edit");
link.title = this.editTitle;
const editLink = document.createElement("a");
editLink.addEventListener("click", () => this.edit());
editLink.classList.add("btn", "btn-icon", "annotation-control-button", "annotation-edit");
editLink.title = this.editTitle;

const icon = document.createElement("i");
icon.classList.add("mdi", "mdi-pencil");
link.appendChild(icon);
const editIcon = document.createElement("i");
editIcon.classList.add("mdi", "mdi-pencil");
editLink.appendChild(editIcon);

header.appendChild(link);
header.appendChild(editLink);

// REMOVE IF AFTER CLOSED BETA
if (isBetaCourse(this.courseId)) {
// Add button to create saved annotation
const saveLink = new NewSavedAnnotation();
saveLink.fromAnnotationId = this.id;
saveLink.annotationText = this.rawText;
saveLink.savedAnnotationId = this.savedAnnotationId;

header.appendChild(saveLink);

// Add icon to signify saved annotation
const icon = new SavedAnnotationIcon();
icon.savedAnnotationId = this.savedAnnotationId;

// update icon if annotation is saved
saveLink.addEventListener("created", (e: CustomEvent) => {
icon.savedAnnotationId = e.detail.id;
});

meta.appendChild(icon);
}
}

if (this.transitionable("answered")) {
Expand Down Expand Up @@ -174,6 +201,10 @@ export abstract class Annotation {
return this.text;
}

public get savedAnnotationId(): number | null {
return null;
}

public get removable(): boolean {
return false;
}
Expand Down Expand Up @@ -212,6 +243,11 @@ export abstract class Annotation {
return true;
}

// REMOVE AFTER CLOSED BETA
protected get courseId(): number {
return undefined;
}

public async update(data): Promise<Annotation> {
// Do nothing.
return data;
Expand Down
Loading

0 comments on commit 0b6c1de

Please sign in to comment.