From 61958fd0f96b2a33585a593014a08baca6ec18c0 Mon Sep 17 00:00:00 2001 From: Ujjwal Pathak Date: Sat, 13 Jan 2024 10:17:46 +0530 Subject: [PATCH 01/13] added delete button --- app/views/campaigns/_course_row.html.haml | 5 +++++ config/locales/en.yml | 1 + 2 files changed, 6 insertions(+) diff --git a/app/views/campaigns/_course_row.html.haml b/app/views/campaigns/_course_row.html.haml index 11301403c6..a32c5e3faf 100644 --- a/app/views/campaigns/_course_row.html.haml +++ b/app/views/campaigns/_course_row.html.haml @@ -59,3 +59,8 @@ = hidden_field_tag('course_title', course.title, id: "course_title-#{course.id}") %button.button.danger.remove-course{'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title} = t('assignments.remove') + %a.course-link{:href => "#{course_slug_path(course.slug)}", style: "padding-top: 0;"} + = form_for(@campaign, url: remove_course_campaign_path(@campaign.slug, course_id: course.id), method: :put, id: "remove_course-#{course.id}", html: { class: 'remove-program-form' }) do + = hidden_field_tag('course_title', course.title, id: "course_title-#{course.id}") + %button.button.danger.remove-course{'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title} + = t('assignments.delete') \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 7107132695..8ccd950683 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -293,6 +293,7 @@ en: confirm_add_available: Are you sure you want to add %{title}? confirm_addition: Are you sure you want to assign %{title} to %{username}? confirm_deletion: Are you sure you want to delete this assignment? + delete: Delete editors: Assigned to group_members: Group members label: Assign From 81d6dfc1a43862923ddc28392ed481243bb4f38f Mon Sep 17 00:00:00 2001 From: Ujjwal Pathak Date: Sat, 13 Jan 2024 21:10:01 +0530 Subject: [PATCH 02/13] first draft --- app/assets/javascripts/utils/course.js | 18 ++++++++++++++++++ app/assets/stylesheets/_fonts.styl | 5 ++++- app/presenters/courses_presenter.rb | 4 ++++ app/views/campaigns/_course_row.html.haml | 15 ++++++++++----- config/locales/en.yml | 3 ++- 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/utils/course.js b/app/assets/javascripts/utils/course.js index 73c030fd52..e949c56a2b 100644 --- a/app/assets/javascripts/utils/course.js +++ b/app/assets/javascripts/utils/course.js @@ -91,6 +91,24 @@ document.onreadystatechange = () => { }); } + const y = document.getElementsByClassName('delete-course-prerequisite')[0]; + if (y) { + y.addEventListener('click', () => alert(I18n.t('campaign.delete_course_instructions_campaign'))); + } + + const z = document.getElementsByClassName('delete-course-from-campaign')[0]; + if (z) { + z.addEventListener('click', (e) => { + const enteredTitle = window.prompt(I18n.t('courses.confirm_course_deletion', { title: e.target.dataset.title })); + if (!enteredTitle) { + e.preventDefault(); + } else if (enteredTitle.trim() !== e.target.dataset.title.trim()) { + e.preventDefault(); + alert(I18n.t('courses.confirm_course_deletion_failed', { title: enteredTitle })); + } + }); +} + return document.querySelectorAll('select.sorts').forEach(item => item?.addEventListener('change', function () { const list = (() => { switch (this.getAttribute('rel')) { diff --git a/app/assets/stylesheets/_fonts.styl b/app/assets/stylesheets/_fonts.styl index 6843b4c3e4..324a6d7c99 100644 --- a/app/assets/stylesheets/_fonts.styl +++ b/app/assets/stylesheets/_fonts.styl @@ -19,4 +19,7 @@ color zircon .red - color warning \ No newline at end of file + color warning + +.delete-course-prerequisite + margin 0px 24px 12px 24px !important; \ No newline at end of file diff --git a/app/presenters/courses_presenter.rb b/app/presenters/courses_presenter.rb index 9f4a23f14b..7a13d33458 100644 --- a/app/presenters/courses_presenter.rb +++ b/app/presenters/courses_presenter.rb @@ -59,6 +59,10 @@ def can_remove_course? @can_remove ||= current_user&.admin? || campaign_organizer? end + def can_delete_course? + @can_remove ||= current_user&.admin? || campaign_organizer? + end + def campaign_organizer? return false unless campaign return @campaign_organizer if @campaign_organizer_set diff --git a/app/views/campaigns/_course_row.html.haml b/app/views/campaigns/_course_row.html.haml index a32c5e3faf..16bb5062de 100644 --- a/app/views/campaigns/_course_row.html.haml +++ b/app/views/campaigns/_course_row.html.haml @@ -59,8 +59,13 @@ = hidden_field_tag('course_title', course.title, id: "course_title-#{course.id}") %button.button.danger.remove-course{'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title} = t('assignments.remove') - %a.course-link{:href => "#{course_slug_path(course.slug)}", style: "padding-top: 0;"} - = form_for(@campaign, url: remove_course_campaign_path(@campaign.slug, course_id: course.id), method: :put, id: "remove_course-#{course.id}", html: { class: 'remove-program-form' }) do - = hidden_field_tag('course_title', course.title, id: "course_title-#{course.id}") - %button.button.danger.remove-course{'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title} - = t('assignments.delete') \ No newline at end of file + - if @presenter&.can_delete_course? + - if course.campaigns.size > 1 + %button.button.danger.delete-course-prerequisite + = t('assignments.delete') + - else + %a.course-link{:href => "#{course_slug_path(course.slug)}", style: "padding-top: 0;"} + = form_for(@campaign, url: "/courses/#{course.slug}.json", method: :delete, id: "delete_course-#{course.id}", html: { class: 'delete-program-form' }) do + = hidden_field_tag('course_title', course.title, id: "course_title-#{course.id}") + %button.button.danger.delete-course-from-campaign{'data-title' => course.title} + = t('assignments.delete') \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 8ccd950683..32ced747af 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -388,6 +388,7 @@ en: default_passcode_explanation: "By default, new programs in this campaign should have:" description: Description delete_campaign: Delete this campaign + delete_course_instructions_campaign: You may delete this course if all other campaigns are removed first. disable_account_requests: Disable account requests enable_account_requests: Enable account requests newest_campaigns: Newest Campaigns @@ -488,7 +489,7 @@ en: campaign_courses: "%{title} Courses" campaign_select: "Select a campaign" campaign_users: "%{title} Editors" - confirm_course_deletion: Are you sure you want to delete the course titled %{title}? If so, type the title of the course to proceed. + confirm_course_deletion: 'Are you sure you want to delete the course titled %{title}? If so, type the title of the course to proceed.' confirm_course_deletion_failed: '"%{title}" is not the title of this course. The course has not been deleted.' confirm_manual_update: Are you sure you want to run a manual update? The most recent revisions will be imported and then the page will reload. This process may take some time. controlled_by_event_center: Enrollment in this event is controlled by Wikimedia Event Center. It cannot be joined from the Dashboard. From 1499fef66a6e583917067a94074f310a57f79673 Mon Sep 17 00:00:00 2001 From: Ujjwal Pathak Date: Wed, 24 Jan 2024 16:25:09 +0530 Subject: [PATCH 03/13] adding redirect_to after delete --- app/controllers/courses_controller.rb | 8 ++++++-- app/views/campaigns/_course_row.html.haml | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 828c006f45..370c950112 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -60,8 +60,12 @@ def update def destroy validate DeleteCourseWorker.schedule_deletion(course: @course, current_user:) - render json: { success: true } - end + if params[:campaign].nil? + render json: { success: true } + else + redirect_to programs_campaign_path(params[:slug]) + end + end # /courses/school/title_(term) # /courses/school/title_(term)/subpage diff --git a/app/views/campaigns/_course_row.html.haml b/app/views/campaigns/_course_row.html.haml index 16bb5062de..ec8cd15c7f 100644 --- a/app/views/campaigns/_course_row.html.haml +++ b/app/views/campaigns/_course_row.html.haml @@ -65,7 +65,7 @@ = t('assignments.delete') - else %a.course-link{:href => "#{course_slug_path(course.slug)}", style: "padding-top: 0;"} - = form_for(@campaign, url: "/courses/#{course.slug}.json", method: :delete, id: "delete_course-#{course.id}", html: { class: 'delete-program-form' }) do + = form_for(@campaign, url: "/courses/#{course.slug}.json?campaign=true&slug=#{@campaign.slug}", method: :delete, id: "delete_course-#{course.id}", html: { class: 'delete-program-form' }) do = hidden_field_tag('course_title', course.title, id: "course_title-#{course.id}") %button.button.danger.delete-course-from-campaign{'data-title' => course.title} = t('assignments.delete') \ No newline at end of file From e310ba5c2db7c193b31bfb580cdc3a3bc3cda9f6 Mon Sep 17 00:00:00 2001 From: Ujjwal Pathak Date: Sat, 27 Jan 2024 18:48:02 +0530 Subject: [PATCH 04/13] making final changes --- app/controllers/courses_controller.rb | 16 ++++++++++++---- app/views/campaigns/_course_row.html.haml | 8 ++++---- config/locales/en.yml | 2 ++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 370c950112..c5166fcf5f 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -59,11 +59,19 @@ def update def destroy validate - DeleteCourseWorker.schedule_deletion(course: @course, current_user:) - if params[:campaign].nil? - render json: { success: true } - else + if params.key?(:campaign) + campaigns_course = CampaignsCourses.find_by(course_id: @course.id, + campaign_id: params[:campaign_id]) + result = campaigns_course&.destroy + message = result ? 'campaign.course_removed' : 'campaign.course_already_removed' + flash[:notice] = t(message, title: @course.title, + campaign_title: params[:campaign_title]) + end + DeleteCourseWorker.schedule_deletion(course: @course, current_user: current_user) + if params.key?(:campaign) redirect_to programs_campaign_path(params[:slug]) + else + render json: { success: true } end end diff --git a/app/views/campaigns/_course_row.html.haml b/app/views/campaigns/_course_row.html.haml index ec8cd15c7f..29e1e14c70 100644 --- a/app/views/campaigns/_course_row.html.haml +++ b/app/views/campaigns/_course_row.html.haml @@ -57,15 +57,15 @@ %a.course-link{:href => "#{course_slug_path(course.slug)}"} = form_for(@campaign, url: remove_course_campaign_path(@campaign.slug, course_id: course.id), method: :put, id: "remove_course-#{course.id}", html: { class: 'remove-program-form' }) do = hidden_field_tag('course_title', course.title, id: "course_title-#{course.id}") - %button.button.danger.remove-course{'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title} + %button.button.danger.remove-course{ 'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title, title: t('campaign.remove_course_tooltip') } = t('assignments.remove') - if @presenter&.can_delete_course? - if course.campaigns.size > 1 - %button.button.danger.delete-course-prerequisite + %button.button.danger.delete-course-prerequisite{ 'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title, title: t('campaign.delete_course_tooltip') } = t('assignments.delete') - else %a.course-link{:href => "#{course_slug_path(course.slug)}", style: "padding-top: 0;"} - = form_for(@campaign, url: "/courses/#{course.slug}.json?campaign=true&slug=#{@campaign.slug}", method: :delete, id: "delete_course-#{course.id}", html: { class: 'delete-program-form' }) do + = form_for(@campaign, url: "/courses/#{course.slug}.json?campaign=true&campaign_title=#{@campaign.title}&campaign_id=#{@campaign.id}&slug=#{@campaign.slug}", method: :delete, id: "delete_course-#{course.id}", html: { class: 'delete-program-form' }) do = hidden_field_tag('course_title', course.title, id: "course_title-#{course.id}") - %button.button.danger.delete-course-from-campaign{'data-title' => course.title} + %button.button.danger.delete-course-from-campaign{'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title, title: t('campaign.delete_course_tooltip') } = t('assignments.delete') \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 32ced747af..6c9daf8149 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -388,6 +388,7 @@ en: default_passcode_explanation: "By default, new programs in this campaign should have:" description: Description delete_campaign: Delete this campaign + delete_course_tooltip: Delete and remove from the campaign. delete_course_instructions_campaign: You may delete this course if all other campaigns are removed first. disable_account_requests: Disable account requests enable_account_requests: Enable account requests @@ -403,6 +404,7 @@ en: When an organizer creates a program in this campaign, the text in this area will be copied over as a description on the program page random_passcode: a random passcode + remove_course_tooltip: Remove from campaign. requested_accounts: Requested accounts title: Title too_many_articles: The edited article list for this campaign is too long to be displayed. Please view individual courses/programs/events to see the articles edited. From 632aa4295b82db9544ba2f8a0b4d5dce69c106c9 Mon Sep 17 00:00:00 2001 From: Ujjwal Pathak Date: Sat, 27 Jan 2024 19:10:18 +0530 Subject: [PATCH 05/13] very minor changes -- not directly related to my issue --- .../javascripts/components/overview/available_actions.jsx | 2 +- .../List/Assignment/Header/Actions/MarkAsIncompleteButton.jsx | 2 +- config/locales/en.yml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/components/overview/available_actions.jsx b/app/assets/javascripts/components/overview/available_actions.jsx index 0466dc0d32..67ee91f902 100644 --- a/app/assets/javascripts/components/overview/available_actions.jsx +++ b/app/assets/javascripts/components/overview/available_actions.jsx @@ -72,7 +72,7 @@ const AvailableActions = createReactClass({ } const enteredTitle = prompt(I18n.t('courses.confirm_course_deletion', { title: this.props.course.title })); - if (enteredTitle.trim() === this.props.course.title.trim()) { + if (enteredTitle !== null && enteredTitle.trim() === this.props.course.title.trim()) { return this.props.deleteCourse(this.props.course.slug); } else if (enteredTitle) { return alert(I18n.t('courses.confirm_course_deletion_failed', { title: enteredTitle })); diff --git a/app/assets/javascripts/components/overview/my_articles/components/Categories/List/Assignment/Header/Actions/MarkAsIncompleteButton.jsx b/app/assets/javascripts/components/overview/my_articles/components/Categories/List/Assignment/Header/Actions/MarkAsIncompleteButton.jsx index 2c8a3b024a..3a7a4ac818 100644 --- a/app/assets/javascripts/components/overview/my_articles/components/Categories/List/Assignment/Header/Actions/MarkAsIncompleteButton.jsx +++ b/app/assets/javascripts/components/overview/my_articles/components/Categories/List/Assignment/Header/Actions/MarkAsIncompleteButton.jsx @@ -19,7 +19,7 @@ export const MarkAsIncompleteButton = (props) => { className="button danger small" onClick={update({ ...props, dispatch })} > - Mark as Incomplete + {I18n.t('articles.mark_as_complete')} ); diff --git a/config/locales/en.yml b/config/locales/en.yml index 6c9daf8149..46d0ff9082 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -188,6 +188,7 @@ en: history: (history) label: Articles loading: Loading articles... + mark_as_complete: Mark as Complete new: (new) none: This course has not edited any articles. preview: Brief preview of Article From a45a9b09b49512c0d574fada89a6ac51a05a4589 Mon Sep 17 00:00:00 2001 From: Ujjwal Pathak Date: Wed, 14 Feb 2024 20:14:46 +0530 Subject: [PATCH 06/13] minor changes/improvements to code quality --- app/assets/javascripts/utils/course.js | 18 +++++++++--------- app/controllers/courses_controller.rb | 23 ++++++++++++----------- app/presenters/courses_presenter.rb | 2 +- config/locales/en.yml | 2 +- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/app/assets/javascripts/utils/course.js b/app/assets/javascripts/utils/course.js index e949c56a2b..4d6dfa4749 100644 --- a/app/assets/javascripts/utils/course.js +++ b/app/assets/javascripts/utils/course.js @@ -78,9 +78,9 @@ document.onreadystatechange = () => { } // for use on campaign/programs page - const x = document.querySelectorAll('.remove-course'); - for (let i = 0; i < x.length; i += 1) { - x[i]?.addEventListener('click', (e) => { + const removeCourseBtn = document.querySelectorAll('.remove-course'); + for (let i = 0; i < removeCourseBtn.length; i += 1) { + removeCourseBtn[i]?.addEventListener('click', (e) => { const confirmed = window.confirm(I18n.t('campaign.confirm_course_removal', { title: e.target.dataset.title, campaign_title: e.target.dataset.campaignTitle @@ -91,14 +91,14 @@ document.onreadystatechange = () => { }); } - const y = document.getElementsByClassName('delete-course-prerequisite')[0]; - if (y) { - y.addEventListener('click', () => alert(I18n.t('campaign.delete_course_instructions_campaign'))); + const deleteCoursePrerequisiteBtn = document.getElementsByClassName('delete-course-prerequisite')[0]; + if (deleteCoursePrerequisiteBtn) { + deleteCoursePrerequisiteBtn.addEventListener('click', () => alert(I18n.t('campaign.delete_course_instructions_campaign'))); } - const z = document.getElementsByClassName('delete-course-from-campaign')[0]; - if (z) { - z.addEventListener('click', (e) => { + const deleteCourseBtn = document.getElementsByClassName('delete-course-from-campaign')[0]; + if (deleteCourseBtn) { + deleteCourseBtn.addEventListener('click', (e) => { const enteredTitle = window.prompt(I18n.t('courses.confirm_course_deletion', { title: e.target.dataset.title })); if (!enteredTitle) { e.preventDefault(); diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index c5166fcf5f..23fdabb377 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -60,20 +60,21 @@ def update def destroy validate if params.key?(:campaign) - campaigns_course = CampaignsCourses.find_by(course_id: @course.id, - campaign_id: params[:campaign_id]) - result = campaigns_course&.destroy - message = result ? 'campaign.course_removed' : 'campaign.course_already_removed' - flash[:notice] = t(message, title: @course.title, - campaign_title: params[:campaign_title]) - end - DeleteCourseWorker.schedule_deletion(course: @course, current_user: current_user) - if params.key?(:campaign) - redirect_to programs_campaign_path(params[:slug]) + remove_course_from_campaign else + DeleteCourseWorker.schedule_deletion(course: @course, current_user: current_user) render json: { success: true } end - end + end + + def remove_course_from_campaign + campaigns_course = CampaignsCourses.find_by(course_id: @course.id, campaign_id: params[:campaign_id]) + result = campaigns_course.destroy + message = result ? 'campaign.course_removed' : 'campaign.course_already_removed' + flash[:notice] = t(message, title: @course.title, campaign_title: params[:campaign_title]) + DeleteCourseWorker.schedule_deletion(course: @course, current_user: current_user) + redirect_to programs_campaign_path(params[:slug]) + end # /courses/school/title_(term) # /courses/school/title_(term)/subpage diff --git a/app/presenters/courses_presenter.rb b/app/presenters/courses_presenter.rb index 7a13d33458..ac407c214a 100644 --- a/app/presenters/courses_presenter.rb +++ b/app/presenters/courses_presenter.rb @@ -60,7 +60,7 @@ def can_remove_course? end def can_delete_course? - @can_remove ||= current_user&.admin? || campaign_organizer? + @can_delete ||= current_user&.admin? || campaign_organizer? end def campaign_organizer? diff --git a/config/locales/en.yml b/config/locales/en.yml index 46d0ff9082..95a94c5fd0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -294,7 +294,7 @@ en: confirm_add_available: Are you sure you want to add %{title}? confirm_addition: Are you sure you want to assign %{title} to %{username}? confirm_deletion: Are you sure you want to delete this assignment? - delete: Delete + delete: Remove and Delete editors: Assigned to group_members: Group members label: Assign From 12da5503c4943219f5bdacba2fcf583d91a51f08 Mon Sep 17 00:00:00 2001 From: Ujjwal Pathak Date: Sun, 18 Feb 2024 15:25:23 +0530 Subject: [PATCH 07/13] new child controller for delete_course method --- .../components/overview/available_actions.jsx | 1 + .../delete_from_campaign_controller.rb | 46 +++++++++++++++++++ app/controllers/courses_controller.rb | 19 ++------ app/views/campaigns/_course_row.html.haml | 11 +++-- config/locales/en.yml | 2 + config/routes.rb | 5 +- 6 files changed, 63 insertions(+), 21 deletions(-) create mode 100644 app/controllers/courses/delete_from_campaign_controller.rb diff --git a/app/assets/javascripts/components/overview/available_actions.jsx b/app/assets/javascripts/components/overview/available_actions.jsx index 67ee91f902..0e0b899d54 100644 --- a/app/assets/javascripts/components/overview/available_actions.jsx +++ b/app/assets/javascripts/components/overview/available_actions.jsx @@ -72,6 +72,7 @@ const AvailableActions = createReactClass({ } const enteredTitle = prompt(I18n.t('courses.confirm_course_deletion', { title: this.props.course.title })); + // Check if enteredTitle is not null before calling trim. if (enteredTitle !== null && enteredTitle.trim() === this.props.course.title.trim()) { return this.props.deleteCourse(this.props.course.slug); } else if (enteredTitle) { diff --git a/app/controllers/courses/delete_from_campaign_controller.rb b/app/controllers/courses/delete_from_campaign_controller.rb new file mode 100644 index 0000000000..454db2d0e8 --- /dev/null +++ b/app/controllers/courses/delete_from_campaign_controller.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +class Courses::DeleteFromCampaignController < CoursesController + include CourseHelper + + def delete_course_from_campaign + validate + if params.key?(:campaign) + remove_course_from_campaign_but_not_deleted + else + remove_and_delete_course_from_campaign + end + end + + def validate + slug = params[:slug].gsub(/\.json$/, '') + @course = find_course_by_slug(slug) + raise NotPermittedError unless current_user&.can_edit?(@course) + end + + def remove_and_delete_course_from_campaign + campaigns_course = find_campaigns_course + result = campaigns_course.destroy + message = result ? 'campaign.course_removed_and_deleted' : 'campaign.course_already_removed' + flash[:notice] = t(message, title: @course.title, campaign_title: params[:campaign_title]) + DeleteCourseWorker.schedule_deletion(course: @course, current_user: current_user) + redirect_to_campaign_path + end + + def remove_course_from_campaign_but_not_deleted + campaigns_course = find_campaigns_course + result = campaigns_course.destroy + message = result ? 'campaign.course_removed_but_not_deleted' : 'campaign.course_already_removed' + flash[:notice] = t(message, title: @course.title, campaign_title: params[:campaign_title]) + redirect_to_campaign_path + end + + def find_campaigns_course + CampaignsCourses.find_by(course_id: @course.id, campaign_id: params[:campaign_id]) + end + + def redirect_to_campaign_path + redirect_to programs_campaign_path(params[:campaign_slug]) + end + +end \ No newline at end of file diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 23fdabb377..a624e03a0b 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -59,21 +59,8 @@ def update def destroy validate - if params.key?(:campaign) - remove_course_from_campaign - else - DeleteCourseWorker.schedule_deletion(course: @course, current_user: current_user) - render json: { success: true } - end - end - - def remove_course_from_campaign - campaigns_course = CampaignsCourses.find_by(course_id: @course.id, campaign_id: params[:campaign_id]) - result = campaigns_course.destroy - message = result ? 'campaign.course_removed' : 'campaign.course_already_removed' - flash[:notice] = t(message, title: @course.title, campaign_title: params[:campaign_title]) - DeleteCourseWorker.schedule_deletion(course: @course, current_user: current_user) - redirect_to programs_campaign_path(params[:slug]) + DeleteCourseWorker.schedule_deletion(course: @course, current_user:) + render json: { success: true } end # /courses/school/title_(term) @@ -446,4 +433,4 @@ def set_enrollment_details_in_session session['course_slug'] = @course.slug session['enroll_code'] = params['enroll'] || '' end -end +end \ No newline at end of file diff --git a/app/views/campaigns/_course_row.html.haml b/app/views/campaigns/_course_row.html.haml index 29e1e14c70..d595c3552a 100644 --- a/app/views/campaigns/_course_row.html.haml +++ b/app/views/campaigns/_course_row.html.haml @@ -7,7 +7,7 @@ %a.course-link{:href => "#{course_slug_path(course.slug)}"} = course.school + "/" + course.term - if Features.wiki_ed? - %td{:class => "table-link-cell"} + %td{:class => "table-link-cell"} %a.course-link{:href => "#{course_slug_path(course.slug)}"} %span.first_instructor = course.courses_users.where(role: 1).first&.real_name @@ -61,11 +61,14 @@ = t('assignments.remove') - if @presenter&.can_delete_course? - if course.campaigns.size > 1 - %button.button.danger.delete-course-prerequisite{ 'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title, title: t('campaign.delete_course_tooltip') } - = t('assignments.delete') + %a.course-link{:href => "#{course_slug_path(course.slug)}", style: "padding-top: 0;"} + = form_for(@campaign, url: "/courses/#{course.slug}.json/delete_from_campaign?campaign=true&campaign_title=#{@campaign.title}&campaign_id=#{@campaign.id}&campaign_slug=#{@campaign.slug}", method: :delete, id: "delete_course-#{course.id}", html: { class: 'delete-program-form' }) do + = hidden_field_tag('course_title', course.title, id: "course_title-#{course.id}") + %button.button.danger.delete-course-from-campaign{'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title, title: t('campaign.delete_course_tooltip') } + = t('assignments.delete') - else %a.course-link{:href => "#{course_slug_path(course.slug)}", style: "padding-top: 0;"} - = form_for(@campaign, url: "/courses/#{course.slug}.json?campaign=true&campaign_title=#{@campaign.title}&campaign_id=#{@campaign.id}&slug=#{@campaign.slug}", method: :delete, id: "delete_course-#{course.id}", html: { class: 'delete-program-form' }) do + = form_for(@campaign, url: "/courses/#{course.slug}.json/delete_from_campaign?campaign_title=#{@campaign.title}&campaign_id=#{@campaign.id}&campaign_slug=#{@campaign.slug}", method: :delete, id: "delete_course-#{course.id}", html: { class: 'delete-program-form' }) do = hidden_field_tag('course_title', course.title, id: "course_title-#{course.id}") %button.button.danger.delete-course-from-campaign{'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title, title: t('campaign.delete_course_tooltip') } = t('assignments.delete') \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 95a94c5fd0..b9112ce36c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -366,6 +366,8 @@ en: course_already_removed: '"%{title}" was already removed from the "%{campaign_title}" campaign' course: Course course_removed: '"%{title}" has been removed from the "%{campaign_title}" campaign' + course_removed_and_deleted: '"%{title}" has been deleted and removed from the "%{campaign_title}" campaign' + course_removed_but_not_deleted: '"%{title}" has been removed from the "%{campaign_title}" but has not been deleted as it is present in other campaigns as well' create_campaign: Create a New Campaign create_my_campaign: Create my Campaign! customize_passcode: a default passcode diff --git a/config/routes.rb b/config/routes.rb index d3c3d15447..41cb03fcf5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -168,7 +168,10 @@ post '/courses/:slug/students/add_to_watchlist', to: 'courses/watchlist#add_to_watchlist', as: 'add_to_watchlist', constraints: { slug: /.*/ } - + delete 'courses/:slug/delete_from_campaign' => 'courses/delete_from_campaign#delete_course_from_campaign', as: 'delete_from_campaign', + constraints: { + slug: /.*/ + } get 'embed/course_stats/:school/:titleterm(/:_subpage(/:_subsubpage))' => 'embed#course_stats', constraints: { school: /[^\/]*/, From 223296a04c04f13572422c41fbebcdefe002c07e Mon Sep 17 00:00:00 2001 From: Ujjwal Pathak Date: Sun, 18 Feb 2024 18:19:11 +0530 Subject: [PATCH 08/13] fix - ruby linting errors --- .../delete_from_campaign_controller.rb | 9 +- config/application.example.yml | 131 ------------------ config/database.example.yml | 32 ----- 3 files changed, 4 insertions(+), 168 deletions(-) delete mode 100644 config/application.example.yml delete mode 100644 config/database.example.yml diff --git a/app/controllers/courses/delete_from_campaign_controller.rb b/app/controllers/courses/delete_from_campaign_controller.rb index 454db2d0e8..1c5d24a453 100644 --- a/app/controllers/courses/delete_from_campaign_controller.rb +++ b/app/controllers/courses/delete_from_campaign_controller.rb @@ -7,7 +7,7 @@ def delete_course_from_campaign validate if params.key?(:campaign) remove_course_from_campaign_but_not_deleted - else + else remove_and_delete_course_from_campaign end end @@ -17,13 +17,13 @@ def validate @course = find_course_by_slug(slug) raise NotPermittedError unless current_user&.can_edit?(@course) end - + def remove_and_delete_course_from_campaign campaigns_course = find_campaigns_course result = campaigns_course.destroy message = result ? 'campaign.course_removed_and_deleted' : 'campaign.course_already_removed' flash[:notice] = t(message, title: @course.title, campaign_title: params[:campaign_title]) - DeleteCourseWorker.schedule_deletion(course: @course, current_user: current_user) + DeleteCourseWorker.schedule_deletion(course: @course, current_user:) redirect_to_campaign_path end @@ -42,5 +42,4 @@ def find_campaigns_course def redirect_to_campaign_path redirect_to programs_campaign_path(params[:campaign_slug]) end - -end \ No newline at end of file +end diff --git a/config/application.example.yml b/config/application.example.yml deleted file mode 100644 index dc8b44eb9e..0000000000 --- a/config/application.example.yml +++ /dev/null @@ -1,131 +0,0 @@ -# This example configuration is suitable for a development environment. -# Depending on which features you are working on, you may need to make -# adjustments to enable, disable, or configure certain features. - -# This is the main switch between the Wiki Education configuration -# and the Programs & Events Dashboard configuration. -# Set this to 'true' to enable Wiki Education-only features, -# or set it to 'false' to enable the features used for the global community -# instance of the Dashboard. - wiki_education: 'false' - -# The name of the dashboard - dashboard_title: Programs and Events Dashboard -# The root url of the dashboard - dashboard_url: outreachdashboard.wmflabs.org -# description of the dashboard for the 'meta' html tag, which is used by search -# engines - meta_description: Programs and Events dashboard for Wikimedia editing projects - - contact_email: 'contact@wikiedu.org' - - # This is the basis for login/session cookies for Docker builds. - # It gets turned into an environment variable during the build process - # by `waypoint.hcl`. - secret_key_base: - -# a message to display to all users at the top of each page -# sitenotice: "NOTICE: The system will go down for maintenance soon." - -# Pages on meta.wikimedia.org that define training content. -# Only - training_slides_wiki_page: 'Training modules/dashboard/slides' - training_modules_wiki_page: 'Training modules/dashboard/modules' - training_libraries_wiki_page: 'Training modules/dashboard/libraries' - -# Wikimedia OAuth consumer details. Register a consumer at: -# https://meta.wikimedia.org/wiki/Special:OAuthConsumerRegistration/propose -# No one but the user who registers the consumer will be able to log in until -# the consumer gets approved by Wikimedia Foundation staff. -# The example keys are for an auth-only consumer that can be used for development. -# Details about the example consumer can be found here: https://meta.wikimedia.org/w/index.php?title=Special:OAuthListConsumers/view/3f9cb511cf7d0d23f10bbf6fbdc77b26 -# Use that url with the wikipedia_token from another consumer to look up the edit rights -# available to it. - wikipedia_token: 6e171fe7c5fc549ecce52471d22a6b0a - wikipedia_secret: 7f345a52566194a19d2adba5fcbb802e8c79f7ef - -# Setting disable_wiki_output to 'true' means course pages will not be mirrored -# to the wiki, and other on-wiki edits will not be attempted. -# The default OAuth token does allow edits, so take care with this setting even -# in a development environment. -# If enabled here, edits must also be enabled explicitly on a per-wiki -# basis. See below. - disable_wiki_output: 'true' - -# Projects with automatic edits enabled, add as edit_. -# edit_en.wikipedia.org: "true" - -# The default language version of Wikipedia: .wikipedia.org - wiki_language: en - -# The prefix for all course pages that get posted on behalf of users. -# In production, this should probably be in the Project (Wikipedia) namespace, -# and should be a prefix that will only be used for this purpose. -# In development, userspace is a safe option. - course_prefix: 'User:Ragesock' - course_talk_prefix: 'User_talk:Ragesock' - -# This is the community discussion page where new courses should be announced. - course_announcement_page: 'User:Ragesock' - -# Comma-separated list of OAuth client IDs used by the system for Wiki edits - oauth_ids: '252,212' - -# Page ID of the page that is used to indicate training completion. If a user -# has edited this page, they will be counted as having completed training. - training_page_id: '36892501' - -# To set up error logging via Sentry, add a Sentry project url here: - sentry_dsn: 'http://somelongkey:anotherlongkey@sentry.myserver.com/1' - -# The slug for the default campaign - default_campaign: "miscellanea" - -# How many days after a course ends should the dashboard continue updating -# data for it? - update_length: "30" - -# What is the cutoff score for "article completeness" to flag articles/drafts -# as potential DYK candidates? - dyk_wp10_limit: "30" - -# Uncomment cron_log_debug to use log level 'debug' for update logs. The default is 'info'. -# cron_log_debug: "true" - -# Uncomment no_views to disable view stats updates. -# no_views: "true" - -# Logo filename, under the /images directory. - logo_file: "outreach-logo.png" - -# Favicon filename, under /images - favicon_file: "outreach-logo.png" - -# Development-mode favicon filename, under /images - favicon_dev_file: "favicon_dev.png" - -# Enable hot-loading development features. This will only work with 'yarn hot' running. - hot_loading: 'false' - -# Default sender for emails - SENDER_EMAIL_ADDRESS: 'test@example.com' - -# ==== Ticketing System Environment Variables -# Email at which to receive forwarded ticket emails - TICKET_FORWARDING_DOMAIN: 'wikiedu.org' - SALESFORCE_BCC_EMAIL: 'salesforce@salesforce.com' - -# Whitelisted test emails for staging and development -# Except in production, the system will only send mail to these addresses. - survey_test_email: 'developmer@yourdomain.me' - -# Username of communications manager who receives certain alert emails -# Can be left blank. - communications_manager: 'Sage (Wiki Ed)' -# Username of user who will receive requests for technical help from the Get Help button -# Can be left blank. - technical_help_staff: 'Sage (Wiki Ed)' - -# Secret for authentication with Wikimedia Event Center -# Generate one for production or staging via `rails secret` -# WikimediaCampaignsPlatformSecret: diff --git a/config/database.example.yml b/config/database.example.yml deleted file mode 100644 index a675fb29e8..0000000000 --- a/config/database.example.yml +++ /dev/null @@ -1,32 +0,0 @@ -# Only mysql — and probably mariadb — are supported. -# Create a database with utf8 encoding and ut8_unicode_ci collation for development or production. -# Setting up a non-root user and using a password are good ideas. - -default: &default - adapter: mysql2 - encoding: utf8mb4 - username: wiki - password: wikiedu - host: 127.0.0.1 - port: 3306 - pool: 40 - -development: - <<: *default - database: dashboard - -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. -test: - <<: *default - database: dashboard_testing - -staging: - <<: *default - database: - -production: - <<: *default - database: - pool: 40 From b1572af27a70412fee73a5d1b6b3a358f3417967 Mon Sep 17 00:00:00 2001 From: Ujjwal Pathak Date: Sun, 18 Feb 2024 18:36:57 +0530 Subject: [PATCH 09/13] Revert "fix - ruby linting errors" This reverts commit 223296a04c04f13572422c41fbebcdefe002c07e. --- .../delete_from_campaign_controller.rb | 9 +- config/application.example.yml | 131 ++++++++++++++++++ config/database.example.yml | 32 +++++ 3 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 config/application.example.yml create mode 100644 config/database.example.yml diff --git a/app/controllers/courses/delete_from_campaign_controller.rb b/app/controllers/courses/delete_from_campaign_controller.rb index 1c5d24a453..454db2d0e8 100644 --- a/app/controllers/courses/delete_from_campaign_controller.rb +++ b/app/controllers/courses/delete_from_campaign_controller.rb @@ -7,7 +7,7 @@ def delete_course_from_campaign validate if params.key?(:campaign) remove_course_from_campaign_but_not_deleted - else + else remove_and_delete_course_from_campaign end end @@ -17,13 +17,13 @@ def validate @course = find_course_by_slug(slug) raise NotPermittedError unless current_user&.can_edit?(@course) end - + def remove_and_delete_course_from_campaign campaigns_course = find_campaigns_course result = campaigns_course.destroy message = result ? 'campaign.course_removed_and_deleted' : 'campaign.course_already_removed' flash[:notice] = t(message, title: @course.title, campaign_title: params[:campaign_title]) - DeleteCourseWorker.schedule_deletion(course: @course, current_user:) + DeleteCourseWorker.schedule_deletion(course: @course, current_user: current_user) redirect_to_campaign_path end @@ -42,4 +42,5 @@ def find_campaigns_course def redirect_to_campaign_path redirect_to programs_campaign_path(params[:campaign_slug]) end -end + +end \ No newline at end of file diff --git a/config/application.example.yml b/config/application.example.yml new file mode 100644 index 0000000000..dc8b44eb9e --- /dev/null +++ b/config/application.example.yml @@ -0,0 +1,131 @@ +# This example configuration is suitable for a development environment. +# Depending on which features you are working on, you may need to make +# adjustments to enable, disable, or configure certain features. + +# This is the main switch between the Wiki Education configuration +# and the Programs & Events Dashboard configuration. +# Set this to 'true' to enable Wiki Education-only features, +# or set it to 'false' to enable the features used for the global community +# instance of the Dashboard. + wiki_education: 'false' + +# The name of the dashboard + dashboard_title: Programs and Events Dashboard +# The root url of the dashboard + dashboard_url: outreachdashboard.wmflabs.org +# description of the dashboard for the 'meta' html tag, which is used by search +# engines + meta_description: Programs and Events dashboard for Wikimedia editing projects + + contact_email: 'contact@wikiedu.org' + + # This is the basis for login/session cookies for Docker builds. + # It gets turned into an environment variable during the build process + # by `waypoint.hcl`. + secret_key_base: + +# a message to display to all users at the top of each page +# sitenotice: "NOTICE: The system will go down for maintenance soon." + +# Pages on meta.wikimedia.org that define training content. +# Only + training_slides_wiki_page: 'Training modules/dashboard/slides' + training_modules_wiki_page: 'Training modules/dashboard/modules' + training_libraries_wiki_page: 'Training modules/dashboard/libraries' + +# Wikimedia OAuth consumer details. Register a consumer at: +# https://meta.wikimedia.org/wiki/Special:OAuthConsumerRegistration/propose +# No one but the user who registers the consumer will be able to log in until +# the consumer gets approved by Wikimedia Foundation staff. +# The example keys are for an auth-only consumer that can be used for development. +# Details about the example consumer can be found here: https://meta.wikimedia.org/w/index.php?title=Special:OAuthListConsumers/view/3f9cb511cf7d0d23f10bbf6fbdc77b26 +# Use that url with the wikipedia_token from another consumer to look up the edit rights +# available to it. + wikipedia_token: 6e171fe7c5fc549ecce52471d22a6b0a + wikipedia_secret: 7f345a52566194a19d2adba5fcbb802e8c79f7ef + +# Setting disable_wiki_output to 'true' means course pages will not be mirrored +# to the wiki, and other on-wiki edits will not be attempted. +# The default OAuth token does allow edits, so take care with this setting even +# in a development environment. +# If enabled here, edits must also be enabled explicitly on a per-wiki +# basis. See below. + disable_wiki_output: 'true' + +# Projects with automatic edits enabled, add as edit_. +# edit_en.wikipedia.org: "true" + +# The default language version of Wikipedia: .wikipedia.org + wiki_language: en + +# The prefix for all course pages that get posted on behalf of users. +# In production, this should probably be in the Project (Wikipedia) namespace, +# and should be a prefix that will only be used for this purpose. +# In development, userspace is a safe option. + course_prefix: 'User:Ragesock' + course_talk_prefix: 'User_talk:Ragesock' + +# This is the community discussion page where new courses should be announced. + course_announcement_page: 'User:Ragesock' + +# Comma-separated list of OAuth client IDs used by the system for Wiki edits + oauth_ids: '252,212' + +# Page ID of the page that is used to indicate training completion. If a user +# has edited this page, they will be counted as having completed training. + training_page_id: '36892501' + +# To set up error logging via Sentry, add a Sentry project url here: + sentry_dsn: 'http://somelongkey:anotherlongkey@sentry.myserver.com/1' + +# The slug for the default campaign + default_campaign: "miscellanea" + +# How many days after a course ends should the dashboard continue updating +# data for it? + update_length: "30" + +# What is the cutoff score for "article completeness" to flag articles/drafts +# as potential DYK candidates? + dyk_wp10_limit: "30" + +# Uncomment cron_log_debug to use log level 'debug' for update logs. The default is 'info'. +# cron_log_debug: "true" + +# Uncomment no_views to disable view stats updates. +# no_views: "true" + +# Logo filename, under the /images directory. + logo_file: "outreach-logo.png" + +# Favicon filename, under /images + favicon_file: "outreach-logo.png" + +# Development-mode favicon filename, under /images + favicon_dev_file: "favicon_dev.png" + +# Enable hot-loading development features. This will only work with 'yarn hot' running. + hot_loading: 'false' + +# Default sender for emails + SENDER_EMAIL_ADDRESS: 'test@example.com' + +# ==== Ticketing System Environment Variables +# Email at which to receive forwarded ticket emails + TICKET_FORWARDING_DOMAIN: 'wikiedu.org' + SALESFORCE_BCC_EMAIL: 'salesforce@salesforce.com' + +# Whitelisted test emails for staging and development +# Except in production, the system will only send mail to these addresses. + survey_test_email: 'developmer@yourdomain.me' + +# Username of communications manager who receives certain alert emails +# Can be left blank. + communications_manager: 'Sage (Wiki Ed)' +# Username of user who will receive requests for technical help from the Get Help button +# Can be left blank. + technical_help_staff: 'Sage (Wiki Ed)' + +# Secret for authentication with Wikimedia Event Center +# Generate one for production or staging via `rails secret` +# WikimediaCampaignsPlatformSecret: diff --git a/config/database.example.yml b/config/database.example.yml new file mode 100644 index 0000000000..a675fb29e8 --- /dev/null +++ b/config/database.example.yml @@ -0,0 +1,32 @@ +# Only mysql — and probably mariadb — are supported. +# Create a database with utf8 encoding and ut8_unicode_ci collation for development or production. +# Setting up a non-root user and using a password are good ideas. + +default: &default + adapter: mysql2 + encoding: utf8mb4 + username: wiki + password: wikiedu + host: 127.0.0.1 + port: 3306 + pool: 40 + +development: + <<: *default + database: dashboard + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: dashboard_testing + +staging: + <<: *default + database: + +production: + <<: *default + database: + pool: 40 From dd77fdd5bd2419ca388b8af929973920967e342c Mon Sep 17 00:00:00 2001 From: Ujjwal Pathak Date: Sun, 18 Feb 2024 18:43:48 +0530 Subject: [PATCH 10/13] fix - wrong files commited --- .../courses/delete_from_campaign_controller.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/controllers/courses/delete_from_campaign_controller.rb b/app/controllers/courses/delete_from_campaign_controller.rb index 454db2d0e8..1c5d24a453 100644 --- a/app/controllers/courses/delete_from_campaign_controller.rb +++ b/app/controllers/courses/delete_from_campaign_controller.rb @@ -7,7 +7,7 @@ def delete_course_from_campaign validate if params.key?(:campaign) remove_course_from_campaign_but_not_deleted - else + else remove_and_delete_course_from_campaign end end @@ -17,13 +17,13 @@ def validate @course = find_course_by_slug(slug) raise NotPermittedError unless current_user&.can_edit?(@course) end - + def remove_and_delete_course_from_campaign campaigns_course = find_campaigns_course result = campaigns_course.destroy message = result ? 'campaign.course_removed_and_deleted' : 'campaign.course_already_removed' flash[:notice] = t(message, title: @course.title, campaign_title: params[:campaign_title]) - DeleteCourseWorker.schedule_deletion(course: @course, current_user: current_user) + DeleteCourseWorker.schedule_deletion(course: @course, current_user:) redirect_to_campaign_path end @@ -42,5 +42,4 @@ def find_campaigns_course def redirect_to_campaign_path redirect_to programs_campaign_path(params[:campaign_slug]) end - -end \ No newline at end of file +end From 3cae4f5d94ea6079ca3ebb0cf751b3f8dba6466b Mon Sep 17 00:00:00 2001 From: Ujjwal Pathak Date: Tue, 27 Feb 2024 03:04:36 +0530 Subject: [PATCH 11/13] fix - linting error --- app/controllers/courses_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index a624e03a0b..828c006f45 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -433,4 +433,4 @@ def set_enrollment_details_in_session session['course_slug'] = @course.slug session['enroll_code'] = params['enroll'] || '' end -end \ No newline at end of file +end From 3b43fd6dcf937c0bccd350fa282091ebbac9a34d Mon Sep 17 00:00:00 2001 From: Ujjwal Pathak Date: Tue, 27 Feb 2024 20:04:04 +0530 Subject: [PATCH 12/13] fix - changes requested --- app/assets/javascripts/utils/course.js | 5 ----- app/assets/stylesheets/_fonts.styl | 5 +---- .../courses/delete_from_campaign_controller.rb | 2 +- app/presenters/courses_presenter.rb | 4 +--- app/views/campaigns/_course_row.html.haml | 17 +++++------------ config/locales/en.yml | 1 - 6 files changed, 8 insertions(+), 26 deletions(-) diff --git a/app/assets/javascripts/utils/course.js b/app/assets/javascripts/utils/course.js index 4d6dfa4749..d95b91b9f8 100644 --- a/app/assets/javascripts/utils/course.js +++ b/app/assets/javascripts/utils/course.js @@ -91,11 +91,6 @@ document.onreadystatechange = () => { }); } - const deleteCoursePrerequisiteBtn = document.getElementsByClassName('delete-course-prerequisite')[0]; - if (deleteCoursePrerequisiteBtn) { - deleteCoursePrerequisiteBtn.addEventListener('click', () => alert(I18n.t('campaign.delete_course_instructions_campaign'))); - } - const deleteCourseBtn = document.getElementsByClassName('delete-course-from-campaign')[0]; if (deleteCourseBtn) { deleteCourseBtn.addEventListener('click', (e) => { diff --git a/app/assets/stylesheets/_fonts.styl b/app/assets/stylesheets/_fonts.styl index 324a6d7c99..6843b4c3e4 100644 --- a/app/assets/stylesheets/_fonts.styl +++ b/app/assets/stylesheets/_fonts.styl @@ -19,7 +19,4 @@ color zircon .red - color warning - -.delete-course-prerequisite - margin 0px 24px 12px 24px !important; \ No newline at end of file + color warning \ No newline at end of file diff --git a/app/controllers/courses/delete_from_campaign_controller.rb b/app/controllers/courses/delete_from_campaign_controller.rb index 1c5d24a453..c283e36437 100644 --- a/app/controllers/courses/delete_from_campaign_controller.rb +++ b/app/controllers/courses/delete_from_campaign_controller.rb @@ -5,7 +5,7 @@ class Courses::DeleteFromCampaignController < CoursesController def delete_course_from_campaign validate - if params.key?(:campaign) + if @course.campaigns.size > 1 remove_course_from_campaign_but_not_deleted else remove_and_delete_course_from_campaign diff --git a/app/presenters/courses_presenter.rb b/app/presenters/courses_presenter.rb index ac407c214a..00c4e2ab36 100644 --- a/app/presenters/courses_presenter.rb +++ b/app/presenters/courses_presenter.rb @@ -59,9 +59,7 @@ def can_remove_course? @can_remove ||= current_user&.admin? || campaign_organizer? end - def can_delete_course? - @can_delete ||= current_user&.admin? || campaign_organizer? - end + alias_method :can_delete_course?, :can_remove_course? def campaign_organizer? return false unless campaign diff --git a/app/views/campaigns/_course_row.html.haml b/app/views/campaigns/_course_row.html.haml index d595c3552a..7d1bbfecdc 100644 --- a/app/views/campaigns/_course_row.html.haml +++ b/app/views/campaigns/_course_row.html.haml @@ -60,15 +60,8 @@ %button.button.danger.remove-course{ 'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title, title: t('campaign.remove_course_tooltip') } = t('assignments.remove') - if @presenter&.can_delete_course? - - if course.campaigns.size > 1 - %a.course-link{:href => "#{course_slug_path(course.slug)}", style: "padding-top: 0;"} - = form_for(@campaign, url: "/courses/#{course.slug}.json/delete_from_campaign?campaign=true&campaign_title=#{@campaign.title}&campaign_id=#{@campaign.id}&campaign_slug=#{@campaign.slug}", method: :delete, id: "delete_course-#{course.id}", html: { class: 'delete-program-form' }) do - = hidden_field_tag('course_title', course.title, id: "course_title-#{course.id}") - %button.button.danger.delete-course-from-campaign{'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title, title: t('campaign.delete_course_tooltip') } - = t('assignments.delete') - - else - %a.course-link{:href => "#{course_slug_path(course.slug)}", style: "padding-top: 0;"} - = form_for(@campaign, url: "/courses/#{course.slug}.json/delete_from_campaign?campaign_title=#{@campaign.title}&campaign_id=#{@campaign.id}&campaign_slug=#{@campaign.slug}", method: :delete, id: "delete_course-#{course.id}", html: { class: 'delete-program-form' }) do - = hidden_field_tag('course_title', course.title, id: "course_title-#{course.id}") - %button.button.danger.delete-course-from-campaign{'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title, title: t('campaign.delete_course_tooltip') } - = t('assignments.delete') \ No newline at end of file + %a.course-link{:href => "#{course_slug_path(course.slug)}", style: "padding-top: 0;"} + = form_for(@campaign, url: "/courses/#{course.slug}.json/delete_from_campaign?campaign_title=#{@campaign.title}&campaign_id=#{@campaign.id}&campaign_slug=#{@campaign.slug}", method: :delete, id: "delete_course-#{course.id}", html: { class: 'delete-program-form' }) do + = hidden_field_tag('course_title', course.title, id: "course_title-#{course.id}") + %button.button.danger.delete-course-from-campaign{'data-id' => course.id, 'data-title' => course.title, 'data-campaign-title' => @campaign.title, title: t('campaign.delete_course_tooltip') } + = t('assignments.delete') \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index b9112ce36c..91d95ef0f9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -392,7 +392,6 @@ en: description: Description delete_campaign: Delete this campaign delete_course_tooltip: Delete and remove from the campaign. - delete_course_instructions_campaign: You may delete this course if all other campaigns are removed first. disable_account_requests: Disable account requests enable_account_requests: Enable account requests newest_campaigns: Newest Campaigns From 87ffb261191f117671ee88940314d8247695b678 Mon Sep 17 00:00:00 2001 From: Ujjwal Pathak Date: Tue, 27 Feb 2024 20:06:26 +0530 Subject: [PATCH 13/13] updated syntax for alias_method --- app/presenters/courses_presenter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/presenters/courses_presenter.rb b/app/presenters/courses_presenter.rb index 00c4e2ab36..519b5e0dda 100644 --- a/app/presenters/courses_presenter.rb +++ b/app/presenters/courses_presenter.rb @@ -59,7 +59,7 @@ def can_remove_course? @can_remove ||= current_user&.admin? || campaign_organizer? end - alias_method :can_delete_course?, :can_remove_course? + alias can_delete_course? can_remove_course? def campaign_organizer? return false unless campaign