BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gitlab-ce
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
gitlab-ce
Commits
d853d821
Commit
d853d821
authored
May 22, 2017
by
Filipa Lacerda
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'issue-edit-inline-description-template' into 'issue-edit-inline'
Issue edit inline description template See merge request !11382
parents
3f996024
21205d1e
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
259 additions
and
4 deletions
+259
-4
app.vue
app/assets/javascripts/issue_show/components/app.vue
+18
-1
description_template.vue
...pts/issue_show/components/fields/description_template.vue
+111
-0
form.vue
app/assets/javascripts/issue_show/components/form.vue
+41
-3
index.js
app/assets/javascripts/issue_show/index.js
+8
-0
issuables_helper.rb
app/helpers/issuables_helper.rb
+8
-0
show.html.haml
app/views/projects/issues/show.html.haml
+1
-0
description_template_spec.js
...issue_show/components/fields/description_template_spec.js
+49
-0
form_spec.js
spec/javascripts/issue_show/components/form_spec.js
+23
-0
No files found.
app/assets/javascripts/issue_show/components/app.vue
View file @
d853d821
...
...
@@ -46,6 +46,11 @@ export default {
required
:
false
,
default
:
''
,
},
issuableTemplates
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
[],
},
isConfidential
:
{
type
:
Boolean
,
required
:
true
,
...
...
@@ -58,6 +63,14 @@ export default {
type
:
String
,
required
:
true
,
},
projectPath
:
{
type
:
String
,
required
:
true
,
},
projectNamespace
:
{
type
:
String
,
required
:
true
,
},
projectsAutocompleteUrl
:
{
type
:
String
,
required
:
true
,
...
...
@@ -186,9 +199,13 @@ export default {
:form-state=
"formState"
:can-move=
"canMove"
:can-destroy=
"canDestroy"
:issuable-templates=
"issuableTemplates"
:markdown-docs=
"markdownDocs"
:markdown-preview-url=
"markdownPreviewUrl"
:projects-autocomplete-url=
"projectsAutocompleteUrl"
/>
:project-path=
"projectPath"
:project-namespace=
"projectNamespace"
:projects-autocomplete-url=
"projectsAutocompleteUrl"
/>
<div
v-else
>
<title-component
:issuable-ref=
"issuableRef"
...
...
app/assets/javascripts/issue_show/components/fields/description_template.vue
0 → 100644
View file @
d853d821
<
script
>
export
default
{
props
:
{
formState
:
{
type
:
Object
,
required
:
true
,
},
issuableTemplates
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
[],
},
projectPath
:
{
type
:
String
,
required
:
true
,
},
projectNamespace
:
{
type
:
String
,
required
:
true
,
},
},
computed
:
{
issuableTemplatesJson
()
{
return
JSON
.
stringify
(
this
.
issuableTemplates
);
},
},
mounted
()
{
// Create the editor for the template
const
editor
=
document
.
querySelector
(
'.detail-page-description .note-textarea'
)
||
{};
editor
.
setValue
=
(
val
)
=>
{
this
.
formState
.
description
=
val
;
};
editor
.
getValue
=
()
=>
this
.
formState
.
description
;
this
.
issuableTemplate
=
new
gl
.
IssuableTemplateSelectors
({
$dropdowns
:
$
(
this
.
$refs
.
toggle
),
editor
,
});
},
};
</
script
>
<
template
>
<div
class=
"dropdown js-issuable-selector-wrap"
data-issuable-type=
"issue"
>
<button
class=
"dropdown-menu-toggle js-issuable-selector"
type=
"button"
ref=
"toggle"
data-field-name=
"issuable_template"
data-selected=
"null"
data-toggle=
"dropdown"
:data-namespace-path=
"projectNamespace"
:data-project-path=
"projectPath"
:data-data=
"issuableTemplatesJson"
>
<span
class=
"dropdown-toggle-text"
>
Choose a template
</span>
<i
aria-hidden=
"true"
class=
"fa fa-chevron-down"
>
</i>
</button>
<div
class=
"dropdown-menu dropdown-select"
>
<div
class=
"dropdown-title"
>
Choose a template
<button
class=
"dropdown-title-button dropdown-menu-close"
aria-label=
"Close"
type=
"button"
>
<i
aria-hidden=
"true"
class=
"fa fa-times dropdown-menu-close-icon"
>
</i>
</button>
</div>
<div
class=
"dropdown-input"
>
<input
type=
"search"
class=
"dropdown-input-field"
placeholder=
"Filter"
autocomplete=
"off"
/>
<i
aria-hidden=
"true"
class=
"fa fa-search dropdown-input-search"
>
</i>
<i
role=
"button"
aria-label=
"Clear templates search input"
class=
"fa fa-times dropdown-input-clear js-dropdown-input-clear"
>
</i>
</div>
<div
class=
"dropdown-content"
></div>
<div
class=
"dropdown-footer"
>
<ul
class=
"dropdown-footer-list"
>
<li>
<a
class=
"no-template"
>
No template
</a>
</li>
<li>
<a
class=
"reset-template"
>
Reset template
</a>
</li>
</ul>
</div>
</div>
</div>
</
template
>
app/assets/javascripts/issue_show/components/form.vue
View file @
d853d821
...
...
@@ -3,6 +3,7 @@
import
titleField
from
'./fields/title.vue'
;
import
descriptionField
from
'./fields/description.vue'
;
import
editActions
from
'./edit_actions.vue'
;
import
descriptionTemplate
from
'./fields/description_template.vue'
;
import
projectMove
from
'./fields/project_move.vue'
;
import
confidentialCheckbox
from
'./fields/confidential_checkbox.vue'
;
...
...
@@ -20,6 +21,11 @@
type
:
Object
,
required
:
true
,
},
issuableTemplates
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
[],
},
markdownPreviewUrl
:
{
type
:
String
,
required
:
true
,
...
...
@@ -28,6 +34,14 @@
type
:
String
,
required
:
true
,
},
projectPath
:
{
type
:
String
,
required
:
true
,
},
projectNamespace
:
{
type
:
String
,
required
:
true
,
},
projectsAutocompleteUrl
:
{
type
:
String
,
required
:
true
,
...
...
@@ -37,24 +51,48 @@
lockedWarning
,
titleField
,
descriptionField
,
descriptionTemplate
,
editActions
,
projectMove
,
confidentialCheckbox
,
},
computed
:
{
hasIssuableTemplates
()
{
return
this
.
issuableTemplates
.
length
;
},
},
};
</
script
>
<
template
>
<form>
<locked-warning
v-if=
"formState.lockedWarningVisible"
/>
<div
class=
"row"
>
<div
class=
"col-sm-4 col-lg-3"
v-if=
"hasIssuableTemplates"
>
<description-template
:form-state=
"formState"
:issuable-templates=
"issuableTemplates"
:project-path=
"projectPath"
:project-namespace=
"projectNamespace"
/>
</div>
<div
:class=
"
{
'col-sm-8 col-lg-9': hasIssuableTemplates,
'col-xs-12': !hasIssuableTemplates,
}">
<title-field
:form-state=
"formState"
/>
<confidential-checkbox
:form-state=
"formState"
/>
:form-state=
"formState"
:issuable-templates=
"issuableTemplates"
/>
</div>
</div>
<description-field
:form-state=
"formState"
:markdown-preview-url=
"markdownPreviewUrl"
:markdown-docs=
"markdownDocs"
/>
<confidential-checkbox
:form-state=
"formState"
/>
<project-move
v-if=
"canMove"
:form-state=
"formState"
...
...
app/assets/javascripts/issue_show/index.js
View file @
d853d821
...
...
@@ -4,6 +4,8 @@ import issuableApp from './components/app.vue';
import
'../vue_shared/vue_resource_interceptor'
;
document
.
addEventListener
(
'DOMContentLoaded'
,
()
=>
{
const
initialDataEl
=
document
.
getElementById
(
'js-issuable-app-initial-data'
);
const
initialData
=
JSON
.
parse
(
initialDataEl
.
innerHTML
.
replace
(
/"/g
,
'"'
));
$
(
'.issuable-edit'
).
on
(
'click'
,
(
e
)
=>
{
e
.
preventDefault
();
...
...
@@ -44,7 +46,10 @@ document.addEventListener('DOMContentLoaded', () => {
isConfidential
:
gl
.
utils
.
convertPermissionToBoolean
(
isConfidential
),
markdownPreviewUrl
,
markdownDocs
,
projectPath
:
initialData
.
project_path
,
projectNamespace
:
initialData
.
namespace_path
,
projectsAutocompleteUrl
,
issuableTemplates
:
initialData
.
templates
,
};
},
render
(
createElement
)
{
...
...
@@ -58,9 +63,12 @@ document.addEventListener('DOMContentLoaded', () => {
initialTitle
:
this
.
initialTitle
,
initialDescriptionHtml
:
this
.
initialDescriptionHtml
,
initialDescriptionText
:
this
.
initialDescriptionText
,
issuableTemplates
:
this
.
issuableTemplates
,
isConfidential
:
this
.
isConfidential
,
markdownPreviewUrl
:
this
.
markdownPreviewUrl
,
markdownDocs
:
this
.
markdownDocs
,
projectPath
:
this
.
projectPath
,
projectNamespace
:
this
.
projectNamespace
,
projectsAutocompleteUrl
:
this
.
projectsAutocompleteUrl
,
},
});
...
...
app/helpers/issuables_helper.rb
View file @
d853d821
...
...
@@ -199,6 +199,14 @@ module IssuablesHelper
issuable_filter_params
.
any?
{
|
k
|
params
.
key?
(
k
)
}
end
def
issuable_initial_data
(
issuable
)
{
templates:
issuable_templates
(
issuable
),
project_path:
ref_project
.
path
,
namespace_path:
ref_project
.
namespace
.
full_path
}.
to_json
end
private
def
sidebar_gutter_collapsed?
...
...
app/views/projects/issues/show.html.haml
View file @
d853d821
...
...
@@ -51,6 +51,7 @@
.issue-details.issuable-details
.detail-page-description.content-block
%script
#js-issuable-app-initial-data
{
type:
"application/json"
}=
issuable_initial_data
(
@issue
)
#js-issuable-app
{
"data"
=>
{
"endpoint"
=>
namespace_project_issue_path
(
@project
.
namespace
,
@project
,
@issue
),
"can-update"
=>
can?
(
current_user
,
:update_issue
,
@issue
).
to_s
,
"can-destroy"
=>
can?
(
current_user
,
:destroy_issue
,
@issue
).
to_s
,
...
...
spec/javascripts/issue_show/components/fields/description_template_spec.js
0 → 100644
View file @
d853d821
import
Vue
from
'vue'
;
import
descriptionTemplate
from
'~/issue_show/components/fields/description_template.vue'
;
import
'~/templates/issuable_template_selector'
;
import
'~/templates/issuable_template_selectors'
;
describe
(
'Issue description template component'
,
()
=>
{
let
vm
;
let
formState
;
beforeEach
((
done
)
=>
{
const
Component
=
Vue
.
extend
(
descriptionTemplate
);
formState
=
{
description
:
'test'
,
};
vm
=
new
Component
({
propsData
:
{
formState
,
issuableTemplates
:
[{
name
:
'test'
}],
projectPath
:
'/'
,
projectNamespace
:
'/'
,
},
}).
$mount
();
Vue
.
nextTick
(
done
);
});
it
(
'renders templates as JSON array in data attribute'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'.js-issuable-selector'
).
getAttribute
(
'data-data'
),
).
toBe
(
'[{"name":"test"}]'
);
});
it
(
'updates formState when changing template'
,
()
=>
{
vm
.
issuableTemplate
.
editor
.
setValue
(
'test new template'
);
expect
(
formState
.
description
,
).
toBe
(
'test new template'
);
});
it
(
'returns formState description with editor getValue'
,
()
=>
{
formState
.
description
=
'testing new template'
;
expect
(
vm
.
issuableTemplate
.
editor
.
getValue
(),
).
toBe
(
'testing new template'
);
});
});
spec/javascripts/issue_show/components/form_spec.js
View file @
d853d821
import
Vue
from
'vue'
;
import
formComponent
from
'~/issue_show/components/form.vue'
;
import
'~/templates/issuable_template_selector'
;
import
'~/templates/issuable_template_selectors'
;
describe
(
'Inline edit form component'
,
()
=>
{
let
vm
;
...
...
@@ -19,12 +21,33 @@ describe('Inline edit form component', () => {
markdownPreviewUrl
:
'/'
,
markdownDocs
:
'/'
,
projectsAutocompleteUrl
:
'/'
,
projectPath
:
'/'
,
projectNamespace
:
'/'
,
},
}).
$mount
();
Vue
.
nextTick
(
done
);
});
it
(
'does not render template selector if no templates exist'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'.js-issuable-selector-wrap'
),
).
toBeNull
();
});
it
(
'renders template selector when templates exists'
,
(
done
)
=>
{
spyOn
(
gl
,
'IssuableTemplateSelectors'
);
vm
.
issuableTemplates
=
[
'test'
];
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'.js-issuable-selector-wrap'
),
).
not
.
toBeNull
();
done
();
});
});
it
(
'hides locked warning by default'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'.alert'
),
...
...
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