Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
李少辉-开发者
gitlab-foss
提交
f564cbb2
G
gitlab-foss
项目概览
李少辉-开发者
/
gitlab-foss
通知
15
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
gitlab-foss
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
f564cbb2
编写于
4月 03, 2017
作者:
B
Bryce Johnson
提交者:
Alfredo Sumaran
4月 03, 2017
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Make file templates easy to use and discover
上级
ca6a7f1e
变更
31
隐藏空白更改
内联
并排
Showing
31 changed file
with
832 addition
and
217 deletion
+832
-217
app/assets/javascripts/blob/file_template_mediator.js
app/assets/javascripts/blob/file_template_mediator.js
+241
-0
app/assets/javascripts/blob/file_template_selector.js
app/assets/javascripts/blob/file_template_selector.js
+60
-0
app/assets/javascripts/blob/template_selector.js
app/assets/javascripts/blob/template_selector.js
+0
-0
app/assets/javascripts/blob/template_selectors/blob_ci_yaml_selector.js
...ascripts/blob/template_selectors/blob_ci_yaml_selector.js
+0
-9
app/assets/javascripts/blob/template_selectors/blob_ci_yaml_selectors.js
...scripts/blob/template_selectors/blob_ci_yaml_selectors.js
+0
-23
app/assets/javascripts/blob/template_selectors/blob_dockerfile_selector.js
...ripts/blob/template_selectors/blob_dockerfile_selector.js
+0
-9
app/assets/javascripts/blob/template_selectors/blob_dockerfile_selectors.js
...ipts/blob/template_selectors/blob_dockerfile_selectors.js
+0
-23
app/assets/javascripts/blob/template_selectors/blob_gitignore_selector.js
...cripts/blob/template_selectors/blob_gitignore_selector.js
+0
-9
app/assets/javascripts/blob/template_selectors/blob_gitignore_selectors.js
...ripts/blob/template_selectors/blob_gitignore_selectors.js
+0
-23
app/assets/javascripts/blob/template_selectors/blob_license_selector.js
...ascripts/blob/template_selectors/blob_license_selector.js
+0
-13
app/assets/javascripts/blob/template_selectors/blob_license_selectors.js
...scripts/blob/template_selectors/blob_license_selectors.js
+0
-24
app/assets/javascripts/blob/template_selectors/ci_yaml_selector.js
...s/javascripts/blob/template_selectors/ci_yaml_selector.js
+32
-0
app/assets/javascripts/blob/template_selectors/dockerfile_selector.js
...avascripts/blob/template_selectors/dockerfile_selector.js
+32
-0
app/assets/javascripts/blob/template_selectors/gitignore_selector.js
...javascripts/blob/template_selectors/gitignore_selector.js
+31
-0
app/assets/javascripts/blob/template_selectors/license_selector.js
...s/javascripts/blob/template_selectors/license_selector.js
+38
-0
app/assets/javascripts/blob/template_selectors/type_selector.js
...sets/javascripts/blob/template_selectors/type_selector.js
+25
-0
app/assets/javascripts/blob_edit/blob_bundle.js
app/assets/javascripts/blob_edit/blob_bundle.js
+2
-1
app/assets/javascripts/blob_edit/edit_blob.js
app/assets/javascripts/blob_edit/edit_blob.js
+11
-27
app/assets/javascripts/templates/issuable_template_selector.js
...ssets/javascripts/templates/issuable_template_selector.js
+1
-1
app/assets/stylesheets/pages/editor.scss
app/assets/stylesheets/pages/editor.scss
+113
-29
app/views/projects/blob/_editor.html.haml
app/views/projects/blob/_editor.html.haml
+7
-13
app/views/projects/blob/_template_selectors.html.haml
app/views/projects/blob/_template_selectors.html.haml
+17
-0
app/views/projects/blob/edit.html.haml
app/views/projects/blob/edit.html.haml
+5
-2
app/views/projects/blob/new.html.haml
app/views/projects/blob/new.html.haml
+4
-4
changelogs/unreleased/25332-make-file-templates-easy-to-use-and-discover.yml
...ed/25332-make-file-templates-easy-to-use-and-discover.yml
+4
-0
spec/features/auto_deploy_spec.rb
spec/features/auto_deploy_spec.rb
+2
-2
spec/features/projects/blobs/user_create_spec.rb
spec/features/projects/blobs/user_create_spec.rb
+1
-1
spec/features/projects/files/project_owner_creates_license_file_spec.rb
...projects/files/project_owner_creates_license_file_spec.rb
+2
-2
spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
...sees_link_to_create_license_file_in_empty_project_spec.rb
+2
-2
spec/features/projects/files/template_type_dropdown_spec.rb
spec/features/projects/files/template_type_dropdown_spec.rb
+135
-0
spec/features/projects/files/undo_template_spec.rb
spec/features/projects/files/undo_template_spec.rb
+67
-0
未找到文件。
app/assets/javascripts/blob/file_template_mediator.js
0 → 100644
浏览文件 @
f564cbb2
/* eslint-disable class-methods-use-this */
/* global Flash */
import
FileTemplateTypeSelector
from
'
./template_selectors/type_selector
'
;
import
BlobCiYamlSelector
from
'
./template_selectors/ci_yaml_selector
'
;
import
DockerfileSelector
from
'
./template_selectors/dockerfile_selector
'
;
import
GitignoreSelector
from
'
./template_selectors/gitignore_selector
'
;
import
LicenseSelector
from
'
./template_selectors/license_selector
'
;
export
default
class
FileTemplateMediator
{
constructor
({
editor
,
currentAction
})
{
this
.
editor
=
editor
;
this
.
currentAction
=
currentAction
;
this
.
initTemplateSelectors
();
this
.
initTemplateTypeSelector
();
this
.
initDomElements
();
this
.
initDropdowns
();
this
.
initPageEvents
();
}
initTemplateSelectors
()
{
// Order dictates template type dropdown item order
this
.
templateSelectors
=
[
GitignoreSelector
,
BlobCiYamlSelector
,
DockerfileSelector
,
LicenseSelector
,
].
map
(
TemplateSelectorClass
=>
new
TemplateSelectorClass
({
mediator
:
this
}));
}
initTemplateTypeSelector
()
{
this
.
typeSelector
=
new
FileTemplateTypeSelector
({
mediator
:
this
,
dropdownData
:
this
.
templateSelectors
.
map
((
templateSelector
)
=>
{
const
cfg
=
templateSelector
.
config
;
return
{
name
:
cfg
.
name
,
key
:
cfg
.
key
,
};
}),
});
}
initDomElements
()
{
const
$templatesMenu
=
$
(
'
.template-selectors-menu
'
);
const
$undoMenu
=
$templatesMenu
.
find
(
'
.template-selectors-undo-menu
'
);
const
$fileEditor
=
$
(
'
.file-editor
'
);
this
.
$templatesMenu
=
$templatesMenu
;
this
.
$undoMenu
=
$undoMenu
;
this
.
$undoBtn
=
$undoMenu
.
find
(
'
button
'
);
this
.
$templateSelectors
=
$templatesMenu
.
find
(
'
.template-selector-dropdowns-wrap
'
);
this
.
$filenameInput
=
$fileEditor
.
find
(
'
.js-file-path-name-input
'
);
this
.
$fileContent
=
$fileEditor
.
find
(
'
#file-content
'
);
this
.
$commitForm
=
$fileEditor
.
find
(
'
form
'
);
this
.
$navLinks
=
$fileEditor
.
find
(
'
.nav-links
'
);
}
initDropdowns
()
{
if
(
this
.
currentAction
===
'
create
'
)
{
this
.
typeSelector
.
show
();
}
else
{
this
.
hideTemplateSelectorMenu
();
}
this
.
displayMatchedTemplateSelector
();
}
initPageEvents
()
{
this
.
listenForFilenameInput
();
this
.
prepFileContentForSubmit
();
this
.
listenForPreviewMode
();
}
listenForFilenameInput
()
{
this
.
$filenameInput
.
on
(
'
keyup blur
'
,
()
=>
{
this
.
displayMatchedTemplateSelector
();
});
}
prepFileContentForSubmit
()
{
this
.
$commitForm
.
submit
(()
=>
{
this
.
$fileContent
.
val
(
this
.
editor
.
getValue
());
});
}
listenForPreviewMode
()
{
this
.
$navLinks
.
on
(
'
click
'
,
'
a
'
,
(
e
)
=>
{
const
urlPieces
=
e
.
target
.
href
.
split
(
'
#
'
);
const
hash
=
urlPieces
[
1
];
if
(
hash
===
'
preview
'
)
{
this
.
hideTemplateSelectorMenu
();
}
else
if
(
hash
===
'
editor
'
)
{
this
.
showTemplateSelectorMenu
();
}
});
}
selectTemplateType
(
item
,
el
,
e
)
{
if
(
e
)
{
e
.
preventDefault
();
}
this
.
templateSelectors
.
forEach
((
selector
)
=>
{
if
(
selector
.
config
.
key
===
item
.
key
)
{
selector
.
show
();
}
else
{
selector
.
hide
();
}
});
this
.
typeSelector
.
setToggleText
(
item
.
name
);
this
.
cacheToggleText
();
}
selectTemplateFile
(
selector
,
query
,
data
)
{
selector
.
renderLoading
();
// in case undo menu is already already there
this
.
destroyUndoMenu
();
this
.
fetchFileTemplate
(
selector
.
config
.
endpoint
,
query
,
data
)
.
then
((
file
)
=>
{
this
.
showUndoMenu
();
this
.
setEditorContent
(
file
);
this
.
setFilename
(
selector
.
config
.
name
);
selector
.
renderLoaded
();
})
.
catch
(
err
=>
new
Flash
(
`An error occurred while fetching the template:
${
err
}
`
));
}
displayMatchedTemplateSelector
()
{
const
currentInput
=
this
.
getFilename
();
this
.
templateSelectors
.
forEach
((
selector
)
=>
{
const
match
=
selector
.
config
.
pattern
.
test
(
currentInput
);
if
(
match
)
{
this
.
typeSelector
.
show
();
this
.
selectTemplateType
(
selector
.
config
);
this
.
showTemplateSelectorMenu
();
}
});
}
fetchFileTemplate
(
apiCall
,
query
,
data
)
{
return
new
Promise
((
resolve
)
=>
{
const
resolveFile
=
file
=>
resolve
(
file
);
if
(
!
data
)
{
apiCall
(
query
,
resolveFile
);
}
else
{
apiCall
(
query
,
data
,
resolveFile
);
}
});
}
setEditorContent
(
file
)
{
if
(
!
file
&&
file
!==
''
)
return
;
const
newValue
=
file
.
content
||
file
;
this
.
editor
.
setValue
(
newValue
,
1
);
this
.
editor
.
focus
();
this
.
editor
.
navigateFileStart
();
}
findTemplateSelectorByKey
(
key
)
{
return
this
.
templateSelectors
.
find
(
selector
=>
selector
.
config
.
key
===
key
);
}
showUndoMenu
()
{
this
.
$undoMenu
.
removeClass
(
'
hidden
'
);
this
.
$undoBtn
.
on
(
'
click
'
,
()
=>
{
this
.
restoreFromCache
();
this
.
destroyUndoMenu
();
});
}
destroyUndoMenu
()
{
this
.
cacheFileContents
();
this
.
cacheToggleText
();
this
.
$undoMenu
.
addClass
(
'
hidden
'
);
this
.
$undoBtn
.
off
(
'
click
'
);
}
hideTemplateSelectorMenu
()
{
this
.
$templatesMenu
.
hide
();
}
showTemplateSelectorMenu
()
{
this
.
$templatesMenu
.
show
();
}
cacheToggleText
()
{
this
.
cachedToggleText
=
this
.
getTemplateSelectorToggleText
();
}
cacheFileContents
()
{
this
.
cachedContent
=
this
.
editor
.
getValue
();
this
.
cachedFilename
=
this
.
getFilename
();
}
restoreFromCache
()
{
this
.
setEditorContent
(
this
.
cachedContent
);
this
.
setFilename
(
this
.
cachedFilename
);
this
.
setTemplateSelectorToggleText
();
}
getTemplateSelectorToggleText
()
{
return
this
.
$templateSelectors
.
find
(
'
.js-template-selector-wrap:visible .dropdown-toggle-text
'
)
.
text
();
}
setTemplateSelectorToggleText
()
{
return
this
.
$templateSelectors
.
find
(
'
.js-template-selector-wrap:visible .dropdown-toggle-text
'
)
.
text
(
this
.
cachedToggleText
);
}
getTypeSelectorToggleText
()
{
return
this
.
typeSelector
.
getToggleText
();
}
getFilename
()
{
return
this
.
$filenameInput
.
val
();
}
setFilename
(
name
)
{
this
.
$filenameInput
.
val
(
name
);
}
getSelected
()
{
return
this
.
templateSelectors
.
find
(
selector
=>
selector
.
selected
);
}
}
app/assets/javascripts/blob/file_template_selector.js
0 → 100644
浏览文件 @
f564cbb2
/* global Api */
export
default
class
FileTemplateSelector
{
constructor
(
mediator
)
{
this
.
mediator
=
mediator
;
this
.
$dropdown
=
null
;
this
.
$wrapper
=
null
;
}
init
()
{
const
cfg
=
this
.
config
;
this
.
$dropdown
=
$
(
cfg
.
dropdown
);
this
.
$wrapper
=
$
(
cfg
.
wrapper
);
this
.
$loadingIcon
=
this
.
$wrapper
.
find
(
'
.fa-chevron-down
'
);
this
.
$dropdownToggleText
=
this
.
$wrapper
.
find
(
'
.dropdown-toggle-text
'
);
this
.
initDropdown
();
}
show
()
{
if
(
this
.
$dropdown
===
null
)
{
this
.
init
();
}
this
.
$wrapper
.
removeClass
(
'
hidden
'
);
}
hide
()
{
if
(
this
.
$dropdown
!==
null
)
{
this
.
$wrapper
.
addClass
(
'
hidden
'
);
}
}
getToggleText
()
{
return
this
.
$dropdownToggleText
.
text
();
}
setToggleText
(
text
)
{
this
.
$dropdownToggleText
.
text
(
text
);
}
renderLoading
()
{
this
.
$loadingIcon
.
addClass
(
'
fa-spinner fa-spin
'
)
.
removeClass
(
'
fa-chevron-down
'
);
}
renderLoaded
()
{
this
.
$loadingIcon
.
addClass
(
'
fa-chevron-down
'
)
.
removeClass
(
'
fa-spinner fa-spin
'
);
}
reportSelection
(
query
,
el
,
e
,
data
)
{
e
.
preventDefault
();
return
this
.
mediator
.
selectTemplateFile
(
this
,
query
,
data
);
}
}
app/assets/javascripts/blob/template_selector
s/template_selector
.js
→
app/assets/javascripts/blob/template_selector.js
浏览文件 @
f564cbb2
文件已移动
app/assets/javascripts/blob/template_selectors/blob_ci_yaml_selector.js
已删除
100644 → 0
浏览文件 @
ca6a7f1e
/* global Api */
import
TemplateSelector
from
'
./template_selector
'
;
export
default
class
BlobCiYamlSelector
extends
TemplateSelector
{
requestFile
(
query
)
{
return
Api
.
gitlabCiYml
(
query
.
name
,
(
file
,
config
)
=>
this
.
setEditorContent
(
file
,
config
));
}
}
app/assets/javascripts/blob/template_selectors/blob_ci_yaml_selectors.js
已删除
100644 → 0
浏览文件 @
ca6a7f1e
/* global Api */
import
BlobCiYamlSelector
from
'
./blob_ci_yaml_selector
'
;
export
default
class
BlobCiYamlSelectors
{
constructor
({
editor
,
$dropdowns
})
{
this
.
$dropdowns
=
$dropdowns
||
$
(
'
.js-gitlab-ci-yml-selector
'
);
this
.
initSelectors
(
editor
);
}
initSelectors
(
editor
)
{
this
.
$dropdowns
.
each
((
i
,
dropdown
)
=>
{
const
$dropdown
=
$
(
dropdown
);
return
new
BlobCiYamlSelector
({
editor
,
pattern
:
/
(
.gitlab-ci.yml
)
/
,
data
:
$dropdown
.
data
(
'
data
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-gitlab-ci-yml-selector-wrap
'
),
dropdown
:
$dropdown
,
});
});
}
}
app/assets/javascripts/blob/template_selectors/blob_dockerfile_selector.js
已删除
100644 → 0
浏览文件 @
ca6a7f1e
/* global Api */
import
TemplateSelector
from
'
./template_selector
'
;
export
default
class
BlobDockerfileSelector
extends
TemplateSelector
{
requestFile
(
query
)
{
return
Api
.
dockerfileYml
(
query
.
name
,
(
file
,
config
)
=>
this
.
setEditorContent
(
file
,
config
));
}
}
app/assets/javascripts/blob/template_selectors/blob_dockerfile_selectors.js
已删除
100644 → 0
浏览文件 @
ca6a7f1e
import
BlobDockerfileSelector
from
'
./blob_dockerfile_selector
'
;
export
default
class
BlobDockerfileSelectors
{
constructor
({
editor
,
$dropdowns
})
{
this
.
editor
=
editor
;
this
.
$dropdowns
=
$dropdowns
||
$
(
'
.js-dockerfile-selector
'
);
this
.
initSelectors
();
}
initSelectors
()
{
const
editor
=
this
.
editor
;
this
.
$dropdowns
.
each
((
i
,
dropdown
)
=>
{
const
$dropdown
=
$
(
dropdown
);
return
new
BlobDockerfileSelector
({
editor
,
pattern
:
/
(
Dockerfile
)
/
,
data
:
$dropdown
.
data
(
'
data
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-dockerfile-selector-wrap
'
),
dropdown
:
$dropdown
,
});
});
}
}
app/assets/javascripts/blob/template_selectors/blob_gitignore_selector.js
已删除
100644 → 0
浏览文件 @
ca6a7f1e
/* global Api */
import
TemplateSelector
from
'
./template_selector
'
;
export
default
class
BlobGitignoreSelector
extends
TemplateSelector
{
requestFile
(
query
)
{
return
Api
.
gitignoreText
(
query
.
name
,
(
file
,
config
)
=>
this
.
setEditorContent
(
file
,
config
));
}
}
app/assets/javascripts/blob/template_selectors/blob_gitignore_selectors.js
已删除
100644 → 0
浏览文件 @
ca6a7f1e
import
BlobGitignoreSelector
from
'
./blob_gitignore_selector
'
;
export
default
class
BlobGitignoreSelectors
{
constructor
({
editor
,
$dropdowns
})
{
this
.
$dropdowns
=
$dropdowns
||
$
(
'
.js-gitignore-selector
'
);
this
.
editor
=
editor
;
this
.
initSelectors
();
}
initSelectors
()
{
this
.
$dropdowns
.
each
((
i
,
dropdown
)
=>
{
const
$dropdown
=
$
(
dropdown
);
return
new
BlobGitignoreSelector
({
pattern
:
/
(
.gitignore
)
/
,
data
:
$dropdown
.
data
(
'
data
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-gitignore-selector-wrap
'
),
dropdown
:
$dropdown
,
editor
:
this
.
editor
,
});
});
}
}
app/assets/javascripts/blob/template_selectors/blob_license_selector.js
已删除
100644 → 0
浏览文件 @
ca6a7f1e
/* global Api */
import
TemplateSelector
from
'
./template_selector
'
;
export
default
class
BlobLicenseSelector
extends
TemplateSelector
{
requestFile
(
query
)
{
const
data
=
{
project
:
this
.
dropdown
.
data
(
'
project
'
),
fullname
:
this
.
dropdown
.
data
(
'
fullname
'
),
};
return
Api
.
licenseText
(
query
.
id
,
data
,
(
file
,
config
)
=>
this
.
setEditorContent
(
file
,
config
));
}
}
app/assets/javascripts/blob/template_selectors/blob_license_selectors.js
已删除
100644 → 0
浏览文件 @
ca6a7f1e
/* eslint-disable no-unused-vars, no-param-reassign */
import
BlobLicenseSelector
from
'
./blob_license_selector
'
;
export
default
class
BlobLicenseSelectors
{
constructor
({
$dropdowns
,
editor
})
{
this
.
$dropdowns
=
$dropdowns
||
$
(
'
.js-license-selector
'
);
this
.
initSelectors
(
editor
);
}
initSelectors
(
editor
)
{
this
.
$dropdowns
.
each
((
i
,
dropdown
)
=>
{
const
$dropdown
=
$
(
dropdown
);
return
new
BlobLicenseSelector
({
editor
,
pattern
:
/^
(
.+
\/)?(
licen
[
sc
]
e|copying
)(
$|
\.)
/i
,
data
:
$dropdown
.
data
(
'
data
'
),
wrapper
:
$dropdown
.
closest
(
'
.js-license-selector-wrap
'
),
dropdown
:
$dropdown
,
});
});
}
}
app/assets/javascripts/blob/template_selectors/ci_yaml_selector.js
0 → 100644
浏览文件 @
f564cbb2
/* global Api */
import
FileTemplateSelector
from
'
../file_template_selector
'
;
export
default
class
BlobCiYamlSelector
extends
FileTemplateSelector
{
constructor
({
mediator
})
{
super
(
mediator
);
this
.
config
=
{
key
:
'
gitlab-ci-yaml
'
,
name
:
'
.gitlab-ci.yml
'
,
pattern
:
/
(
.gitlab-ci.yml
)
/
,
endpoint
:
Api
.
gitlabCiYml
,
dropdown
:
'
.js-gitlab-ci-yml-selector
'
,
wrapper
:
'
.js-gitlab-ci-yml-selector-wrap
'
,
};
}
initDropdown
()
{
// maybe move to super class as well
this
.
$dropdown
.
glDropdown
({
data
:
this
.
$dropdown
.
data
(
'
data
'
),
filterable
:
true
,
selectable
:
true
,
toggleLabel
:
item
=>
item
.
name
,
search
:
{
fields
:
[
'
name
'
],
},
clicked
:
(
query
,
el
,
e
)
=>
this
.
reportSelection
(
query
.
name
,
el
,
e
),
text
:
item
=>
item
.
name
,
});
}
}
app/assets/javascripts/blob/template_selectors/dockerfile_selector.js
0 → 100644
浏览文件 @
f564cbb2
/* global Api */
import
FileTemplateSelector
from
'
../file_template_selector
'
;
export
default
class
DockerfileSelector
extends
FileTemplateSelector
{
constructor
({
mediator
})
{
super
(
mediator
);
this
.
config
=
{
key
:
'
dockerfile
'
,
name
:
'
Dockerfile
'
,
pattern
:
/
(
Dockerfile
)
/
,
endpoint
:
Api
.
dockerfileYml
,
dropdown
:
'
.js-dockerfile-selector
'
,
wrapper
:
'
.js-dockerfile-selector-wrap
'
,
};
}
initDropdown
()
{
// maybe move to super class as well
this
.
$dropdown
.
glDropdown
({
data
:
this
.
$dropdown
.
data
(
'
data
'
),
filterable
:
true
,
selectable
:
true
,
toggleLabel
:
item
=>
item
.
name
,
search
:
{
fields
:
[
'
name
'
],
},
clicked
:
(
query
,
el
,
e
)
=>
this
.
reportSelection
(
query
.
name
,
el
,
e
),
text
:
item
=>
item
.
name
,
});
}
}
app/assets/javascripts/blob/template_selectors/gitignore_selector.js
0 → 100644
浏览文件 @
f564cbb2
/* global Api */
import
FileTemplateSelector
from
'
../file_template_selector
'
;
export
default
class
BlobGitignoreSelector
extends
FileTemplateSelector
{
constructor
({
mediator
})
{
super
(
mediator
);
this
.
config
=
{
key
:
'
gitignore
'
,
name
:
'
.gitignore
'
,
pattern
:
/
(
.gitignore
)
/
,
endpoint
:
Api
.
gitignoreText
,
dropdown
:
'
.js-gitignore-selector
'
,
wrapper
:
'
.js-gitignore-selector-wrap
'
,
};
}
initDropdown
()
{
this
.
$dropdown
.
glDropdown
({
data
:
this
.
$dropdown
.
data
(
'
data
'
),
filterable
:
true
,
selectable
:
true
,
toggleLabel
:
item
=>
item
.
name
,
search
:
{
fields
:
[
'
name
'
],
},
clicked
:
(
query
,
el
,
e
)
=>
this
.
reportSelection
(
query
.
name
,
el
,
e
),
text
:
item
=>
item
.
name
,
});
}
}
app/assets/javascripts/blob/template_selectors/license_selector.js
0 → 100644
浏览文件 @
f564cbb2
/* global Api */
import
FileTemplateSelector
from
'
../file_template_selector
'
;
export
default
class
BlobLicenseSelector
extends
FileTemplateSelector
{
constructor
({
mediator
})
{
super
(
mediator
);
this
.
config
=
{
key
:
'
license
'
,
name
:
'
LICENSE
'
,
pattern
:
/^
(
.+
\/)?(
licen
[
sc
]
e|copying
)(
$|
\.)
/i
,
endpoint
:
Api
.
licenseText
,
dropdown
:
'
.js-license-selector
'
,
wrapper
:
'
.js-license-selector-wrap
'
,
};
}
initDropdown
()
{
this
.
$dropdown
.
glDropdown
({
data
:
this
.
$dropdown
.
data
(
'
data
'
),
filterable
:
true
,
selectable
:
true
,
toggleLabel
:
item
=>
item
.
name
,
search
:
{
fields
:
[
'
name
'
],
},
clicked
:
(
query
,
el
,
e
)
=>
{
const
data
=
{
project
:
this
.
$dropdown
.
data
(
'
project
'
),
fullname
:
this
.
$dropdown
.
data
(
'
fullname
'
),
};
this
.
reportSelection
(
query
.
id
,
el
,
e
,
data
);
},
text
:
item
=>
item
.
name
,
});
}
}
app/assets/javascripts/blob/template_selectors/type_selector.js
0 → 100644
浏览文件 @
f564cbb2
import
FileTemplateSelector
from
'
../file_template_selector
'
;
export
default
class
FileTemplateTypeSelector
extends
FileTemplateSelector
{
constructor
({
mediator
,
dropdownData
})
{
super
(
mediator
);
this
.
mediator
=
mediator
;
this
.
config
=
{
dropdown
:
'
.js-template-type-selector
'
,
wrapper
:
'
.js-template-type-selector-wrap
'
,
dropdownData
,
};
}
initDropdown
()
{
this
.
$dropdown
.
glDropdown
({
data
:
this
.
config
.
dropdownData
,
filterable
:
false
,
selectable
:
true
,
toggleLabel
:
item
=>
item
.
name
,
clicked
:
(
item
,
el
,
e
)
=>
this
.
mediator
.
selectTemplateType
(
item
,
el
,
e
),
text
:
item
=>
item
.
name
,
});
}
}
app/assets/javascripts/blob_edit/blob_bundle.js
浏览文件 @
f564cbb2
...
...
@@ -13,8 +13,9 @@ $(() => {
const
urlRoot
=
editBlobForm
.
data
(
'
relative-url-root
'
);
const
assetsPath
=
editBlobForm
.
data
(
'
assets-prefix
'
);
const
blobLanguage
=
editBlobForm
.
data
(
'
blob-language
'
);
const
currentAction
=
$
(
'
.js-file-title
'
).
data
(
'
current-action
'
);
new
EditBlob
(
`
${
urlRoot
}${
assetsPath
}
`
,
blobLanguage
);
new
EditBlob
(
`
${
urlRoot
}${
assetsPath
}
`
,
blobLanguage
,
currentAction
);
new
NewCommitForm
(
editBlobForm
);
}
...
...
app/assets/javascripts/blob_edit/edit_blob.js
浏览文件 @
f564cbb2
/* global ace */
import
BlobLicenseSelectors
from
'
../blob/template_selectors/blob_license_selectors
'
;
import
BlobGitignoreSelectors
from
'
../blob/template_selectors/blob_gitignore_selectors
'
;
import
BlobCiYamlSelectors
from
'
../blob/template_selectors/blob_ci_yaml_selectors
'
;
import
BlobDockerfileSelectors
from
'
../blob/template_selectors/blob_dockerfile_selectors
'
;
import
TemplateSelectorMediator
from
'
../blob/file_template_mediator
'
;
export
default
class
EditBlob
{
constructor
(
assetsPath
,
aceMode
)
{
constructor
(
assetsPath
,
aceMode
,
currentAction
)
{
this
.
configureAceEditor
(
aceMode
,
assetsPath
);
this
.
prepFileContentForSubmit
();
this
.
initModePanesAndLinks
();
this
.
initSoftWrap
();
this
.
initFileSelectors
();
this
.
initFileSelectors
(
currentAction
);
}
configureAceEditor
(
aceMode
,
assetsPath
)
{
...
...
@@ -19,6 +15,10 @@ export default class EditBlob {
ace
.
config
.
loadModule
(
'
ace/ext/searchbox
'
);
this
.
editor
=
ace
.
edit
(
'
editor
'
);
// This prevents warnings re: automatic scrolling being logged
this
.
editor
.
$blockScrolling
=
Infinity
;
this
.
editor
.
focus
();
if
(
aceMode
)
{
...
...
@@ -26,29 +26,13 @@ export default class EditBlob {
}
}
prepFileContentForSubmit
()
{
$
(
'
form
'
).
submit
(()
=>
{
$
(
'
#file-content
'
).
val
(
this
.
editor
.
getValue
());
initFileSelectors
(
currentAction
)
{
this
.
fileTemplateMediator
=
new
TemplateSelectorMediator
({
currentAction
,
editor
:
this
.
editor
,
});
}
initFileSelectors
()
{
this
.
blobTemplateSelectors
=
[
new
BlobLicenseSelectors
({
editor
:
this
.
editor
,
}),
new
BlobGitignoreSelectors
({
editor
:
this
.
editor
,
}),
new
BlobCiYamlSelectors
({
editor
:
this
.
editor
,
}),
new
BlobDockerfileSelectors
({
editor
:
this
.
editor
,
}),
];
}
initModePanesAndLinks
()
{
this
.
$editModePanes
=
$
(
'
.js-edit-mode-pane
'
);
this
.
$editModeLinks
=
$
(
'
.js-edit-mode a
'
);
...
...
app/assets/javascripts/templates/issuable_template_selector.js
浏览文件 @
f564cbb2
/* eslint-disable comma-dangle, max-len, no-useless-return, no-param-reassign, max-len */
/* global Api */
import
TemplateSelector
from
'
../blob/template_selector
s/template_selector
'
;
import
TemplateSelector
from
'
../blob/template_selector
'
;
((
global
)
=>
{
class
IssuableTemplateSelector
extends
TemplateSelector
{
...
...
app/assets/stylesheets/pages/editor.scss
浏览文件 @
f564cbb2
.file-editor
{
.nav-links
{
border-top
:
1px
solid
$border-color
;
border-right
:
1px
solid
$border-color
;
border-left
:
1px
solid
$border-color
;
border-bottom
:
none
;
border-radius
:
2px
;
background
:
$gray-normal
;
}
#editor
{
border
:
none
;
border-radius
:
0
;
...
...
@@ -72,11 +81,7 @@
}
.encoding-selector
,
.soft-wrap-toggle
,
.license-selector
,
.gitignore-selector
,
.gitlab-ci-yml-selector
,
.dockerfile-selector
{
.soft-wrap-toggle
{
display
:
inline-block
;
vertical-align
:
top
;
font-family
:
$regular_font
;
...
...
@@ -103,28 +108,9 @@
}
}
}
.gitignore-selector
,
.license-selector
,
.gitlab-ci-yml-selector
,
.dockerfile-selector
{
.dropdown
{
line-height
:
21px
;
}
.dropdown-menu-toggle
{
vertical-align
:
top
;
width
:
220px
;
}
}
.gitlab-ci-yml-selector
{
.dropdown-menu-toggle
{
width
:
250px
;
}
}
}
@media
(
max-width
:
$screen-xs-max
){
.file-editor
{
.file-title
{
...
...
@@ -149,10 +135,7 @@
margin
:
3px
0
;
}
.encoding-selector
,
.license-selector
,
.gitignore-selector
,
.gitlab-ci-yml-selector
{
.encoding-selector
{
display
:
block
;
margin
:
3px
0
;
...
...
@@ -163,3 +146,104 @@
}
}
}
.blob-new-page-title
,
.blob-edit-page-title
{
margin
:
19px
0
21px
;
vertical-align
:
top
;
display
:
inline-block
;
@media
(
max-width
:
$screen-sm-max
)
{
display
:
block
;
margin
:
19px
0
12px
;
}
}
.template-selectors-menu
{
display
:
inline-block
;
vertical-align
:
top
;
margin
:
14px
0
0
16px
;
padding
:
0
0
0
14px
;
border-left
:
1px
solid
$border-color
;
@media
(
max-width
:
$screen-sm-max
)
{
display
:
block
;
width
:
100%
;
margin
:
5px
0
;
padding
:
0
;
border-left
:
none
;
}
}
.templates-selectors-label
{
display
:
inline-block
;
vertical-align
:
top
;
margin-top
:
6px
;
line-height
:
21px
;
@media
(
max-width
:
$screen-sm-max
)
{
display
:
block
;
margin
:
5px
0
;
}
}
.template-selector-dropdowns-wrap
{
display
:
inline-block
;
margin-left
:
8px
;
vertical-align
:
top
;
margin
:
5px
0
0
8px
;
@media
(
max-width
:
$screen-sm-max
)
{
display
:
block
;
width
:
100%
;
margin
:
0
0
16px
;
}
.license-selector
,
.gitignore-selector
,
.gitlab-ci-yml-selector
,
.dockerfile-selector
,
.template-type-selector
{
display
:
inline-block
;
vertical-align
:
top
;
font-family
:
$regular_font
;
margin-top
:
-5px
;
@media
(
max-width
:
$screen-sm-max
)
{
display
:
block
;
width
:
100%
;
margin
:
5px
0
;
}
.dropdown
{
line-height
:
21px
;
}
.dropdown-menu-toggle
{
width
:
250px
;
vertical-align
:
top
;
@media
(
max-width
:
$screen-sm-max
)
{
display
:
block
;
width
:
100%
;
margin
:
5px
0
;
}
}
}
}
.template-selectors-undo-menu
{
display
:
inline-block
;
margin
:
7px
0
0
10px
;
@media
(
max-width
:
$screen-sm-max
)
{
display
:
block
;
width
:
100%
;
margin
:
20px
0
;
}
button
{
margin
:
-4px
0
0
15px
;
}
}
app/views/projects/blob/_editor.html.haml
浏览文件 @
f564cbb2
-
action
=
current_action?
(
:edit
)
||
current_action?
(
:update
)
?
'edit'
:
'create'
.file-holder.file.append-bottom-default
.js-file-title.file-title.clearfix
.js-file-title.file-title.clearfix
{
data:
{
current_action:
action
}
}
.editor-ref
=
icon
(
'code-fork'
)
=
ref
%span
.editor-file-name
-
if
current_action?
(
:edit
)
||
current_action?
(
:update
)
=
text_field_tag
'file_path'
,
(
params
[
:file_path
]
||
@path
),
class:
'form-control new-file-path'
class:
'form-control new-file-path
js-file-path-name-input
'
-
if
current_action?
(
:new
)
||
current_action?
(
:create
)
%span
.editor-file-name
\/
=
text_field_tag
'file_name'
,
params
[
:file_name
],
placeholder:
"File name"
,
required:
true
,
class:
'form-control new-file-name'
required:
true
,
class:
'form-control new-file-name
js-file-path-name-input
'
.pull-right.file-buttons
.license-selector.js-license-selector-wrap.hidden
=
dropdown_tag
(
"Choose a License template"
,
options:
{
toggle_class:
'btn js-license-selector'
,
title:
"Choose a license"
,
filter:
true
,
placeholder:
"Filter"
,
data:
{
data:
licenses_for_select
,
project:
@project
.
name
,
fullname:
@project
.
namespace
.
human_name
}
}
)
.gitignore-selector.js-gitignore-selector-wrap.hidden
=
dropdown_tag
(
"Choose a .gitignore template"
,
options:
{
toggle_class:
'btn js-gitignore-selector'
,
title:
"Choose a template"
,
filter:
true
,
placeholder:
"Filter"
,
data:
{
data:
gitignore_names
}
}
)
.gitlab-ci-yml-selector.js-gitlab-ci-yml-selector-wrap.hidden
=
dropdown_tag
(
"Choose a GitLab CI Yaml template"
,
options:
{
toggle_class:
'btn js-gitlab-ci-yml-selector'
,
title:
"Choose a template"
,
filter:
true
,
placeholder:
"Filter"
,
data:
{
data:
gitlab_ci_ymls
}
}
)
.dockerfile-selector.js-dockerfile-selector-wrap.hidden
=
dropdown_tag
(
"Choose a Dockerfile template"
,
options:
{
toggle_class:
'btn js-dockerfile-selector'
,
title:
"Choose a template"
,
filter:
true
,
placeholder:
"Filter"
,
data:
{
data:
dockerfile_names
}
}
)
=
button_tag
class:
'soft-wrap-toggle btn'
,
type:
'button'
do
=
button_tag
class:
'soft-wrap-toggle btn'
,
type:
'button'
,
tabindex:
'-1'
do
%span
.no-wrap
=
custom_icon
(
'icon_no_wrap'
)
No wrap
...
...
@@ -31,7 +25,7 @@
=
custom_icon
(
'icon_soft_wrap'
)
Soft wrap
.encoding-selector
=
select_tag
:encoding
,
options_for_select
([
"base64"
,
"text"
],
"text"
),
class:
'select2'
=
select_tag
:encoding
,
options_for_select
([
"base64"
,
"text"
],
"text"
),
class:
'select2'
,
tabindex:
'-1'
.file-editor.code
%pre
.js-edit-mode-pane
#editor
=
params
[
:content
]
||
local_assigns
[
:blob_data
]
...
...
app/views/projects/blob/_template_selectors.html.haml
0 → 100644
浏览文件 @
f564cbb2
.template-selectors-menu
.templates-selectors-label
Template
.template-selector-dropdowns-wrap
.template-type-selector.js-template-type-selector-wrap.hidden
=
dropdown_tag
(
"Choose type"
,
options:
{
toggle_class:
'btn js-template-type-selector'
,
title:
"Choose a template type"
}
)
.license-selector.js-license-selector-wrap.js-template-selector-wrap.hidden
=
dropdown_tag
(
"Apply a License template"
,
options:
{
toggle_class:
'btn js-license-selector'
,
title:
"Apply a license"
,
filter:
true
,
placeholder:
"Filter"
,
data:
{
data:
licenses_for_select
,
project:
@project
.
name
,
fullname:
@project
.
namespace
.
human_name
}
}
)
.gitignore-selector.js-gitignore-selector-wrap.js-template-selector-wrap.hidden
=
dropdown_tag
(
"Apply a .gitignore template"
,
options:
{
toggle_class:
'btn js-gitignore-selector'
,
title:
"Apply a template"
,
filter:
true
,
placeholder:
"Filter"
,
data:
{
data:
gitignore_names
}
}
)
.gitlab-ci-yml-selector.js-gitlab-ci-yml-selector-wrap.js-template-selector-wrap.hidden
=
dropdown_tag
(
"Apply a GitLab CI Yaml template"
,
options:
{
toggle_class:
'btn js-gitlab-ci-yml-selector'
,
title:
"Apply a template"
,
filter:
true
,
placeholder:
"Filter"
,
data:
{
data:
gitlab_ci_ymls
}
}
)
.dockerfile-selector.js-dockerfile-selector-wrap.js-template-selector-wrap.hidden
=
dropdown_tag
(
"Apply a Dockerfile template"
,
options:
{
toggle_class:
'btn js-dockerfile-selector'
,
title:
"Apply a template"
,
filter:
true
,
placeholder:
"Filter"
,
data:
{
data:
dockerfile_names
}
}
)
.template-selectors-undo-menu.hidden
%span
.text-info
Template applied
%button
.btn.btn-sm.btn-info
Undo
app/views/projects/blob/edit.html.haml
浏览文件 @
f564cbb2
...
...
@@ -11,12 +11,15 @@
Someone edited the file the same time you did. Please check out
=
link_to
"the file"
,
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
tree_join
(
@target_branch
,
@file_path
)),
target:
"_blank"
,
rel:
'noopener noreferrer'
and make sure your changes will not unintentionally remove theirs.
.editor-title-row
%h3
.page-title.blob-edit-page-title
Edit file
=
render
'template_selectors'
.file-editor
%ul
.nav-links.no-bottom.js-edit-mode
%li
.active
=
link_to
'#editor'
do
Edit Fil
e
Writ
e
%li
=
link_to
'#preview'
,
'data-preview-url'
=>
namespace_project_preview_blob_path
(
@project
.
namespace
,
@project
,
@id
)
do
...
...
app/views/projects/blob/new.html.haml
浏览文件 @
f564cbb2
...
...
@@ -2,10 +2,10 @@
-
content_for
:page_specific_javascripts
do
=
page_specific_javascript_tag
(
'lib/ace.js'
)
=
page_specific_javascript_bundle_tag
(
'blob'
)
%h3
.
page-title
New F
ile
.editor-title-row
%h3
.page-title.blob-new-
page-title
New f
ile
=
render
'template_selectors'
.file-editor
=
form_tag
(
namespace_project_create_blob_path
(
@project
.
namespace
,
@project
,
@id
),
method: :post
,
class:
'form-horizontal js-edit-blob-form js-new-blob-form js-quick-submit js-requires-input'
,
data:
blob_editor_paths
)
do
=
render
'projects/blob/editor'
,
ref:
@ref
...
...
changelogs/unreleased/25332-make-file-templates-easy-to-use-and-discover.yml
0 → 100644
浏览文件 @
f564cbb2
---
title
:
Remove no-new annotation from file_template_mediator.js.
merge_request
:
!9782
author
:
spec/features/auto_deploy_spec.rb
浏览文件 @
f564cbb2
...
...
@@ -42,7 +42,7 @@ describe 'Auto deploy' do
it
'includes OpenShift as an available template'
,
js:
true
do
click_link
'Set up auto deploy'
click_button
'
Choose
a GitLab CI Yaml template'
click_button
'
Apply
a GitLab CI Yaml template'
within
'.gitlab-ci-yml-selector'
do
expect
(
page
).
to
have_content
(
'OpenShift'
)
...
...
@@ -51,7 +51,7 @@ describe 'Auto deploy' do
it
'creates a merge request using "auto-deploy" branch'
,
js:
true
do
click_link
'Set up auto deploy'
click_button
'
Choose
a GitLab CI Yaml template'
click_button
'
Apply
a GitLab CI Yaml template'
within
'.gitlab-ci-yml-selector'
do
click_on
'OpenShift'
end
...
...
spec/features/projects/blobs/user_create_spec.rb
浏览文件 @
f564cbb2
...
...
@@ -88,7 +88,7 @@ feature 'New blob creation', feature: true, js: true do
scenario
'shows error message'
do
expect
(
page
).
to
have_content
(
'Your changes could not be committed because a file with the same name already exists'
)
expect
(
page
).
to
have_content
(
'New
F
ile'
)
expect
(
page
).
to
have_content
(
'New
f
ile'
)
expect
(
page
).
to
have_content
(
'NextFeature'
)
end
end
...
...
spec/features/projects/files/project_owner_creates_license_file_spec.rb
浏览文件 @
f564cbb2
...
...
@@ -40,7 +40,7 @@ feature 'project owner creates a license file', feature: true, js: true do
scenario
'project master creates a license file from the "Add license" link'
do
click_link
'Add License'
expect
(
page
).
to
have_content
(
'New
F
ile'
)
expect
(
page
).
to
have_content
(
'New
f
ile'
)
expect
(
current_path
).
to
eq
(
namespace_project_new_blob_path
(
project
.
namespace
,
project
,
'master'
))
expect
(
find
(
'#file_name'
).
value
).
to
eq
(
'LICENSE'
)
...
...
@@ -63,7 +63,7 @@ feature 'project owner creates a license file', feature: true, js: true do
def
select_template
(
template
)
page
.
within
(
'.js-license-selector-wrap'
)
do
click_button
'
Choose
a License template'
click_button
'
Apply
a License template'
click_link
template
wait_for_ajax
end
...
...
spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
浏览文件 @
f564cbb2
...
...
@@ -14,7 +14,7 @@ feature 'project owner sees a link to create a license file in empty project', f
visit
namespace_project_path
(
project
.
namespace
,
project
)
click_link
'Create empty bare repository'
click_on
'LICENSE'
expect
(
page
).
to
have_content
(
'New
F
ile'
)
expect
(
page
).
to
have_content
(
'New
f
ile'
)
expect
(
current_path
).
to
eq
(
namespace_project_new_blob_path
(
project
.
namespace
,
project
,
'master'
))
...
...
@@ -40,7 +40,7 @@ feature 'project owner sees a link to create a license file in empty project', f
def
select_template
(
template
)
page
.
within
(
'.js-license-selector-wrap'
)
do
click_button
'
Choose
a License template'
click_button
'
Apply
a License template'
click_link
template
wait_for_ajax
end
...
...
spec/features/projects/files/template_type_dropdown_spec.rb
0 → 100644
浏览文件 @
f564cbb2
require
'spec_helper'
feature
'Template type dropdown selector'
,
js:
true
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:user
)
{
create
(
:user
)
}
before
do
project
.
team
<<
[
user
,
:master
]
login_as
user
end
context
'editing a non-matching file'
do
before
do
create_and_edit_file
(
'.random-file.js'
)
end
scenario
'not displayed'
do
check_type_selector_display
(
false
)
end
scenario
'selects every template type correctly'
do
fill_in
'file_path'
,
with:
'.gitignore'
try_selecting_all_types
end
scenario
'updates toggle value when input matches'
do
fill_in
'file_path'
,
with:
'.gitignore'
check_type_selector_toggle_text
(
'.gitignore'
)
end
end
context
'editing a matching file'
do
before
do
visit
namespace_project_edit_blob_path
(
project
.
namespace
,
project
,
File
.
join
(
project
.
default_branch
,
'LICENSE'
))
end
scenario
'displayed'
do
check_type_selector_display
(
true
)
end
scenario
'is displayed when input matches'
do
check_type_selector_display
(
true
)
end
scenario
'selects every template type correctly'
do
try_selecting_all_types
end
context
'user previews changes'
do
before
do
click_link
'Preview Changes'
end
scenario
'type selector is hidden and shown correctly'
do
check_type_selector_display
(
false
)
click_link
'Write'
check_type_selector_display
(
true
)
end
end
end
context
'creating a matching file'
do
before
do
visit
namespace_project_new_blob_path
(
project
.
namespace
,
project
,
'master'
,
file_name:
'.gitignore'
)
end
scenario
'is displayed'
do
check_type_selector_display
(
true
)
end
scenario
'toggle is set to the correct value'
do
check_type_selector_toggle_text
(
'.gitignore'
)
end
scenario
'selects every template type correctly'
do
try_selecting_all_types
end
end
context
'creating a file'
do
before
do
visit
namespace_project_new_blob_path
(
project
.
namespace
,
project
,
project
.
default_branch
)
end
scenario
'type selector is shown'
do
check_type_selector_display
(
true
)
end
scenario
'toggle is set to the proper value'
do
check_type_selector_toggle_text
(
'Choose type'
)
end
scenario
'selects every template type correctly'
do
try_selecting_all_types
end
end
end
def
check_type_selector_display
(
is_visible
)
count
=
is_visible
?
1
:
0
expect
(
page
).
to
have_css
(
'.js-template-type-selector'
,
count:
count
)
end
def
try_selecting_all_types
try_selecting_template_type
(
'LICENSE'
,
'Apply a License template'
)
try_selecting_template_type
(
'Dockerfile'
,
'Apply a Dockerfile template'
)
try_selecting_template_type
(
'.gitlab-ci.yml'
,
'Apply a GitLab CI Yaml template'
)
try_selecting_template_type
(
'.gitignore'
,
'Apply a .gitignore template'
)
end
def
try_selecting_template_type
(
template_type
,
selector_label
)
select_template_type
(
template_type
)
check_template_selector_display
(
selector_label
)
check_type_selector_toggle_text
(
template_type
)
end
def
select_template_type
(
template_type
)
find
(
'.js-template-type-selector'
).
click
find
(
'.dropdown-content li'
,
text:
template_type
).
click
end
def
check_template_selector_display
(
content
)
expect
(
page
).
to
have_content
(
content
)
end
def
check_type_selector_toggle_text
(
template_type
)
dropdown_toggle_button
=
find
(
'.template-type-selector .dropdown-toggle-text'
)
expect
(
dropdown_toggle_button
).
to
have_content
(
template_type
)
end
def
create_and_edit_file
(
file_name
)
visit
namespace_project_new_blob_path
(
project
.
namespace
,
project
,
'master'
,
file_name:
file_name
)
click_button
"Commit Changes"
visit
namespace_project_edit_blob_path
(
project
.
namespace
,
project
,
File
.
join
(
project
.
default_branch
,
file_name
))
end
spec/features/projects/files/undo_template_spec.rb
0 → 100644
浏览文件 @
f564cbb2
require
'spec_helper'
include
WaitForAjax
feature
'Template Undo Button'
,
js:
true
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:user
)
{
create
(
:user
)
}
before
do
project
.
team
<<
[
user
,
:master
]
login_as
user
end
context
'editing a matching file and applying a template'
do
before
do
visit
namespace_project_edit_blob_path
(
project
.
namespace
,
project
,
File
.
join
(
project
.
default_branch
,
"LICENSE"
))
select_file_template
(
'.js-license-selector'
,
'Apache License 2.0'
)
end
scenario
'reverts template application'
do
try_template_undo
(
'http://www.apache.org/licenses/'
,
'Apply a License template'
)
end
end
context
'creating a non-matching file'
do
before
do
visit
namespace_project_new_blob_path
(
project
.
namespace
,
project
,
'master'
)
select_file_template_type
(
'LICENSE'
)
select_file_template
(
'.js-license-selector'
,
'Apache License 2.0'
)
end
scenario
'reverts template application'
do
try_template_undo
(
'http://www.apache.org/licenses/'
,
'Apply a License template'
)
end
end
end
def
try_template_undo
(
template_content
,
toggle_text
)
check_undo_button_display
check_content_reverted
(
template_content
)
check_toggle_text_set
(
toggle_text
)
end
def
check_toggle_text_set
(
neutral_toggle_text
)
expect
(
page
).
to
have_content
(
neutral_toggle_text
)
end
def
check_undo_button_display
expect
(
page
).
to
have_content
(
'Template applied'
)
expect
(
page
).
to
have_css
(
'.template-selectors-undo-menu .btn-info'
)
end
def
check_content_reverted
(
template_content
)
find
(
'.template-selectors-undo-menu .btn-info'
).
click
expect
(
page
).
not_to
have_content
(
template_content
)
expect
(
find
(
'.template-type-selector .dropdown-toggle-text'
)).
to
have_content
()
end
def
select_file_template
(
template_selector_selector
,
template_name
)
find
(
template_selector_selector
).
click
find
(
'.dropdown-content li'
,
text:
template_name
).
click
wait_for_ajax
end
def
select_file_template_type
(
template_type
)
find
(
'.js-template-type-selector'
).
click
find
(
'.dropdown-content li'
,
text:
template_type
).
click
end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录