Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
bbb24da9
Commit
bbb24da9
authored
Apr 12, 2018
by
Mike Greiling
Committed by
Clement Ho
Apr 12, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Resolve "Clean up old project permissions frontend code"
parent
7ea7b2ab
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
16 additions
and
418 deletions
+16
-418
app/assets/javascripts/pages/projects/edit/index.js
app/assets/javascripts/pages/projects/edit/index.js
+2
-2
app/assets/javascripts/pages/projects/new/index.js
app/assets/javascripts/pages/projects/new/index.js
+2
-2
app/assets/javascripts/pages/projects/shared/project_new.js
app/assets/javascripts/pages/projects/shared/project_new.js
+0
-152
app/assets/javascripts/pages/projects/shared/save_project_loader.js
.../javascripts/pages/projects/shared/save_project_loader.js
+12
-0
app/assets/javascripts/visibility_select.js
app/assets/javascripts/visibility_select.js
+0
-21
app/helpers/projects_helper.rb
app/helpers/projects_helper.rb
+0
-66
app/views/projects/_visibility_select.html.haml
app/views/projects/_visibility_select.html.haml
+0
-9
spec/helpers/projects_helper_spec.rb
spec/helpers/projects_helper_spec.rb
+0
-68
spec/javascripts/visibility_select_spec.js
spec/javascripts/visibility_select_spec.js
+0
-98
No files found.
app/assets/javascripts/pages/projects/edit/index.js
View file @
bbb24da9
import
initSettingsPanels
from
'
~/settings_panels
'
;
import
setupProjectEdit
from
'
~/project_edit
'
;
import
initConfirmDangerModal
from
'
~/confirm_danger_modal
'
;
import
ProjectNew
from
'
../shared/project_new
'
;
import
initProjectLoadingSpinner
from
'
../shared/save_project_loader
'
;
import
projectAvatar
from
'
../shared/project_avatar
'
;
import
initProjectPermissionsSettings
from
'
../shared/permissions
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
new
ProjectNew
();
// eslint-disable-line no-new
initProjectLoadingSpinner
();
setupProjectEdit
();
// Initialize expandable settings panels
initSettingsPanels
();
...
...
app/assets/javascripts/pages/projects/new/index.js
View file @
bbb24da9
import
ProjectNew
from
'
../shared/project_new
'
;
import
initProjectLoadingSpinner
from
'
../shared/save_project_loader
'
;
import
initProjectVisibilitySelector
from
'
../../../project_visibility
'
;
import
initProjectNew
from
'
../../../projects/project_new
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
new
ProjectNew
();
// eslint-disable-line no-new
initProjectLoadingSpinner
();
initProjectVisibilitySelector
();
initProjectNew
.
bindEvents
();
});
app/assets/javascripts/pages/projects/shared/project_new.js
deleted
100644 → 0
View file @
7ea7b2ab
/* eslint-disable func-names, no-var, no-underscore-dangle, prefer-template, prefer-arrow-callback*/
import
$
from
'
jquery
'
;
import
VisibilitySelect
from
'
../../../visibility_select
'
;
function
highlightChanges
(
$elm
)
{
$elm
.
addClass
(
'
highlight-changes
'
);
setTimeout
(()
=>
$elm
.
removeClass
(
'
highlight-changes
'
),
10
);
}
export
default
class
ProjectNew
{
constructor
()
{
this
.
toggleSettings
=
this
.
toggleSettings
.
bind
(
this
);
this
.
$selects
=
$
(
'
.features select
'
);
this
.
$repoSelects
=
this
.
$selects
.
filter
(
'
.js-repo-select
'
);
this
.
$projectSelects
=
this
.
$selects
.
not
(
'
.js-repo-select
'
);
$
(
'
.project-edit-container
'
).
on
(
'
ajax:before
'
,
()
=>
{
$
(
'
.project-edit-container
'
).
hide
();
return
$
(
'
.save-project-loader
'
).
show
();
});
this
.
initVisibilitySelect
();
this
.
toggleSettings
();
this
.
toggleSettingsOnclick
();
this
.
toggleRepoVisibility
();
}
initVisibilitySelect
()
{
const
visibilityContainer
=
document
.
querySelector
(
'
.js-visibility-select
'
);
if
(
!
visibilityContainer
)
return
;
const
visibilitySelect
=
new
VisibilitySelect
(
visibilityContainer
);
visibilitySelect
.
init
();
const
$visibilitySelect
=
$
(
visibilityContainer
).
find
(
'
select
'
);
let
projectVisibility
=
$visibilitySelect
.
val
();
const
PROJECT_VISIBILITY_PRIVATE
=
'
0
'
;
$visibilitySelect
.
on
(
'
change
'
,
()
=>
{
const
newProjectVisibility
=
$visibilitySelect
.
val
();
if
(
projectVisibility
!==
newProjectVisibility
)
{
this
.
$projectSelects
.
each
((
idx
,
select
)
=>
{
const
$select
=
$
(
select
);
const
$options
=
$select
.
find
(
'
option
'
);
const
values
=
$
.
map
(
$options
,
e
=>
e
.
value
);
// if switched to "private", limit visibility options
if
(
newProjectVisibility
===
PROJECT_VISIBILITY_PRIVATE
)
{
if
(
$select
.
val
()
!==
values
[
0
]
&&
$select
.
val
()
!==
values
[
1
])
{
$select
.
val
(
values
[
1
]).
trigger
(
'
change
'
);
highlightChanges
(
$select
);
}
$options
.
slice
(
2
).
disable
();
}
// if switched from "private", increase visibility for non-disabled options
if
(
projectVisibility
===
PROJECT_VISIBILITY_PRIVATE
)
{
$options
.
enable
();
if
(
$select
.
val
()
!==
values
[
0
]
&&
$select
.
val
()
!==
values
[
values
.
length
-
1
])
{
$select
.
val
(
values
[
values
.
length
-
1
]).
trigger
(
'
change
'
);
highlightChanges
(
$select
);
}
}
});
projectVisibility
=
newProjectVisibility
;
}
});
}
toggleSettings
()
{
this
.
$selects
.
each
(
function
()
{
var
$select
=
$
(
this
);
var
className
=
$select
.
data
(
'
field
'
)
.
replace
(
/_/g
,
'
-
'
)
.
replace
(
'
access-level
'
,
'
feature
'
);
ProjectNew
.
_showOrHide
(
$select
,
'
.
'
+
className
);
});
}
toggleSettingsOnclick
()
{
this
.
$selects
.
on
(
'
change
'
,
this
.
toggleSettings
);
}
static
_showOrHide
(
checkElement
,
container
)
{
const
$container
=
$
(
container
);
if
(
$
(
checkElement
).
val
()
!==
'
0
'
)
{
return
$container
.
show
();
}
return
$container
.
hide
();
}
toggleRepoVisibility
()
{
var
$repoAccessLevel
=
$
(
'
.js-repo-access-level select
'
);
var
$lfsEnabledOption
=
$
(
'
.js-lfs-enabled select
'
);
var
containerRegistry
=
document
.
querySelectorAll
(
'
.js-container-registry
'
)[
0
];
var
containerRegistryCheckbox
=
document
.
getElementById
(
'
project_container_registry_enabled
'
);
var
prevSelectedVal
=
parseInt
(
$repoAccessLevel
.
val
(),
10
);
this
.
$repoSelects
.
find
(
"
option[value='
"
+
$repoAccessLevel
.
val
()
+
"
']
"
)
.
nextAll
()
.
hide
();
$repoAccessLevel
.
off
(
'
change
'
)
.
on
(
'
change
'
,
function
()
{
var
selectedVal
=
parseInt
(
$repoAccessLevel
.
val
(),
10
);
this
.
$repoSelects
.
each
(
function
()
{
var
$this
=
$
(
this
);
var
repoSelectVal
=
parseInt
(
$this
.
val
(),
10
);
$this
.
find
(
'
option
'
).
enable
();
if
(
selectedVal
<
repoSelectVal
||
repoSelectVal
===
prevSelectedVal
)
{
$this
.
val
(
selectedVal
).
trigger
(
'
change
'
);
highlightChanges
(
$this
);
}
$this
.
find
(
"
option[value='
"
+
selectedVal
+
"
']
"
).
nextAll
().
disable
();
});
if
(
selectedVal
)
{
this
.
$repoSelects
.
removeClass
(
'
disabled
'
);
if
(
$lfsEnabledOption
.
length
)
{
$lfsEnabledOption
.
removeClass
(
'
disabled
'
);
highlightChanges
(
$lfsEnabledOption
);
}
if
(
containerRegistry
)
{
containerRegistry
.
style
.
display
=
''
;
}
}
else
{
this
.
$repoSelects
.
addClass
(
'
disabled
'
);
if
(
$lfsEnabledOption
.
length
)
{
$lfsEnabledOption
.
val
(
'
false
'
).
addClass
(
'
disabled
'
);
highlightChanges
(
$lfsEnabledOption
);
}
if
(
containerRegistry
)
{
containerRegistry
.
style
.
display
=
'
none
'
;
containerRegistryCheckbox
.
checked
=
false
;
}
}
prevSelectedVal
=
selectedVal
;
}.
bind
(
this
));
}
}
app/assets/javascripts/pages/projects/shared/save_project_loader.js
0 → 100644
View file @
bbb24da9
import
$
from
'
jquery
'
;
export
default
function
initProjectLoadingSpinner
()
{
const
$formContainer
=
$
(
'
.project-edit-container
'
);
const
$loadingSpinner
=
$
(
'
.save-project-loader
'
);
// show loading spinner when saving
$formContainer
.
on
(
'
ajax:before
'
,
()
=>
{
$formContainer
.
hide
();
$loadingSpinner
.
show
();
});
}
app/assets/javascripts/visibility_select.js
deleted
100644 → 0
View file @
7ea7b2ab
export
default
class
VisibilitySelect
{
constructor
(
container
)
{
if
(
!
container
)
throw
new
Error
(
'
VisibilitySelect requires a container element as argument 1
'
);
this
.
container
=
container
;
this
.
helpBlock
=
this
.
container
.
querySelector
(
'
.help-block
'
);
this
.
select
=
this
.
container
.
querySelector
(
'
select
'
);
}
init
()
{
if
(
this
.
select
)
{
this
.
updateHelpText
();
this
.
select
.
addEventListener
(
'
change
'
,
this
.
updateHelpText
.
bind
(
this
));
}
else
{
this
.
helpBlock
.
textContent
=
this
.
container
.
querySelector
(
'
.js-locked
'
).
dataset
.
helpBlock
;
}
}
updateHelpText
()
{
this
.
helpBlock
.
textContent
=
this
.
select
.
querySelector
(
'
option:checked
'
).
dataset
.
description
;
}
}
app/helpers/projects_helper.rb
View file @
bbb24da9
...
...
@@ -157,40 +157,6 @@ module ProjectsHelper
current_user
&
.
recent_push
(
@project
)
end
def
project_feature_access_select
(
field
)
# Don't show option "everyone with access" if project is private
options
=
project_feature_options
level
=
@project
.
project_feature
.
public_send
(
field
)
# rubocop:disable GitlabSecurity/PublicSend
if
@project
.
private?
disabled_option
=
ProjectFeature
::
ENABLED
highest_available_option
=
ProjectFeature
::
PRIVATE
if
level
==
disabled_option
end
options
=
options_for_select
(
options
.
invert
,
selected:
highest_available_option
||
level
,
disabled:
disabled_option
)
content_tag
:div
,
class:
"select-wrapper"
do
concat
(
content_tag
(
:select
,
options
,
name:
"project[project_feature_attributes][
#{
field
}
]"
,
id:
"project_project_feature_attributes_
#{
field
}
"
,
class:
"pull-right form-control select-control
#{
repo_children_classes
(
field
)
}
"
,
data:
{
field:
field
}
)
)
concat
(
icon
(
'chevron-down'
)
)
end
.
html_safe
end
def
link_to_autodeploy_doc
link_to
_
(
'About auto deploy'
),
help_page_path
(
'ci/autodeploy/index'
),
target:
'_blank'
end
...
...
@@ -274,16 +240,6 @@ module ProjectsHelper
private
def
repo_children_classes
(
field
)
needs_repo_check
=
[
:merge_requests_access_level
,
:builds_access_level
]
return
unless
needs_repo_check
.
include?
(
field
)
classes
=
"project-repo-select js-repo-select"
classes
<<
" disabled"
unless
@project
.
feature_available?
(
:repository
,
current_user
)
classes
end
def
get_project_nav_tabs
(
project
,
current_user
)
nav_tabs
=
[
:home
]
...
...
@@ -447,14 +403,6 @@ module ProjectsHelper
filtered_message
.
gsub
(
project
.
repository_storage_path
.
chomp
(
'/'
),
"[REPOS PATH]"
)
end
def
project_feature_options
{
ProjectFeature
::
DISABLED
=>
s_
(
'ProjectFeature|Disabled'
),
ProjectFeature
::
PRIVATE
=>
s_
(
'ProjectFeature|Only team members'
),
ProjectFeature
::
ENABLED
=>
s_
(
'ProjectFeature|Everyone with access'
)
}
end
def
project_child_container_class
(
view_path
)
view_path
==
"projects/issues/issues"
?
"prepend-top-default"
:
"project-show-
#{
view_path
}
"
end
...
...
@@ -463,20 +411,6 @@ module ProjectsHelper
IssuesFinder
.
new
(
current_user
,
project_id:
project
.
id
).
execute
end
def
visibility_select_options
(
project
,
selected_level
)
level_options
=
Gitlab
::
VisibilityLevel
.
values
.
each_with_object
([])
do
|
level
,
level_options
|
next
if
restricted_levels
.
include?
(
level
)
level_options
<<
[
visibility_level_label
(
level
),
{
data:
{
description:
visibility_level_description
(
level
,
project
)
}
},
level
]
end
options_for_select
(
level_options
,
selected_level
)
end
def
restricted_levels
return
[]
if
current_user
.
admin?
...
...
app/views/projects/_visibility_select.html.haml
deleted
100644 → 0
View file @
7ea7b2ab
-
if
can_change_visibility_level?
(
@project
,
current_user
)
.select-wrapper
=
form
.
select
(
model_method
,
visibility_select_options
(
@project
,
selected_level
),
{},
class:
'form-control visibility-select select-control'
)
=
icon
(
'chevron-down'
)
-
else
.info.js-locked
{
data:
{
help_block:
visibility_level_description
(
@project
.
visibility_level
,
@project
)
}
}
=
visibility_level_icon
(
@project
.
visibility_level
)
%strong
=
visibility_level_label
(
@project
.
visibility_level
)
spec/helpers/projects_helper_spec.rb
View file @
bbb24da9
...
...
@@ -322,74 +322,6 @@ describe ProjectsHelper do
end
end
describe
"#project_feature_access_select"
do
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:user
)
{
create
(
:user
)
}
context
"when project is internal or public"
do
it
"shows all options"
do
helper
.
instance_variable_set
(
:@project
,
project
)
result
=
helper
.
project_feature_access_select
(
:issues_access_level
)
expect
(
result
).
to
include
(
"Disabled"
)
expect
(
result
).
to
include
(
"Only team members"
)
expect
(
result
).
to
include
(
"Everyone with access"
)
end
end
context
"when project is private"
do
before
do
project
.
update_attributes
(
visibility_level:
Gitlab
::
VisibilityLevel
::
PRIVATE
)
end
it
"shows only allowed options"
do
helper
.
instance_variable_set
(
:@project
,
project
)
result
=
helper
.
project_feature_access_select
(
:issues_access_level
)
expect
(
result
).
to
include
(
"Disabled"
)
expect
(
result
).
to
include
(
"Only team members"
)
expect
(
result
).
to
have_selector
(
'option[disabled]'
,
text:
"Everyone with access"
)
end
end
context
"when project moves from public to private"
do
before
do
project
.
update_attributes
(
visibility_level:
Gitlab
::
VisibilityLevel
::
PRIVATE
)
end
it
"shows the highest allowed level selected"
do
helper
.
instance_variable_set
(
:@project
,
project
)
result
=
helper
.
project_feature_access_select
(
:issues_access_level
)
expect
(
result
).
to
include
(
"Disabled"
)
expect
(
result
).
to
include
(
"Only team members"
)
expect
(
result
).
to
have_selector
(
'option[disabled]'
,
text:
"Everyone with access"
)
expect
(
result
).
to
have_selector
(
'option[selected]'
,
text:
"Only team members"
)
end
end
end
describe
"#visibility_select_options"
do
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:user
)
{
create
(
:user
)
}
before
do
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
user
)
stub_application_setting
(
restricted_visibility_levels:
[
Gitlab
::
VisibilityLevel
::
PUBLIC
])
end
it
"does not include the Public restricted level"
do
expect
(
helper
.
send
(
:visibility_select_options
,
project
,
Gitlab
::
VisibilityLevel
::
PRIVATE
)).
not_to
include
(
'Public'
)
end
it
"includes the Internal level"
do
expect
(
helper
.
send
(
:visibility_select_options
,
project
,
Gitlab
::
VisibilityLevel
::
PRIVATE
)).
to
include
(
'Internal'
)
end
it
"includes the Private level"
do
expect
(
helper
.
send
(
:visibility_select_options
,
project
,
Gitlab
::
VisibilityLevel
::
PRIVATE
)).
to
include
(
'Private'
)
end
end
describe
'#get_project_nav_tabs'
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:user
)
{
create
(
:user
)
}
...
...
spec/javascripts/visibility_select_spec.js
deleted
100644 → 0
View file @
7ea7b2ab
import
VisibilitySelect
from
'
~/visibility_select
'
;
(()
=>
{
describe
(
'
VisibilitySelect
'
,
function
()
{
const
lockedElement
=
document
.
createElement
(
'
div
'
);
lockedElement
.
dataset
.
helpBlock
=
'
lockedHelpBlock
'
;
const
checkedElement
=
document
.
createElement
(
'
div
'
);
checkedElement
.
dataset
.
description
=
'
checkedDescription
'
;
const
mockElements
=
{
container
:
document
.
createElement
(
'
div
'
),
select
:
document
.
createElement
(
'
div
'
),
'
.help-block
'
:
document
.
createElement
(
'
div
'
),
'
.js-locked
'
:
lockedElement
,
'
option:checked
'
:
checkedElement
,
};
beforeEach
(
function
()
{
spyOn
(
Element
.
prototype
,
'
querySelector
'
).
and
.
callFake
(
selector
=>
mockElements
[
selector
]);
});
describe
(
'
constructor
'
,
function
()
{
beforeEach
(
function
()
{
this
.
visibilitySelect
=
new
VisibilitySelect
(
mockElements
.
container
);
});
it
(
'
sets the container member
'
,
function
()
{
expect
(
this
.
visibilitySelect
.
container
).
toEqual
(
mockElements
.
container
);
});
it
(
'
queries and sets the helpBlock member
'
,
function
()
{
expect
(
Element
.
prototype
.
querySelector
).
toHaveBeenCalledWith
(
'
.help-block
'
);
expect
(
this
.
visibilitySelect
.
helpBlock
).
toEqual
(
mockElements
[
'
.help-block
'
]);
});
it
(
'
queries and sets the select member
'
,
function
()
{
expect
(
Element
.
prototype
.
querySelector
).
toHaveBeenCalledWith
(
'
select
'
);
expect
(
this
.
visibilitySelect
.
select
).
toEqual
(
mockElements
.
select
);
});
describe
(
'
if there is no container element provided
'
,
function
()
{
it
(
'
throws an error
'
,
function
()
{
expect
(()
=>
new
VisibilitySelect
()).
toThrowError
(
'
VisibilitySelect requires a container element as argument 1
'
);
});
});
});
describe
(
'
init
'
,
function
()
{
describe
(
'
if there is a select
'
,
function
()
{
beforeEach
(
function
()
{
this
.
visibilitySelect
=
new
VisibilitySelect
(
mockElements
.
container
);
});
it
(
'
calls updateHelpText
'
,
function
()
{
spyOn
(
VisibilitySelect
.
prototype
,
'
updateHelpText
'
);
this
.
visibilitySelect
.
init
();
expect
(
this
.
visibilitySelect
.
updateHelpText
).
toHaveBeenCalled
();
});
it
(
'
adds a change event listener
'
,
function
()
{
spyOn
(
this
.
visibilitySelect
.
select
,
'
addEventListener
'
);
this
.
visibilitySelect
.
init
();
expect
(
this
.
visibilitySelect
.
select
.
addEventListener
.
calls
.
argsFor
(
0
)).
toContain
(
'
change
'
);
});
});
describe
(
'
if there is no select
'
,
function
()
{
beforeEach
(
function
()
{
mockElements
.
select
=
undefined
;
this
.
visibilitySelect
=
new
VisibilitySelect
(
mockElements
.
container
);
this
.
visibilitySelect
.
init
();
});
it
(
'
updates the helpBlock text to the locked `data-help-block` messaged
'
,
function
()
{
expect
(
this
.
visibilitySelect
.
helpBlock
.
textContent
)
.
toEqual
(
lockedElement
.
dataset
.
helpBlock
);
});
afterEach
(
function
()
{
mockElements
.
select
=
document
.
createElement
(
'
div
'
);
});
});
});
describe
(
'
updateHelpText
'
,
function
()
{
beforeEach
(
function
()
{
this
.
visibilitySelect
=
new
VisibilitySelect
(
mockElements
.
container
);
this
.
visibilitySelect
.
init
();
});
it
(
'
updates the helpBlock text to the selected options `data-description`
'
,
function
()
{
expect
(
this
.
visibilitySelect
.
helpBlock
.
textContent
)
.
toEqual
(
checkedElement
.
dataset
.
description
);
});
});
});
})();
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