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
fea7562f
Commit
fea7562f
authored
May 26, 2021
by
Illya Klymov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replace Select2Select component with GlDropdown
- removes Vue binding to Select2Select
parent
c79db67d
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
170 additions
and
110 deletions
+170
-110
app/assets/javascripts/import_entities/components/group_dropdown.vue
...javascripts/import_entities/components/group_dropdown.vue
+40
-0
app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue
...rt_entities/import_groups/components/import_table_row.vue
+16
-10
app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue
...ties/import_projects/components/import_projects_table.vue
+2
-12
app/assets/javascripts/import_entities/import_projects/components/provider_repo_table_row.vue
...es/import_projects/components/provider_repo_table_row.vue
+42
-20
app/assets/javascripts/import_entities/import_projects/index.js
...sets/javascripts/import_entities/import_projects/index.js
+1
-1
app/assets/javascripts/vue_shared/components/select2_select.vue
...sets/javascripts/vue_shared/components/select2_select.vue
+0
-48
qa/qa/page/group/bulk_import.rb
qa/qa/page/group/bulk_import.rb
+4
-1
qa/qa/page/project/import/github.rb
qa/qa/page/project/import/github.rb
+6
-4
spec/frontend/import_entities/components/group_dropdown_spec.js
...rontend/import_entities/components/group_dropdown_spec.js
+44
-0
spec/frontend/import_entities/import_groups/components/import_table_row_spec.js
...ntities/import_groups/components/import_table_row_spec.js
+4
-2
spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
.../import_projects/components/import_projects_table_spec.js
+3
-1
spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js
...mport_projects/components/provider_repo_table_row_spec.js
+8
-11
No files found.
app/assets/javascripts/import_entities/components/group_dropdown.vue
0 → 100644
View file @
fea7562f
<
script
>
import
{
GlDropdown
,
GlSearchBoxByType
}
from
'
@gitlab/ui
'
;
export
default
{
components
:
{
GlDropdown
,
GlSearchBoxByType
,
},
inheritAttrs
:
false
,
props
:
{
namespaces
:
{
type
:
Array
,
required
:
true
,
},
},
data
()
{
return
{
searchTerm
:
''
};
},
computed
:
{
filteredNamespaces
()
{
return
this
.
namespaces
.
filter
((
ns
)
=>
ns
.
toLowerCase
().
includes
(
this
.
searchTerm
.
toLowerCase
()),
);
},
},
};
</
script
>
<
template
>
<gl-dropdown
toggle-class=
"gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
class=
"import-entities-namespace-dropdown gl-h-7 gl-flex-fill-1"
data-qa-selector=
"target_namespace_selector_dropdown"
v-bind=
"$attrs"
>
<template
#header
>
<gl-search-box-by-type
v-model.trim=
"searchTerm"
/>
</
template
>
<slot
:namespaces=
"filteredNamespaces"
></slot>
</gl-dropdown>
</template>
app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue
View file @
fea7562f
<
script
>
import
{
GlButton
,
GlDropdown
,
GlDropdownDivider
,
GlDropdownItem
,
GlDropdownSectionHeader
,
...
...
@@ -11,6 +10,7 @@ import {
}
from
'
@gitlab/ui
'
;
import
{
joinPaths
}
from
'
~/lib/utils/url_utility
'
;
import
{
s__
}
from
'
~/locale
'
;
import
ImportGroupDropdown
from
'
../../components/group_dropdown.vue
'
;
import
ImportStatus
from
'
../../components/import_status.vue
'
;
import
{
STATUSES
}
from
'
../../constants
'
;
import
addValidationErrorMutation
from
'
../graphql/mutations/add_validation_error.mutation.graphql
'
;
...
...
@@ -22,8 +22,8 @@ const DEBOUNCE_INTERVAL = 300;
export
default
{
components
:
{
ImportStatus
,
ImportGroupDropdown
,
GlButton
,
GlDropdown
,
GlDropdownDivider
,
GlDropdownItem
,
GlDropdownSectionHeader
,
...
...
@@ -83,6 +83,10 @@ export default {
},
computed
:
{
availableNamespaceNames
()
{
return
this
.
availableNamespaces
.
map
((
ns
)
=>
ns
.
full_path
);
},
importTarget
()
{
return
this
.
group
.
import_target
;
},
...
...
@@ -153,9 +157,11 @@ export default {
disabled: isAlreadyImported,
}"
>
<gl-dropdown
<import-group-dropdown
#default
="
{ namespaces }"
:text="importTarget.target_namespace"
:disabled="isAlreadyImported"
:namespaces="availableNamespaceNames"
toggle-class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
class="import-entities-namespace-dropdown gl-h-7 gl-flex-grow-1"
data-qa-selector="target_namespace_selector_dropdown"
...
...
@@ -163,22 +169,22 @@ export default {
<gl-dropdown-item
@
click=
"$emit('update-target-namespace', '')"
>
{{
s__
(
'
BulkImport|No parent
'
)
}}
</gl-dropdown-item>
<template
v-if=
"
availableN
amespaces.length"
>
<template
v-if=
"
n
amespaces.length"
>
<gl-dropdown-divider
/>
<gl-dropdown-section-header>
{{
s__
(
'
BulkImport|Existing groups
'
)
}}
</gl-dropdown-section-header>
<gl-dropdown-item
v-for=
"ns in
availableN
amespaces"
:key=
"ns
.full_path
"
v-for=
"ns in
n
amespaces"
:key=
"ns"
data-qa-selector=
"target_group_dropdown_item"
:data-qa-group-name=
"ns
.full_path
"
@
click=
"$emit('update-target-namespace', ns
.full_path
)"
:data-qa-group-name=
"ns"
@
click=
"$emit('update-target-namespace', ns)"
>
{{
ns
.
full_path
}}
{{
ns
}}
</gl-dropdown-item>
</
template
>
</
gl
-dropdown>
</
import-group
-dropdown>
<div
class=
"import-entities-target-select-separator gl-h-7 gl-px-3 gl-display-flex gl-align-items-center gl-border-solid gl-border-0 gl-border-t-1 gl-border-b-1"
>
...
...
app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue
View file @
fea7562f
...
...
@@ -47,18 +47,7 @@ export default {
},
availableNamespaces
()
{
const
serializedNamespaces
=
this
.
namespaces
.
map
(({
fullPath
})
=>
({
id
:
fullPath
,
text
:
fullPath
,
}));
return
[
{
text
:
__
(
'
Groups
'
),
children
:
serializedNamespaces
},
{
text
:
__
(
'
Users
'
),
children
:
[{
id
:
this
.
defaultTargetNamespace
,
text
:
this
.
defaultTargetNamespace
}],
},
];
return
this
.
namespaces
.
map
(({
fullPath
})
=>
fullPath
);
},
importAllButtonText
()
{
...
...
@@ -179,6 +168,7 @@ export default {
:key=
"repo.importSource.providerLink"
:repo=
"repo"
:available-namespaces=
"availableNamespaces"
:user-namespace=
"defaultTargetNamespace"
/>
</
template
>
</tbody>
...
...
app/assets/javascripts/import_entities/import_projects/components/provider_repo_table_row.vue
View file @
fea7562f
<
script
>
import
{
GlIcon
,
GlBadge
,
GlFormInput
,
GlButton
,
GlLink
}
from
'
@gitlab/ui
'
;
import
{
GlIcon
,
GlBadge
,
GlFormInput
,
GlButton
,
GlLink
,
GlDropdownItem
,
GlDropdownDivider
,
GlDropdownSectionHeader
,
}
from
'
@gitlab/ui
'
;
import
{
mapState
,
mapGetters
,
mapActions
}
from
'
vuex
'
;
import
{
__
}
from
'
~/locale
'
;
import
Select2Select
from
'
~/vue_shared/components/select2_select
.vue
'
;
import
ImportGroupDropdown
from
'
../../components/group_dropdown
.vue
'
;
import
ImportStatus
from
'
../../components/import_status.vue
'
;
import
{
STATUSES
}
from
'
../../constants
'
;
import
{
isProjectImportable
,
isIncompatible
,
getImportStatus
}
from
'
../utils
'
;
...
...
@@ -10,10 +19,13 @@ import { isProjectImportable, isIncompatible, getImportStatus } from '../utils';
export
default
{
name
:
'
ProviderRepoTableRow
'
,
components
:
{
Select2Select
,
ImportGroupDropdown
,
ImportStatus
,
GlFormInput
,
GlButton
,
GlDropdownItem
,
GlDropdownDivider
,
GlDropdownSectionHeader
,
GlIcon
,
GlBadge
,
GlLink
,
...
...
@@ -23,6 +35,10 @@ export default {
type
:
Object
,
required
:
true
,
},
userNamespace
:
{
type
:
String
,
required
:
true
,
},
availableNamespaces
:
{
type
:
Array
,
required
:
true
,
...
...
@@ -61,22 +77,6 @@ export default {
return
this
.
ciCdOnly
?
__
(
'
Connect
'
)
:
__
(
'
Import
'
);
},
select2Options
()
{
return
{
data
:
this
.
availableNamespaces
,
containerCssClass
:
'
import-namespace-select qa-project-namespace-select gl-w-auto
'
,
};
},
targetNamespaceSelect
:
{
get
()
{
return
this
.
importTarget
.
targetNamespace
;
},
set
(
value
)
{
this
.
updateImportTarget
({
targetNamespace
:
value
});
},
},
newNameInput
:
{
get
()
{
return
this
.
importTarget
.
newName
;
...
...
@@ -118,7 +118,29 @@ export default {
<template
v-if=
"repo.importSource.target"
>
{{
repo
.
importSource
.
target
}}
</
template
>
<
template
v-else-if=
"isImportNotStarted"
>
<div
class=
"import-entities-target-select gl-display-flex gl-align-items-stretch gl-w-full"
>
<select2-select
v-model=
"targetNamespaceSelect"
:options=
"select2Options"
/>
<import-group-dropdown
#default
="
{ namespaces }"
:text="importTarget.targetNamespace"
:namespaces="availableNamespaces"
>
<template
v-if=
"namespaces.length"
>
<gl-dropdown-section-header>
{{
__
(
'
Groups
'
)
}}
</gl-dropdown-section-header>
<gl-dropdown-item
v-for=
"ns in namespaces"
:key=
"ns"
data-qa-selector=
"target_group_dropdown_item"
:data-qa-group-name=
"ns"
@
click=
"updateImportTarget(
{ targetNamespace: ns })"
>
{{
ns
}}
</gl-dropdown-item>
<gl-dropdown-divider
/>
</
template
>
<gl-dropdown-section-header>
{{ __('Users') }}
</gl-dropdown-section-header>
<gl-dropdown-item
@
click=
"updateImportTarget({ targetNamespace: ns })"
>
{{
userNamespace
}}
</gl-dropdown-item>
</import-group-dropdown>
<div
class=
"import-entities-target-select-separator gl-px-3 gl-display-flex gl-align-items-center gl-border-solid gl-border-0 gl-border-t-1 gl-border-b-1"
>
...
...
app/assets/javascripts/import_entities/import_projects/index.js
View file @
fea7562f
...
...
@@ -38,7 +38,7 @@ export function initStoreFromElement(element) {
export
function
initPropsFromElement
(
element
)
{
return
{
providerTitle
:
element
.
dataset
.
provider
Title
,
providerTitle
:
element
.
dataset
.
provider
,
filterable
:
parseBoolean
(
element
.
dataset
.
filterable
),
paginatable
:
parseBoolean
(
element
.
dataset
.
paginatable
),
};
...
...
app/assets/javascripts/vue_shared/components/select2_select.vue
deleted
100644 → 0
View file @
c79db67d
<
script
>
import
$
from
'
jquery
'
;
import
'
select2
'
;
import
{
loadCSSFile
}
from
'
~/lib/utils/css_utils
'
;
export
default
{
// False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/26
// eslint-disable-next-line @gitlab/require-i18n-strings
name
:
'
Select2Select
'
,
props
:
{
options
:
{
type
:
Object
,
required
:
false
,
default
:
()
=>
({}),
},
value
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
},
watch
:
{
value
()
{
$
(
this
.
$refs
.
dropdownInput
).
val
(
this
.
value
).
trigger
(
'
change
'
);
},
},
mounted
()
{
loadCSSFile
(
gon
.
select2_css_path
)
.
then
(()
=>
{
$
(
this
.
$refs
.
dropdownInput
)
.
val
(
this
.
value
)
.
select2
(
this
.
options
)
.
on
(
'
change
'
,
(
event
)
=>
this
.
$emit
(
'
input
'
,
event
.
target
.
value
));
})
.
catch
(()
=>
{});
},
beforeDestroy
()
{
$
(
this
.
$refs
.
dropdownInput
).
select2
(
'
destroy
'
);
},
};
</
script
>
<
template
>
<input
ref=
"dropdownInput"
type=
"hidden"
/>
</
template
>
qa/qa/page/group/bulk_import.rb
View file @
fea7562f
...
...
@@ -10,12 +10,15 @@ module QA
view
"app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue"
do
element
:import_item
element
:target_namespace_selector_dropdown
element
:target_group_dropdown_item
element
:import_status_indicator
element
:import_group_button
end
view
"app/assets/javascripts/import_entities/components/group_dropdown.vue"
do
element
:target_namespace_selector_dropdown
end
# Import source group in to target group
#
# @param [String] source_group_name
...
...
qa/qa/page/project/import/github.rb
View file @
fea7562f
...
...
@@ -14,13 +14,16 @@ module QA
view
'app/assets/javascripts/import_entities/import_projects/components/provider_repo_table_row.vue'
do
element
:project_import_row
element
:project_namespace_select
element
:project_path_field
element
:import_button
element
:project_path_content
element
:go_to_project_button
end
view
"app/assets/javascripts/import_entities/components/group_dropdown.vue"
do
element
:target_namespace_selector_dropdown
end
def
add_personal_access_token
(
personal_access_token
)
# If for some reasons this process is retried, user cannot re-enter github token in the same group
# In this case skip this step and proceed to import project row
...
...
@@ -59,10 +62,9 @@ module QA
def
choose_test_namespace
(
full_path
)
within_repo_path
(
full_path
)
do
click_element
:project_namespace_select
within_element
(
:target_namespace_selector_dropdown
)
{
click_button
(
class:
'dropdown-toggle'
)
}
click_element
(
:target_group_dropdown_item
,
group_name:
Runtime
::
Namespace
.
path
)
end
search_and_select
(
Runtime
::
Namespace
.
path
)
end
def
set_path
(
full_path
,
name
)
...
...
spec/frontend/import_entities/components/group_dropdown_spec.js
0 → 100644
View file @
fea7562f
import
{
GlSearchBoxByType
,
GlDropdown
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
GroupDropdown
from
'
~/import_entities/components/group_dropdown.vue
'
;
describe
(
'
Import entities group dropdown component
'
,
()
=>
{
let
wrapper
;
let
namespacesTracker
;
const
createComponent
=
(
propsData
)
=>
{
namespacesTracker
=
jest
.
fn
();
wrapper
=
shallowMount
(
GroupDropdown
,
{
scopedSlots
:
{
default
:
namespacesTracker
,
},
stubs
:
{
GlDropdown
},
propsData
,
});
};
afterEach
(()
=>
{
wrapper
.
destroy
();
});
it
(
'
passes namespaces from props to default slot
'
,
()
=>
{
const
namespaces
=
[
'
ns1
'
,
'
ns2
'
];
createComponent
({
namespaces
});
expect
(
namespacesTracker
).
toHaveBeenCalledWith
({
namespaces
});
});
it
(
'
filters namespaces based on user input
'
,
async
()
=>
{
const
namespaces
=
[
'
match1
'
,
'
some unrelated
'
,
'
match2
'
];
createComponent
({
namespaces
});
namespacesTracker
.
mockReset
();
wrapper
.
find
(
GlSearchBoxByType
).
vm
.
$emit
(
'
input
'
,
'
match
'
);
await
nextTick
();
expect
(
namespacesTracker
).
toHaveBeenCalledWith
({
namespaces
:
[
'
match1
'
,
'
match2
'
]
});
});
});
spec/frontend/import_entities/import_groups/components/import_table_row_spec.js
View file @
fea7562f
import
{
GlButton
,
GlDropdown
,
GlDropdown
Item
,
GlLink
,
GlFormInput
}
from
'
@gitlab/ui
'
;
import
{
GlButton
,
GlDropdownItem
,
GlLink
,
GlFormInput
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
ImportGroupDropdown
from
'
~/import_entities/components/group_dropdown.vue
'
;
import
{
STATUSES
}
from
'
~/import_entities/constants
'
;
import
ImportTableRow
from
'
~/import_entities/import_groups/components/import_table_row.vue
'
;
import
addValidationErrorMutation
from
'
~/import_entities/import_groups/graphql/mutations/add_validation_error.mutation.graphql
'
;
...
...
@@ -41,7 +42,7 @@ describe('import table row', () => {
};
const
findImportButton
=
()
=>
findByText
(
GlButton
,
'
Import
'
);
const
findNameInput
=
()
=>
wrapper
.
find
(
GlFormInput
);
const
findNamespaceDropdown
=
()
=>
wrapper
.
find
(
Gl
Dropdown
);
const
findNamespaceDropdown
=
()
=>
wrapper
.
find
(
ImportGroup
Dropdown
);
const
createComponent
=
(
props
)
=>
{
apolloProvider
=
createMockApollo
([
...
...
@@ -65,6 +66,7 @@ describe('import table row', () => {
wrapper
=
shallowMount
(
ImportTableRow
,
{
apolloProvider
,
stubs
:
{
ImportGroupDropdown
},
propsData
:
{
availableNamespaces
:
availableNamespacesFixture
,
groupPathRegex
:
/.*/
,
...
...
spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
View file @
fea7562f
...
...
@@ -11,6 +11,8 @@ import state from '~/import_entities/import_projects/store/state';
describe
(
'
ImportProjectsTable
'
,
()
=>
{
let
wrapper
;
const
USER_NAMESPACE
=
'
root
'
;
const
findFilterField
=
()
=>
wrapper
.
findAllComponents
(
GlFormInput
)
...
...
@@ -48,7 +50,7 @@ describe('ImportProjectsTable', () => {
localVue
.
use
(
Vuex
);
const
store
=
new
Vuex
.
Store
({
state
:
{
...
state
(),
...
initialState
},
state
:
{
...
state
(),
defaultTargetNamespace
:
USER_NAMESPACE
,
...
initialState
},
getters
:
{
...
getters
,
...
customGetters
,
...
...
spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js
View file @
fea7562f
import
{
GlBadge
,
GlButton
}
from
'
@gitlab/ui
'
;
import
{
GlBadge
,
GlButton
,
GlDropdown
}
from
'
@gitlab/ui
'
;
import
{
createLocalVue
,
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
{
STATUSES
}
from
'
~/import_entities//constants
'
;
import
ImportGroupDropdown
from
'
~/import_entities/components/group_dropdown.vue
'
;
import
ImportStatus
from
'
~/import_entities/components/import_status.vue
'
;
import
ProviderRepoTableRow
from
'
~/import_entities/import_projects/components/provider_repo_table_row.vue
'
;
import
Select2Select
from
'
~/vue_shared/components/select2_select.vue
'
;
describe
(
'
ProviderRepoTableRow
'
,
()
=>
{
let
wrapper
;
...
...
@@ -16,10 +16,8 @@ describe('ProviderRepoTableRow', () => {
newName
:
'
newName
'
,
};
const
availableNamespaces
=
[
{
text
:
'
Groups
'
,
children
:
[{
id
:
'
test
'
,
text
:
'
test
'
}]
},
{
text
:
'
Users
'
,
children
:
[{
id
:
'
root
'
,
text
:
'
root
'
}]
},
];
const
availableNamespaces
=
[
'
test
'
];
const
userNamespace
=
'
root
'
;
function
initStore
(
initialState
)
{
const
store
=
new
Vuex
.
Store
({
...
...
@@ -48,7 +46,7 @@ describe('ProviderRepoTableRow', () => {
wrapper
=
shallowMount
(
ProviderRepoTableRow
,
{
localVue
,
store
,
propsData
:
{
availableNamespaces
,
...
props
},
propsData
:
{
availableNamespaces
,
userNamespace
,
...
props
},
});
}
...
...
@@ -81,9 +79,8 @@ describe('ProviderRepoTableRow', () => {
expect
(
wrapper
.
find
(
ImportStatus
).
props
().
status
).
toBe
(
STATUSES
.
NONE
);
});
it
(
'
renders a select2 namespace select
'
,
()
=>
{
expect
(
wrapper
.
find
(
Select2Select
).
exists
()).
toBe
(
true
);
expect
(
wrapper
.
find
(
Select2Select
).
props
().
options
.
data
).
toBe
(
availableNamespaces
);
it
(
'
renders a group namespace select
'
,
()
=>
{
expect
(
wrapper
.
find
(
ImportGroupDropdown
).
props
().
namespaces
).
toBe
(
availableNamespaces
);
});
it
(
'
renders import button
'
,
()
=>
{
...
...
@@ -133,7 +130,7 @@ describe('ProviderRepoTableRow', () => {
});
it
(
'
does not renders a namespace select
'
,
()
=>
{
expect
(
wrapper
.
find
(
Select2Select
).
exists
()).
toBe
(
false
);
expect
(
wrapper
.
find
(
GlDropdown
).
exists
()).
toBe
(
false
);
});
it
(
'
does not render import button
'
,
()
=>
{
...
...
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