Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
EIP
Project Forum
Project Forum
Commits
2558d21e
Commit
2558d21e
authored
Jul 29, 2022
by
Taico Aerts
Browse files
Merge branch 'development' into 'master'
Project Forum Release 2.8.2 See merge request
!787
parents
ad6620da
83b1a74b
Changes
103
Hide whitespace changes
Inline
Side-by-side
.gitlab-ci.yml
View file @
2558d21e
...
...
@@ -13,6 +13,9 @@ include:
-
template
:
Dependency-Scanning.gitlab-ci.yml
-
template
:
Security/SAST.gitlab-ci.yml
variables
:
SAST_EXCLUDED_ANALYZERS
:
'
brakeman,bundler-audit'
license_scanning
:
variables
:
USE_FREEDESKTOP_PLACEHOLDER
:
"
true"
...
...
app/assets/javascripts/normal/registration_form.js
deleted
100644 → 0
View file @
ad6620da
$
(
document
).
on
(
'
turbolinks:load
'
,
function
(){
var
typingTimer
;
var
typingInterval
=
200
;
var
$input
=
$
(
'
.register #user_email
'
);
var
$preview
=
$
(
'
#email-preview
'
);
var
$panel
=
$preview
.
parent
().
parent
();
var
$spinner
=
$panel
.
find
(
'
.spinner-container
'
);
var
loadingAnimation
=
{
start
:
function
()
{
$spinner
.
height
(
$spinner
.
parent
().
height
()
+
2
*
parseInt
(
$spinner
.
parent
().
css
(
'
padding-bottom
'
)));
$spinner
.
show
();
},
stop
:
function
()
{
$spinner
.
hide
();
}
}
$input
.
on
(
'
keyup keydown
'
,
function
()
{
resetTypingTimer
();
loadingAnimation
.
start
();
});
function
resetTypingTimer
()
{
clearTimeout
(
typingTimer
);
typingTimer
=
setInterval
(
refreshPreview
,
typingInterval
);
}
function
refreshPreview
()
{
clearTimeout
(
typingTimer
);
$
.
ajax
({
url
:
$input
.
attr
(
'
data-url
'
),
data
:
{
email
:
$input
.
val
()
},
type
:
'
post
'
,
dataType
:
"
script
"
,
success
:
loadingAnimation
.
stop
});
}
if
(
$input
.
length
>
0
)
{
refreshPreview
();
}
});
app/assets/stylesheets/normal/_login.scss
View file @
2558d21e
...
...
@@ -31,7 +31,7 @@
}
.login--wide
{
max-width
:
84
0px
;
margin
:
15vh
auto
0
auto
;
max-width
:
63
0px
;
margin
:
15vh
auto
0
auto
;
}
.login
{
...
...
app/assets/stylesheets/normal/helpers.scss
View file @
2558d21e
...
...
@@ -108,6 +108,23 @@
.pno
{
padding
:
0
;
}
.mno
{
margin
:
0
;
}
.d-flex
{
display
:
flex
;
}
.justify-content-space-between
{
justify-content
:
space-between
;
}
.flex-column
{
flex-direction
:
column
;
}
.row-equal-height
{
display
:
flex
;
flex-wrap
:
wrap
;
}
/* --------------
BORDER
-------------- */
...
...
@@ -197,6 +214,7 @@
.txt-strong
,
.txt-bold
{
font-weight
:bold
;
}
.txt-italic
{
font-style
:
italic
;
}
.txt-underline
{
text-decoration
:
underline
;
}
.txt-uppercase
{
text-transform
:
uppercase
;
}
.txt-lowercase
{
text-transform
:
lowercase
;
}
...
...
app/controllers/admin/course_editions_controller.rb
View file @
2558d21e
...
...
@@ -77,7 +77,6 @@ module Admin
@course_edition
=
old_course_edition
.
dup
@course_edition
.
configuration
=
old_course_edition
.
configuration
.
dup
@course_edition
.
name
+=
' - Copy'
@course_edition
.
status
=
:hidden
old_course_edition
.
deadlines
.
each
do
|
deadline
|
...
...
@@ -100,6 +99,15 @@ module Admin
end
@override_staff_roles
[
staffmember
]
=
r
end
if
params
[
:active_period
].
nil?
@course_edition
.
name
+=
' - Copy'
else
@course_edition
.
name
+=
" -
#{
Period
.
find_by
(
id:
params
[
:active_period
]).
name
}
"
@course_edition
.
active_period_id
=
params
[
:active_period
]
@course_edition
.
recurrent
=
false
@course_edition
.
recurrent_edition_id
=
old_course_edition
.
id
end
end
def
update
...
...
app/controllers/admin/programmes_controller.rb
View file @
2558d21e
...
...
@@ -89,7 +89,7 @@ module Admin
def
programme_params
params
.
require
(
:programme
).
permit
(
%i[name sso_name]
+
[
configuration_attributes:
%i[course_name group_name project_name company_name]
]
%i[name sso_name]
+
[
configuration_attributes:
%i[course_name group_name
student_group_name
project_name company_name]
]
)
end
end
...
...
app/controllers/companies/role_invitations_controller.rb
View file @
2558d21e
...
...
@@ -49,8 +49,26 @@ module Companies
protected
def
invite_existing_user
(
email
)
user
=
User
.
find_by
email:
email
# do not create a new invitation if the user is an unconfirmed employee
if
user
.
has_role?
(
:unconfirmed_employee
,
@company
)
User
.
transaction
do
user
.
remove_role
:unconfirmed_employee
,
@company
user
.
add_role
:employee
,
@company
end
flash
[
:success
]
=
'Employee successfully confirmed.'
return
end
# do not create a new invitation if the user is already an employee
if
user
.
has_role?
(
:employee
,
@company
)
||
user
.
has_role?
(
:registrar
,
@company
)
flash
[
:danger
]
=
'This user is already an employee.'
return
end
@role_invitation
=
RoleInvitation
.
new
role_invitation_params
@role_invitation
.
user
=
U
ser
.
find_by
email:
email
@role_invitation
.
user
=
u
ser
@role_invitation
.
save
if
@role_invitation
.
persisted?
...
...
app/controllers/companies_controller.rb
View file @
2558d21e
...
...
@@ -82,9 +82,13 @@ class CompaniesController < OfferersController
def
join
@company
=
Company
.
find
(
params
[
:company
])
if
@company
.
allow_to_join
current_user
.
add_role
:unconfirmed_employee
,
@company
if
current_user
.
role_invitations
.
where
(
resource:
@company
,
name: :employee
).
none?
current_user
.
add_role
:unconfirmed_employee
,
@company
else
current_user
.
add_role
:employee
,
@company
end
end
if
current_user
.
has_role?
:unconfirmed_employee
,
@company
if
current_user
.
has_role?
(
:unconfirmed_employee
,
@company
)
||
current_user
.
has_role?
(
:employee
,
@company
)
flash
[
:success
]
=
'Successfully joined company'
else
flash
[
:danger
]
=
'Failed to join company'
...
...
@@ -92,25 +96,14 @@ class CompaniesController < OfferersController
redirect_back
(
fallback_location:
offerer_url
(
@company
.
acting_as
),
allow_other_host:
false
)
end
def
search
matching_companies
=
Company
.
without_role
(
%i[registrar employee unconfirmed_employee]
,
current_user
)
unless
params
[
:name
].
empty?
matching_companies
=
matching_companies
.
where
(
id:
Company
.
search
(
params
[
:name
]).
records
.
ids
)
end
respond_to
do
|
format
|
format
.
json
{
render
json:
matching_companies
}
end
end
protected
def
page_title
case
action_name
when
'show'
,
'edit'
"
#{
@company
.
name
}
-
Companies
-
#{
super
}
"
"
#{
@company
.
name
}
-
#{
current_user
.
companies_name
.
capitalize
}
-
#{
super
}
"
else
"
Companies
-
#{
super
}
"
"
#{
current_user
.
companies_name
.
capitalize
}
-
#{
super
}
"
end
end
...
...
app/controllers/concerns/params_concerns/course_editions.rb
View file @
2558d21e
...
...
@@ -10,6 +10,8 @@ module ParamsConcerns
enrolment_starts_at enrolment_ends_at
offering_projects_starts_at offering_projects_ends_at
preference_ends_at proposal_template
active_period_id
recurrent recurrent_edition_id
]
.
freeze
##
...
...
@@ -19,6 +21,7 @@ module ParamsConcerns
BASE
+
[
deadlines_attributes:
ParamsConcerns
::
Deadlines
::
BASE
+
%i[id _destroy]
,
course_specific_roles_attributes:
ParamsConcerns
::
CourseSpecificRoles
::
BASE
+
%i[id _destroy]
,
projects_attributes:
ParamsConcerns
::
Projects
::
BASE
+
%i[id _destroy]
,
periods_attributes:
ParamsConcerns
::
Periods
::
BASE
+
%i[id _destroy]
,
configuration_attributes:
\
ParamsConcerns
::
CourseConfigurations
::
BASE
+
%i[id]
...
...
app/controllers/concerns/params_concerns/projects.rb
View file @
2558d21e
...
...
@@ -10,6 +10,7 @@ module ParamsConcerns
:offerer_id
,
:course_edition_id
,
:company_contact
,
:projects_modify
,
{
period_ids:
[]
},
{
tag_ids:
[]
}].
freeze
...
...
app/controllers/concerns/preference_mapper.rb
0 → 100644
View file @
2558d21e
module
PreferenceMapper
# Copies project preferences from the given user for the source course edition to the target course edition.
# Both editions should have been created from a recurring course edition.
# Projects are matched through their original project (recurrent course edition). Projects that don't appear in the target are excluded.
# Priorities are remapped such that they all appear at the top of the list, while new projects appear with a "new" tag.
#
# @param user [User]
# @param source_ce [CourseEdition] source course edition
# @param target_ce [CourseEdition] target course edition
def
copy_priorities
(
user
,
source_ce
,
target_ce
)
if
user
.
project_preferences
.
where
(
course_edition_id:
target_ce
).
any?
# Ask for confirmation? Already preferences present.
return
false
end
# We need to reassign priorities for the course edition, they start at 1.
priority
=
1
# All the preferences in the source edition which match in original_project_id with projects in the target edition
user
.
project_preferences
.
where
(
course_edition_id:
source_ce
)
.
joins
(
:project
)
.
where
(
projects:
{
original_project_id:
target_ce
.
projects
.
select
(
:original_project_id
)
})
.
order
(
:priority
)
.
each
do
|
pp
|
# Find the copy of the project in the target course edition
project
=
pp
.
project
.
original_project
.
copies
.
find_by
(
course_edition_id:
target_ce
)
# Create a copy
ProjectPreference
.
create
(
user_id:
user
.
id
,
project_id:
project
.
id
,
course_edition_id:
target_ce
.
id
,
priority:
priority
)
# Increment the priority
priority
+=
1
end
end
# Copies project interests from the given user for the source course edition to the target course edition.
# Both editions should have been created from a recurring course edition.
# Projects are matched through their original project (recurrent course edition). Projects that don't appear in the target are excluded.
#
# @param user [User]
# @param source_ce [CourseEdition] source course edition
# @param target_ce [CourseEdition] target course edition
def
copy_project_interests
(
user
,
source_ce
,
target_ce
)
user
.
project_interests
.
joins
(
:project
)
.
where
(
projects:
{
course_edition_id:
source_ce
})
.
where
(
projects:
{
original_project_id:
target_ce
.
projects
.
select
(
:original_project_id
)
})
.
each
do
|
pi
|
# Find the copy of the project in the target course edition
project
=
pi
.
project
.
original_project
.
copies
.
find_by
(
course_edition_id:
target_ce
)
# Create a copy
ProjectInterest
.
create
(
user_id:
user
.
id
,
project_id:
project
.
id
)
end
end
end
app/controllers/course_editions/project_preferences_controller.rb
View file @
2558d21e
module
CourseEditions
class
ProjectPreferencesController
<
ApplicationController
include
CourseEditionAccessible
include
PreferenceMapper
load_and_authorize_resource
...
...
@@ -22,6 +23,12 @@ module CourseEditions
# If the user has any preferences stored
@any_preferences
=
current_user
.
project_preferences?
(
@course_edition
)
@other_preferences
=
if
@course_edition
.
recurrent_edition
.
nil?
false
else
ProjectPreference
.
where
(
user:
current_user
,
course_edition:
CourseEdition
.
descendants_of
(
@course_edition
.
recurrent_edition
)).
any?
end
@project_name
=
@course_edition
.
configuration
.
project_name_text
(
false
,
false
)
@projects_name
=
@course_edition
.
configuration
.
project_name_text
(
false
,
true
)
...
...
@@ -30,6 +37,11 @@ module CourseEditions
@projects
=
@course_edition
.
approved_projects
(
current_user
)
end
def
copy
copy_priorities
(
current_user
,
CourseEdition
.
find_by
(
id:
params
[
:previous_course_edition
]),
@course_edition
)
redirect_to
course_edition_preferences_path
(
@course_edition
)
end
protected
def
page_title
...
...
app/controllers/course_editions/projects_controller.rb
View file @
2558d21e
module
CourseEditions
class
ProjectsController
<
ApplicationController
include
CourseEditionAccessible
include
PreferenceMapper
# Load the project
before_action
:load_project
,
only:
%i[show update destroy]
...
...
@@ -46,22 +47,38 @@ module CourseEditions
@visible_project_count
=
@possible_projects
.
count
@page_count
=
25
@any_interests
=
current_user
.
project_interests?
(
@course_edition
)
@other_interests
=
if
@course_edition
.
recurrent_edition
.
nil?
false
else
ProjectInterest
.
joins
(
:project
)
.
where
(
user:
current_user
,
projects:
{
course_edition_id:
CourseEdition
.
descendants_of
(
@course_edition
.
recurrent_edition
)
})
.
any?
end
apply_search
apply_filters
apply_ordering
paginate_projects
end
def
copy_interests
copy_project_interests
(
current_user
,
CourseEdition
.
find_by
(
id:
params
[
:previous_course_edition
]),
@course_edition
)
redirect_to
course_edition_projects_path
(
@course_edition
)
end
protected
def
page_title
case
action_name
when
'index'
"Pro
ject
s -
#{
@course_edition
.
display_name
}
-
#{
super
}
"
"Pro
posal
s -
#{
@course_edition
.
display_name
}
-
#{
super
}
"
when
'show'
"
#{
@project
.
name
}
- Pro
ject
s -
#{
super
}
"
"
#{
@project
.
name
}
- Pro
posal
s -
#{
super
}
"
else
"Pro
ject
s -
#{
super
}
"
"Pro
posal
s -
#{
super
}
"
end
end
...
...
app/controllers/courses_controller.rb
View file @
2558d21e
...
...
@@ -12,7 +12,7 @@ class CoursesController < ApplicationController
def
show
add_breadcrumb
@course
.
name
@course_editions
=
@course
.
editions
.
accessible_by
(
current_ability
,
:read
)
@course_editions
=
@course
.
editions
.
accessible_by
(
current_ability
,
:read
)
.
non_recurrent
end
protected
...
...
app/controllers/generic_projects_controller.rb
View file @
2558d21e
...
...
@@ -8,11 +8,13 @@ class GenericProjectsController < ProjectsController
authorize_resource
:project
,
parent:
false
before_action
do
add_breadcrumb
'My Pro
ject
s'
,
generic_projects_path
add_breadcrumb
'My Pro
posal
s'
,
generic_projects_path
end
before_action
only:
%i[show edit]
do
add_breadcrumb
@project
.
name
,
project_path
(
@project
)
@project_name
=
@project
.
course_edition
.
configuration
.
project_name_text
(
false
,
false
)
end
before_action
:load_course_selection
,
only:
%i[new create edit update]
...
...
@@ -66,6 +68,7 @@ class GenericProjectsController < ProjectsController
# Allow selecting previously selected course edition in edits
@possible_course_editions
=
CourseEdition
.
where
(
id:
@possible_course_editions
)
.
or
(
CourseEdition
.
where
(
id:
@project
.
course_edition_id
))
.
standalone
.
relevance_ordered
@possible_courses
=
Course
.
where
(
id:
@possible_course_editions
.
map
(
&
:course_id
)).
sort_by_name
end
...
...
@@ -150,23 +153,29 @@ class GenericProjectsController < ProjectsController
end
def
update
@project
=
@specific_project
.
acting_as
edition
=
@project
.
course_edition
role_hash
=
create_role_hash
(
edition
)
main_specific_project
=
@specific_project
@role_creation_failed
=
false
update_failed
=
false
# If recurrent course edition, also apply update to each selected project
if
@specific_project
.
course_edition
.
recurrent
Project
.
where
(
id:
params
[
:generic_project
][
:projects_modify
]).
each
do
|
project
|
unless
apply_update
(
project
.
specific
)
update_failed
=
true
break
end
end
end
begin
fill_role_assignments
(
role_hash
,
params
[
:generic_project
])
rescue
ArgumentError
=>
e
flash
[
:danger
]
=
e
.
message
if
update_failed
render
'edit'
return
end
if
update_project
(
project_update_params
)
# assign course-specific roles
role_creation_failed
=
assign_course_specific_roles
(
role_hash
)
if
role_creation_failed
@specific_project
=
main_specific_project
@project
=
@specific_project
.
acting_as
if
apply_update
(
main_specific_project
)
if
@role_creation_failed
flash
[
:danger
]
=
I18n
.
t
'activerecord.flashes.project.updated.role_failed'
end
...
...
@@ -184,12 +193,33 @@ class GenericProjectsController < ProjectsController
protected
def
apply_update
(
specific_project
)
@specific_project
=
specific_project
@project
=
@specific_project
.
acting_as
authorize!
:update
,
@project
role_hash
=
create_role_hash
(
@project
.
course_edition
)
begin
fill_role_assignments
(
role_hash
,
params
[
:generic_project
])
rescue
ArgumentError
=>
e
flash
[
:danger
]
=
e
.
message
return
false
end
if
update_project
(
project_update_params
)
@role_creation_failed
|=
assign_course_specific_roles
(
role_hash
)
true
else
false
end
end
def
page_title
case
action_name
when
'show'
,
'edit'
"
#{
@project
.
name
}
- Pro
ject
s -
#{
super
}
"
"
#{
@project
.
name
}
- Pro
posal
s -
#{
super
}
"
else
"Pro
ject
s -
#{
super
}
"
"Pro
posal
s -
#{
super
}
"
end
end
...
...
app/controllers/groups_controller.rb
View file @
2558d21e
class
GroupsController
<
ApplicationController
skip_authorization_check
add_breadcrumb
'My Groups'
before_action
do
add_breadcrumb
"My
#{
current_user
.
groups_name
.
capitalize
}
"
end
def
index
@groups
=
current_user
.
groups
.
order
(
created_at: :desc
).
limit
(
100
)
...
...
@@ -14,6 +16,6 @@ class GroupsController < ApplicationController
protected
def
page_title
"
Groups
-
#{
super
}
"
"
#{
current_user
.
groups_name
.
capitalize
}
-
#{
super
}
"
end
end
app/controllers/projects_controller.rb
View file @
2558d21e
...
...
@@ -212,7 +212,9 @@ class ProjectsController < ApplicationController
end
# Sort them by relevance
@possible_course_editions
=
@possible_course_editions
.
relevance_ordered
@possible_course_editions
=
@possible_course_editions
.
standalone
.
relevance_ordered
# Also load courses
@possible_courses
=
Course
.
where
(
id:
@possible_course_editions
.
map
(
&
:course_id
)).
sort_by_name
...
...
@@ -336,6 +338,7 @@ class ProjectsController < ApplicationController
next
if
csr
.
assignment_rule
==
'not_specifiable_by_client'
role_hash
[
csr
.
id
.
to_s
].
each
do
|
user_csr
|
user_csr
.
resource_id
=
@project
.
id
user_csr
.
course_specific_role
=
csr
unless
user_csr
.
save
...
...
app/controllers/user_programmes_controller.rb
View file @
2558d21e
...
...
@@ -31,13 +31,13 @@ class UserProgrammesController < ApplicationController
url
=
params
[
:cont_url
]
if
url
.
blank?
# If there is no continuation url, redirect to
user_path
redirect_to
user
_path
(
current_user
)
# If there is no continuation url, redirect to
dashboard
redirect_to
root
_path
elsif
url
.
start_with?
(
'/'
)
begin
refer_url
=
URI
.
parse
(
url
).
path
rescue
URI
::
InvalidURIError
refer_url
=
user
_path
(
current_user
)
refer_url
=
root
_path
end
# If the url starts with / then we trust it and we can redirect to it
...
...
app/controllers/users/registration_previews_controller.rb
deleted
100644 → 0
View file @
ad6620da
module
Users
class
RegistrationPreviewsController
<
ActionController
::
Base
protect_from_forgery
with: :exception
def
create
@email
=
params
[
:email
]
@user
=
User
.
new
(
email:
@email
)
respond_to
do
|
format
|
format
.
js
end
end
protected
def
devise_controller
true
end
end
end
app/models/ability.rb
View file @
2558d21e
...
...
@@ -365,7 +365,6 @@ class Ability
# Project
# Students can modify groups of approved projects if their enrolment is approved
can
:index
,
Project
can
:modify
,
Project
,
id:
user
.
student_approved_projects
.
ids
# Group
...
...
@@ -381,6 +380,9 @@ class Ability
can
:create
,
RoleInvitation
can
:invite_to
,
Group
,
id:
user
.
leader_groups
.
ids
can
:manage
,
RoleInvitation
.
manageable_by
(
user
)
can
:copy
,
ProjectPreference
can
:copy_interests
,
Project
end
# The rights to view the content of a set of course editions.
...
...
Prev
1
2
3
4
5
6
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment