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
0
Merge Requests
0
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
Jérome Perrin
gitlab-ce
Commits
cd784a80
Commit
cd784a80
authored
Oct 30, 2017
by
Oswaldo Ferreira
Committed by
Phil Hughes
Oct 30, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[CE backport] Saved configuration for issue board
parent
192049a6
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
174 additions
and
93 deletions
+174
-93
app/assets/javascripts/boards/filtered_search_boards.js
app/assets/javascripts/boards/filtered_search_boards.js
+6
-3
app/assets/javascripts/boards/stores/boards_store.js
app/assets/javascripts/boards/stores/boards_store.js
+5
-3
app/assets/javascripts/filtered_search/dropdown_utils.js
app/assets/javascripts/filtered_search/dropdown_utils.js
+10
-0
app/assets/javascripts/filtered_search/filtered_search_manager.js
...ts/javascripts/filtered_search/filtered_search_manager.js
+5
-5
app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js
...ascripts/filtered_search/filtered_search_visual_tokens.js
+4
-11
app/assets/javascripts/labels_select.js
app/assets/javascripts/labels_select.js
+9
-4
app/assets/javascripts/milestone_select.js
app/assets/javascripts/milestone_select.js
+12
-5
app/assets/javascripts/users_select.js
app/assets/javascripts/users_select.js
+6
-1
app/assets/javascripts/vue_shared/components/loading_icon.vue
...assets/javascripts/vue_shared/components/loading_icon.vue
+7
-1
app/assets/javascripts/vue_shared/components/popup_dialog.vue
...assets/javascripts/vue_shared/components/popup_dialog.vue
+65
-36
app/assets/stylesheets/framework/common.scss
app/assets/stylesheets/framework/common.scss
+3
-0
app/assets/stylesheets/framework/dropdowns.scss
app/assets/stylesheets/framework/dropdowns.scss
+1
-0
app/assets/stylesheets/framework/modal.scss
app/assets/stylesheets/framework/modal.scss
+8
-0
app/assets/stylesheets/framework/tw_bootstrap_variables.scss
app/assets/stylesheets/framework/tw_bootstrap_variables.scss
+33
-0
app/assets/stylesheets/pages/repo.scss
app/assets/stylesheets/pages/repo.scss
+0
-13
app/helpers/boards_helper.rb
app/helpers/boards_helper.rb
+0
-11
No files found.
app/assets/javascripts/boards/filtered_search_boards.js
View file @
cd784a80
...
...
@@ -11,7 +11,8 @@ export default class FilteredSearchBoards extends gl.FilteredSearchManager {
// Issue boards is slightly different, we handle all the requests async
// instead or reloading the page, we just re-fire the list ajax requests
this
.
isHandledAsync
=
true
;
this
.
cantEdit
=
cantEdit
;
this
.
cantEdit
=
cantEdit
.
filter
(
i
=>
typeof
i
===
'
string
'
);
this
.
cantEditWithValue
=
cantEdit
.
filter
(
i
=>
typeof
i
===
'
object
'
);
}
updateObject
(
path
)
{
...
...
@@ -42,7 +43,9 @@ export default class FilteredSearchBoards extends gl.FilteredSearchManager {
this
.
filteredSearchInput
.
dispatchEvent
(
new
Event
(
'
input
'
));
}
canEdit
(
tokenName
)
{
return
this
.
cantEdit
.
indexOf
(
tokenName
)
===
-
1
;
canEdit
(
tokenName
,
tokenValue
)
{
if
(
this
.
cantEdit
.
includes
(
tokenName
))
return
false
;
return
this
.
cantEditWithValue
.
findIndex
(
token
=>
token
.
name
===
tokenName
&&
token
.
value
===
tokenValue
)
===
-
1
;
}
}
app/assets/javascripts/boards/stores/boards_store.js
View file @
cd784a80
...
...
@@ -14,16 +14,18 @@ gl.issueBoards.BoardsStore = {
},
state
:
{},
detail
:
{
issue
:
{}
issue
:
{}
,
},
moving
:
{
issue
:
{},
list
:
{}
list
:
{}
,
},
create
()
{
this
.
state
.
lists
=
[];
this
.
filter
.
path
=
getUrlParamsArray
().
join
(
'
&
'
);
this
.
detail
=
{
issue
:
{}
};
this
.
detail
=
{
issue
:
{},
};
},
addList
(
listObj
,
defaultAvatar
)
{
const
list
=
new
List
(
listObj
,
defaultAvatar
);
...
...
app/assets/javascripts/filtered_search/dropdown_utils.js
View file @
cd784a80
...
...
@@ -147,6 +147,16 @@ class DropdownUtils {
return
dataValue
!==
null
;
}
static
getVisualTokenValues
(
visualToken
)
{
const
tokenName
=
visualToken
&&
visualToken
.
querySelector
(
'
.name
'
).
textContent
.
trim
();
let
tokenValue
=
visualToken
&&
visualToken
.
querySelector
(
'
.value
'
)
&&
visualToken
.
querySelector
(
'
.value
'
).
textContent
.
trim
();
if
(
tokenName
===
'
label
'
&&
tokenValue
)
{
// remove leading symbol and wrapping quotes
tokenValue
=
tokenValue
.
replace
(
/^~
(
"|'
)?(
.*
)
/
,
'
$2
'
).
replace
(
/
(
"|'
)
$/
,
''
);
}
return
{
tokenName
,
tokenValue
};
}
// Determines the full search query (visual tokens + input)
static
getSearchQuery
(
untilInput
=
false
)
{
const
container
=
FilteredSearchContainer
.
container
;
...
...
app/assets/javascripts/filtered_search/filtered_search_manager.js
View file @
cd784a80
...
...
@@ -185,8 +185,8 @@ class FilteredSearchManager {
if
(
e
.
keyCode
===
8
||
e
.
keyCode
===
46
)
{
const
{
lastVisualToken
}
=
gl
.
FilteredSearchVisualTokens
.
getLastVisualTokenBeforeInput
();
const
sanitizedTokenName
=
lastVisualToken
&&
lastVisualToken
.
querySelector
(
'
.name
'
).
textContent
.
trim
(
);
const
canEdit
=
sanitizedTokenName
&&
this
.
canEdit
&&
this
.
canEdit
(
sanitizedTokenNam
e
);
const
{
tokenName
,
tokenValue
}
=
gl
.
DropdownUtils
.
getVisualTokenValues
(
lastVisualToken
);
const
canEdit
=
tokenName
&&
this
.
canEdit
&&
this
.
canEdit
(
tokenName
,
tokenValu
e
);
if
(
this
.
filteredSearchInput
.
value
===
''
&&
lastVisualToken
&&
canEdit
)
{
this
.
filteredSearchInput
.
value
=
gl
.
FilteredSearchVisualTokens
.
getLastTokenPartial
();
gl
.
FilteredSearchVisualTokens
.
removeLastTokenPartial
();
...
...
@@ -336,8 +336,8 @@ class FilteredSearchManager {
let
canClearToken
=
t
.
classList
.
contains
(
'
js-visual-token
'
);
if
(
canClearToken
)
{
const
tokenKey
=
t
.
querySelector
(
'
.name
'
).
textContent
.
trim
(
);
canClearToken
=
this
.
canEdit
&&
this
.
canEdit
(
token
Key
);
const
{
tokenName
,
tokenValue
}
=
gl
.
DropdownUtils
.
getVisualTokenValues
(
t
);
canClearToken
=
this
.
canEdit
&&
this
.
canEdit
(
token
Name
,
tokenValue
);
}
if
(
canClearToken
)
{
...
...
@@ -469,7 +469,7 @@ class FilteredSearchManager {
}
hasFilteredSearch
=
true
;
const
canEdit
=
this
.
canEdit
&&
this
.
canEdit
(
sanitizedKey
);
const
canEdit
=
this
.
canEdit
&&
this
.
canEdit
(
sanitizedKey
,
sanitizedValue
);
gl
.
FilteredSearchVisualTokens
.
addFilterVisualToken
(
sanitizedKey
,
`
${
symbol
}${
quotationsToUse
}${
sanitizedValue
}${
quotationsToUse
}
`
,
...
...
app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js
View file @
cd784a80
...
...
@@ -38,21 +38,14 @@ class FilteredSearchVisualTokens {
}
static
createVisualTokenElementHTML
(
canEdit
=
true
)
{
let
removeTokenMarkup
=
''
;
if
(
canEdit
)
{
removeTokenMarkup
=
`
<div class="remove-token" role="button">
<i class="fa fa-close"></i>
</div>
`
;
}
return
`
<div class="
selectable
" role="button">
<div class="
${
canEdit
?
'
selectable
'
:
'
hidden
'
}
" role="button">
<div class="name"></div>
<div class="value-container">
<div class="value"></div>
${
removeTokenMarkup
}
<div class="remove-token" role="button">
<i class="fa fa-close"></i>
</div>
</div>
</div>
`
;
...
...
app/assets/javascripts/labels_select.js
View file @
cd784a80
...
...
@@ -8,7 +8,7 @@ import CreateLabelDropdown from './create_label';
(
function
()
{
this
.
LabelsSelect
=
(
function
()
{
function
LabelsSelect
(
els
)
{
function
LabelsSelect
(
els
,
options
=
{}
)
{
var
_this
,
$els
;
_this
=
this
;
...
...
@@ -58,6 +58,7 @@ import CreateLabelDropdown from './create_label';
labelHTMLTemplate
=
_
.
template
(
'
<% _.each(labels, function(label){ %> <a href="<%- ["",issueURLSplit[1], issueURLSplit[2],""].join("/") %>issues?label_name[]=<%- encodeURIComponent(label.title) %>"> <span class="label has-tooltip color-label" title="<%- label.description %>" style="background-color: <%- label.color %>; color: <%- label.text_color %>;"> <%- label.title %> </span> </a> <% }); %>
'
);
labelNoneHTMLTemplate
=
'
<span class="no-value">None</span>
'
;
}
const
handleClick
=
options
.
handleClick
;
$sidebarLabelTooltip
.
tooltip
();
...
...
@@ -316,9 +317,9 @@ import CreateLabelDropdown from './create_label';
},
multiSelect
:
$dropdown
.
hasClass
(
'
js-multiselect
'
),
vue
:
$dropdown
.
hasClass
(
'
js-issue-board-sidebar
'
),
clicked
:
function
(
options
)
{
const
{
$el
,
e
,
isMarking
}
=
options
;
const
label
=
options
.
selectedObj
;
clicked
:
function
(
clickEvent
)
{
const
{
$el
,
e
,
isMarking
}
=
clickEvent
;
const
label
=
clickEvent
.
selectedObj
;
var
isIssueIndex
,
isMRIndex
,
page
,
boardsModel
;
var
fadeOutLoader
=
()
=>
{
...
...
@@ -391,6 +392,10 @@ import CreateLabelDropdown from './create_label';
.
then
(
fadeOutLoader
)
.
catch
(
fadeOutLoader
);
}
else
if
(
handleClick
)
{
e
.
preventDefault
();
handleClick
(
label
);
}
else
{
if
(
$dropdown
.
hasClass
(
'
js-multiselect
'
))
{
...
...
app/assets/javascripts/milestone_select.js
View file @
cd784a80
...
...
@@ -5,7 +5,7 @@ import _ from 'underscore';
(
function
()
{
this
.
MilestoneSelect
=
(
function
()
{
function
MilestoneSelect
(
currentProject
,
els
)
{
function
MilestoneSelect
(
currentProject
,
els
,
options
=
{}
)
{
var
_this
,
$els
;
if
(
currentProject
!=
null
)
{
_this
=
this
;
...
...
@@ -136,19 +136,26 @@ import _ from 'underscore';
},
opened
:
function
(
e
)
{
const
$el
=
$
(
e
.
currentTarget
);
if
(
$dropdown
.
hasClass
(
'
js-issue-board-sidebar
'
))
{
if
(
$dropdown
.
hasClass
(
'
js-issue-board-sidebar
'
)
||
options
.
handleClick
)
{
selectedMilestone
=
$dropdown
[
0
].
dataset
.
selected
||
selectedMilestoneDefault
;
}
$
(
'
a.is-active
'
,
$el
).
removeClass
(
'
is-active
'
);
$
(
`[data-milestone-id="
${
selectedMilestone
}
"] > a`
,
$el
).
addClass
(
'
is-active
'
);
},
vue
:
$dropdown
.
hasClass
(
'
js-issue-board-sidebar
'
),
clicked
:
function
(
options
)
{
const
{
$el
,
e
}
=
options
;
let
selected
=
options
.
selectedObj
;
clicked
:
function
(
clickEvent
)
{
const
{
$el
,
e
}
=
clickEvent
;
let
selected
=
clickEvent
.
selectedObj
;
var
data
,
isIssueIndex
,
isMRIndex
,
isSelecting
,
page
,
boardsStore
;
if
(
!
selected
)
return
;
if
(
options
.
handleClick
)
{
e
.
preventDefault
();
options
.
handleClick
(
selected
);
return
;
}
page
=
$
(
'
body
'
).
attr
(
'
data-page
'
);
isIssueIndex
=
page
===
'
projects:issues:index
'
;
isMRIndex
=
(
page
===
page
&&
page
===
'
projects:merge_requests:index
'
);
...
...
app/assets/javascripts/users_select.js
View file @
cd784a80
...
...
@@ -6,7 +6,7 @@ import _ from 'underscore';
// TODO: remove eventHub hack after code splitting refactor
window
.
emitSidebarEvent
=
window
.
emitSidebarEvent
||
$
.
noop
;
function
UsersSelect
(
currentUser
,
els
)
{
function
UsersSelect
(
currentUser
,
els
,
options
=
{}
)
{
var
$els
;
this
.
users
=
this
.
users
.
bind
(
this
);
this
.
user
=
this
.
user
.
bind
(
this
);
...
...
@@ -20,6 +20,8 @@ function UsersSelect(currentUser, els) {
}
}
const
{
handleClick
}
=
options
;
$els
=
$
(
els
);
if
(
!
els
)
{
...
...
@@ -442,6 +444,9 @@ function UsersSelect(currentUser, els) {
}
if
(
$el
.
closest
(
'
.add-issues-modal
'
).
length
)
{
gl
.
issueBoards
.
ModalStore
.
store
.
filter
[
$dropdown
.
data
(
'
field-name
'
)]
=
user
.
id
;
}
else
if
(
handleClick
)
{
e
.
preventDefault
();
handleClick
(
user
,
isMarking
);
}
else
if
(
$dropdown
.
hasClass
(
'
js-filter-submit
'
)
&&
(
isIssueIndex
||
isMRIndex
))
{
return
Issuable
.
filterResults
(
$dropdown
.
closest
(
'
form
'
));
}
else
if
(
$dropdown
.
hasClass
(
'
js-filter-submit
'
))
{
...
...
app/assets/javascripts/vue_shared/components/loading_icon.vue
View file @
cd784a80
...
...
@@ -18,6 +18,12 @@
required
:
false
,
default
:
false
,
},
class
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
},
computed
:
{
...
...
@@ -25,7 +31,7 @@
return
this
.
inline
?
'
span
'
:
'
div
'
;
},
cssClass
()
{
return
`fa-
${
this
.
size
}
x
`
;
return
`fa-
${
this
.
size
}
x
${
this
.
class
}
`
.
trim
()
;
},
},
};
...
...
app/assets/javascripts/vue_shared/components/popup_dialog.vue
View file @
cd784a80
...
...
@@ -5,17 +5,27 @@ export default {
props
:
{
title
:
{
type
:
String
,
required
:
tru
e
,
required
:
fals
e
,
},
text
:
{
type
:
String
,
required
:
false
,
},
hideFooter
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
kind
:
{
type
:
String
,
required
:
false
,
default
:
'
primary
'
,
},
modalDialogClass
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
closeKind
:
{
type
:
String
,
required
:
false
,
...
...
@@ -30,6 +40,11 @@ export default {
type
:
String
,
required
:
true
,
},
submitDisabled
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
computed
:
{
...
...
@@ -57,43 +72,57 @@ export default {
</
script
>
<
template
>
<div
class=
"modal popup-dialog"
role=
"dialog"
tabindex=
"-1"
>
<div
class=
"modal-dialog"
role=
"document"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<button
type=
"button"
class=
"close"
@
click=
"close"
aria-label=
"Close"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
<h4
class=
"modal-title"
>
{{
this
.
title
}}
</h4>
</div>
<div
class=
"modal-body"
>
<slot
name=
"body"
:text=
"text"
>
<p>
{{
text
}}
</p>
</slot>
</div>
<div
class=
"modal-footer"
>
<button
type=
"button"
class=
"btn"
:class=
"btnCancelKindClass"
@
click=
"close"
>
{{
closeButtonLabel
}}
</button>
<button
type=
"button"
class=
"btn"
:class=
"btnKindClass"
@
click=
"emitSubmit(true)"
>
{{
primaryButtonLabel
}}
</button>
<div
class=
"modal-open"
>
<div
class=
"modal popup-dialog"
role=
"dialog"
tabindex=
"-1"
>
<div
:class=
"modalDialogClass"
class=
"modal-dialog"
role=
"document"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<slot
name=
"header"
>
<h4
class=
"modal-title pull-left"
>
{{
this
.
title
}}
</h4>
<button
type=
"button"
class=
"close pull-right"
@
click=
"close"
aria-label=
"Close"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</slot>
</div>
<div
class=
"modal-body"
>
<slot
name=
"body"
:text=
"text"
>
<p>
{{
this
.
text
}}
</p>
</slot>
</div>
<div
class=
"modal-footer"
v-if=
"!hideFooter"
>
<button
type=
"button"
class=
"btn pull-left"
:class=
"btnCancelKindClass"
@
click=
"close"
>
{{
closeButtonLabel
}}
</button>
<button
type=
"button"
class=
"btn pull-right"
:class=
"btnKindClass"
@
click=
"emitSubmit(true)"
>
{{
primaryButtonLabel
}}
</button>
</div>
</div>
</div>
</div>
<div
class=
"modal-backdrop fade in"
/>
</div>
</
template
>
app/assets/stylesheets/framework/common.scss
View file @
cd784a80
...
...
@@ -4,6 +4,9 @@
.cred
{
color
:
$common-red
;
}
.cgreen
{
color
:
$common-green
;
}
.cdark
{
color
:
$common-gray-dark
;
}
.text-secondary
{
color
:
$gl-text-color-secondary
;
}
/** COMMON CLASSES **/
.prepend-top-0
{
margin-top
:
0
;
}
...
...
app/assets/stylesheets/framework/dropdowns.scss
View file @
cd784a80
...
...
@@ -37,6 +37,7 @@
.dropdown-menu-nav
{
@include
set-visible
;
display
:
block
;
min-height
:
40px
;
@media
(
max-width
:
$screen-xs-max
)
{
width
:
100%
;
...
...
app/assets/stylesheets/framework/modal.scss
View file @
cd784a80
...
...
@@ -42,3 +42,11 @@ body.modal-open {
width
:
98%
;
}
}
.modal.popup-dialog
{
display
:
block
;
}
.modal-body
{
background-color
:
$modal-body-bg
;
}
app/assets/stylesheets/framework/tw_bootstrap_variables.scss
View file @
cd784a80
...
...
@@ -164,3 +164,36 @@ $pre-border-color: $border-color;
$table-bg-accent
:
$gray-light
;
$zindex-popover
:
900
;
//== Modals
//
//##
//** Padding applied to the modal body
$modal-inner-padding
:
$gl-padding
;
//** Padding applied to the modal title
$modal-title-padding
:
$gl-padding
;
//** Modal title line-height
// $modal-title-line-height: $line-height-base
//** Background color of modal content area
$modal-content-bg
:
$gray-light
;
$modal-body-bg
:
$white-light
;
//** Modal content border color
// $modal-content-border-color: rgba(0,0,0,.2)
//** Modal content border color **for IE8**
// $modal-content-fallback-border-color: #999
//** Modal backdrop background color
// $modal-backdrop-bg: #000
//** Modal backdrop opacity
// $modal-backdrop-opacity: .5
//** Modal header border color
// $modal-header-border-color: #e5e5e5
//** Modal footer border color
// $modal-footer-border-color: $modal-header-border-color
// $modal-lg: 900px
// $modal-md: 600px
// $modal-sm: 300px
app/assets/stylesheets/pages/repo.scss
View file @
cd784a80
...
...
@@ -7,19 +7,6 @@
background
:
$black-transparent
;
}
.modal.popup-dialog
{
display
:
block
;
background-color
:
$black-transparent
;
z-index
:
2100
;
@media
(
min-width
:
$screen-md-min
)
{
.modal-dialog
{
width
:
600px
;
margin
:
30px
auto
;
}
}
}
.project-refs-form
,
.project-refs-target-form
{
display
:
inline-block
;
...
...
app/helpers/boards_helper.rb
View file @
cd784a80
...
...
@@ -20,17 +20,6 @@ module BoardsHelper
project_issues_path
(
@project
)
end
def
current_board_json
board
=
@board
||
@boards
.
first
board
.
to_json
(
only:
[
:id
,
:name
,
:milestone_id
],
include:
{
milestone:
{
only:
[
:title
]
}
}
)
end
def
board_base_url
project_boards_path
(
@project
)
end
...
...
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