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
629820f0
Commit
629820f0
authored
Jul 07, 2021
by
Nicolò Maria Mezzopera
Committed by
Olena Horal-Koretska
Jul 07, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add new feature flag for apollo refactor
parent
2f4aec55
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
434 additions
and
29 deletions
+434
-29
app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue
...nd_registries/package_registry/components/details/app.vue
+301
-0
app/assets/javascripts/packages_and_registries/package_registry/pages/details.js
...packages_and_registries/package_registry/pages/details.js
+26
-0
app/assets/javascripts/pages/projects/packages/packages/show/index.js
...avascripts/pages/projects/packages/packages/show/index.js
+11
-3
app/helpers/packages_helper.rb
app/helpers/packages_helper.rb
+25
-0
app/views/projects/packages/packages/show.html.haml
app/views/projects/packages/packages/show.html.haml
+4
-20
config/feature_flags/development/package_details_apollo.yml
config/feature_flags/development/package_details_apollo.yml
+8
-0
spec/features/groups/packages_spec.rb
spec/features/groups/packages_spec.rb
+7
-1
spec/features/projects/package_files_spec.rb
spec/features/projects/package_files_spec.rb
+10
-4
spec/features/projects/packages_spec.rb
spec/features/projects/packages_spec.rb
+7
-1
spec/frontend/packages_and_registries/package_registry/components/details/app_spec.js
...egistries/package_registry/components/details/app_spec.js
+35
-0
No files found.
app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue
0 → 100644
View file @
629820f0
<
script
>
/*
* The commented part of this component needs to be re-enabled in the refactor process,
* See here for more info: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64939
*/
import
{
GlBadge
,
GlButton
,
GlModal
,
GlModalDirective
,
GlTooltipDirective
,
GlEmptyState
,
GlTab
,
GlTabs
,
GlSprintf
,
}
from
'
@gitlab/ui
'
;
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_utils
'
;
import
{
objectToQuery
}
from
'
~/lib/utils/url_utility
'
;
import
{
s__
,
__
}
from
'
~/locale
'
;
// import AdditionalMetadata from '~/packages/details/components/additional_metadata.vue';
// import DependencyRow from '~/packages/details/components/dependency_row.vue';
// import InstallationCommands from '~/packages/details/components/installation_commands.vue';
// import PackageFiles from '~/packages/details/components/package_files.vue';
// import PackageHistory from '~/packages/details/components/package_history.vue';
// import PackageListRow from '~/packages/shared/components/package_list_row.vue';
import
PackagesListLoader
from
'
~/packages/shared/components/packages_list_loader.vue
'
;
import
{
PackageType
,
TrackingActions
,
SHOW_DELETE_SUCCESS_ALERT
,
}
from
'
~/packages/shared/constants
'
;
import
{
packageTypeToTrackCategory
}
from
'
~/packages/shared/utils
'
;
import
Tracking
from
'
~/tracking
'
;
export
default
{
name
:
'
PackagesApp
'
,
components
:
{
GlBadge
,
GlButton
,
GlEmptyState
,
GlModal
,
GlTab
,
GlTabs
,
GlSprintf
,
PackageTitle
:
()
=>
import
(
'
~/packages/details/components/package_title.vue
'
),
TerraformTitle
:
()
=>
import
(
'
~/packages_and_registries/infrastructure_registry/components/details_title.vue
'
),
PackagesListLoader
,
// PackageListRow,
// DependencyRow,
// PackageHistory,
// AdditionalMetadata,
// InstallationCommands,
// PackageFiles,
},
directives
:
{
GlTooltip
:
GlTooltipDirective
,
GlModal
:
GlModalDirective
,
},
mixins
:
[
Tracking
.
mixin
()],
inject
:
[
'
titleComponent
'
,
'
projectName
'
,
'
canDelete
'
,
'
svgPath
'
,
'
npmPath
'
,
'
npmHelpPath
'
,
'
projectListUrl
'
,
'
groupListUrl
'
,
],
trackingActions
:
{
...
TrackingActions
},
data
()
{
return
{
fileToDelete
:
null
,
packageEntity
:
{},
};
},
computed
:
{
packageFiles
()
{
return
this
.
packageEntity
.
packageFiles
;
},
isLoading
()
{
return
false
;
},
isValidPackage
()
{
return
Boolean
(
this
.
packageEntity
.
name
);
},
tracking
()
{
return
{
category
:
packageTypeToTrackCategory
(
this
.
packageEntity
.
package_type
),
};
},
hasVersions
()
{
return
this
.
packageEntity
.
versions
?.
length
>
0
;
},
packageDependencies
()
{
return
this
.
packageEntity
.
dependency_links
||
[];
},
showDependencies
()
{
return
this
.
packageEntity
.
package_type
===
PackageType
.
NUGET
;
},
showFiles
()
{
return
this
.
packageEntity
?.
package_type
!==
PackageType
.
COMPOSER
;
},
},
methods
:
{
formatSize
(
size
)
{
return
numberToHumanSize
(
size
);
},
getPackageVersions
()
{
if
(
!
this
.
packageEntity
.
versions
)
{
// this.fetchPackageVersions();
}
},
async
confirmPackageDeletion
()
{
this
.
track
(
TrackingActions
.
DELETE_PACKAGE
);
await
this
.
deletePackage
();
const
returnTo
=
!
this
.
groupListUrl
||
document
.
referrer
.
includes
(
this
.
projectName
)
?
this
.
projectListUrl
:
this
.
groupListUrl
;
// to avoid security issue url are supplied from backend
const
modalQuery
=
objectToQuery
({
[
SHOW_DELETE_SUCCESS_ALERT
]:
true
});
window
.
location
.
replace
(
`
${
returnTo
}
?
${
modalQuery
}
`
);
},
handleFileDelete
(
file
)
{
this
.
track
(
TrackingActions
.
REQUEST_DELETE_PACKAGE_FILE
);
this
.
fileToDelete
=
{
...
file
};
this
.
$refs
.
deleteFileModal
.
show
();
},
confirmFileDelete
()
{
this
.
track
(
TrackingActions
.
DELETE_PACKAGE_FILE
);
// this.deletePackageFile(this.fileToDelete.id);
this
.
fileToDelete
=
null
;
},
},
i18n
:
{
deleteModalTitle
:
s__
(
`PackageRegistry|Delete Package Version`
),
deleteModalContent
:
s__
(
`PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?`
,
),
deleteFileModalTitle
:
s__
(
`PackageRegistry|Delete Package File`
),
deleteFileModalContent
:
s__
(
`PackageRegistry|You are about to delete %{filename}. This is a destructive action that may render your package unusable. Are you sure?`
,
),
},
modal
:
{
packageDeletePrimaryAction
:
{
text
:
__
(
'
Delete
'
),
attributes
:
[
{
variant
:
'
danger
'
},
{
category
:
'
primary
'
},
{
'
data-qa-selector
'
:
'
delete_modal_button
'
},
],
},
fileDeletePrimaryAction
:
{
text
:
__
(
'
Delete
'
),
attributes
:
[{
variant
:
'
danger
'
},
{
category
:
'
primary
'
}],
},
cancelAction
:
{
text
:
__
(
'
Cancel
'
),
},
},
};
</
script
>
<
template
>
<gl-empty-state
v-if=
"!isValidPackage"
:title=
"s__('PackageRegistry|Unable to load package')"
:description=
"s__('PackageRegistry|There was a problem fetching the details for this package.')"
:svg-path=
"svgPath"
/>
<div
v-else
class=
"packages-app"
>
<component
:is=
"titleComponent"
>
<template
#delete-button
>
<gl-button
v-if=
"canDelete"
v-gl-modal=
"'delete-modal'"
class=
"js-delete-button"
variant=
"danger"
category=
"primary"
data-qa-selector=
"delete_button"
>
{{
__
(
'
Delete
'
)
}}
</gl-button>
</
template
>
</component>
<gl-tabs>
<gl-tab
:title=
"__('Detail')"
>
<div
data-qa-selector=
"package_information_content"
>
<!-- <package-history :package-entity="packageEntity" :project-name="projectName" />
<installation-commands
:package-entity="packageEntity"
:npm-path="npmPath"
:npm-help-path="npmHelpPath"
/>
<additional-metadata :package-entity="packageEntity" /> -->
</div>
<!-- <package-files
v-if="showFiles"
:package-files="packageFiles"
:can-delete="canDelete"
@download-file="track($options.trackingActions.PULL_PACKAGE)"
@delete-file="handleFileDelete"
/> -->
</gl-tab>
<gl-tab
v-if=
"showDependencies"
title-item-class=
"js-dependencies-tab"
>
<
template
#title
>
<span>
{{
__
(
'
Dependencies
'
)
}}
</span>
<gl-badge
size=
"sm"
data-testid=
"dependencies-badge"
>
{{
packageDependencies
.
length
}}
</gl-badge>
</
template
>
<
template
v-if=
"packageDependencies.length > 0"
>
<dependency-row
v-for=
"(dep, index) in packageDependencies"
:key=
"index"
:dependency=
"dep"
/>
</
template
>
<p
v-else
class=
"gl-mt-3"
data-testid=
"no-dependencies-message"
>
{{ s__('PackageRegistry|This NuGet package has no dependencies.') }}
</p>
</gl-tab>
<gl-tab
:title=
"__('Other versions')"
title-item-class=
"js-versions-tab"
@
click=
"getPackageVersions"
>
<
template
v-if=
"isLoading && !hasVersions"
>
<packages-list-loader
/>
</
template
>
<
template
v-else-if=
"hasVersions"
>
<!--
<package-list-row
v-for=
"v in packageEntity.versions"
:key=
"v.id"
:package-entity=
"
{ name: packageEntity.name, ...v }"
:package-link="v.id.toString()"
:disable-delete="true"
:show-package-type="false"
/> -->
</
template
>
<p
v-else
class=
"gl-mt-3"
data-testid=
"no-versions-message"
>
{{ s__('PackageRegistry|There are no other versions of this package.') }}
</p>
</gl-tab>
</gl-tabs>
<gl-modal
ref=
"deleteModal"
class=
"js-delete-modal"
modal-id=
"delete-modal"
:action-primary=
"$options.modal.packageDeletePrimaryAction"
:action-cancel=
"$options.modal.cancelAction"
@
primary=
"confirmPackageDeletion"
@
canceled=
"track($options.trackingActions.CANCEL_DELETE_PACKAGE)"
>
<
template
#modal-title
>
{{
$options
.
i18n
.
deleteModalTitle
}}
</
template
>
<gl-sprintf
:message=
"$options.i18n.deleteModalContent"
>
<
template
#version
>
<strong>
{{
packageEntity
.
version
}}
</strong>
</
template
>
<
template
#name
>
<strong>
{{
packageEntity
.
name
}}
</strong>
</
template
>
</gl-sprintf>
</gl-modal>
<gl-modal
ref=
"deleteFileModal"
modal-id=
"delete-file-modal"
:action-primary=
"$options.modal.fileDeletePrimaryAction"
:action-cancel=
"$options.modal.cancelAction"
@
primary=
"confirmFileDelete"
@
canceled=
"track($options.trackingActions.CANCEL_DELETE_PACKAGE_FILE)"
>
<
template
#modal-title
>
{{
$options
.
i18n
.
deleteFileModalTitle
}}
</
template
>
<gl-sprintf
v-if=
"fileToDelete"
:message=
"$options.i18n.deleteFileModalContent"
>
<
template
#filename
>
<strong>
{{
fileToDelete
.
file_name
}}
</strong>
</
template
>
</gl-sprintf>
</gl-modal>
</div>
</template>
app/assets/javascripts/packages_and_registries/package_registry/pages/details.js
0 → 100644
View file @
629820f0
import
Vue
from
'
vue
'
;
import
{
parseBoolean
}
from
'
~/lib/utils/common_utils
'
;
import
Translate
from
'
~/vue_shared/translate
'
;
import
PackagesApp
from
'
../components/details/app.vue
'
;
Vue
.
use
(
Translate
);
export
default
()
=>
{
const
el
=
document
.
getElementById
(
'
js-vue-packages-detail-new
'
);
if
(
!
el
)
{
return
null
;
}
const
{
canDelete
,
...
datasetOptions
}
=
el
.
dataset
;
return
new
Vue
({
el
,
provide
:
{
canDelete
:
parseBoolean
(
canDelete
),
titleComponent
:
'
PackageTitle
'
,
...
datasetOptions
,
},
render
(
createElement
)
{
return
createElement
(
PackagesApp
);
},
});
};
app/assets/javascripts/pages/projects/packages/packages/show/index.js
View file @
629820f0
import
initPackageDetail
from
'
~/packages/details/
'
;
(
async
function
initPackage
()
{
let
app
;
initPackageDetail
();
if
(
document
.
getElementById
(
'
js-vue-packages-detail-new
'
))
{
app
=
await
import
(
/* webpackChunkName: 'new_package_app' */
`~/packages_and_registries/package_registry/pages/details.js`
);
}
else
{
app
=
await
import
(
'
~/packages/details/
'
);
}
app
.
default
();
})();
app/helpers/packages_helper.rb
View file @
629820f0
...
@@ -63,4 +63,29 @@ module PackagesHelper
...
@@ -63,4 +63,29 @@ module PackagesHelper
project
.
container_expiration_policy
.
nil?
&&
project
.
container_expiration_policy
.
nil?
&&
project
.
container_repositories
.
exists?
project
.
container_repositories
.
exists?
end
end
def
package_details_data
(
project
,
package
=
nil
)
{
package:
package
?
package_from_presenter
(
package
)
:
nil
,
can_delete:
can?
(
current_user
,
:destroy_package
,
project
).
to_s
,
svg_path:
image_path
(
'illustrations/no-packages.svg'
),
npm_path:
package_registry_instance_url
(
:npm
),
npm_help_path:
help_page_path
(
'user/packages/npm_registry/index'
),
maven_path:
package_registry_project_url
(
project
.
id
,
:maven
),
maven_help_path:
help_page_path
(
'user/packages/maven_repository/index'
),
conan_path:
package_registry_project_url
(
project
.
id
,
:conan
),
conan_help_path:
help_page_path
(
'user/packages/conan_repository/index'
),
nuget_path:
nuget_package_registry_url
(
project
.
id
),
nuget_help_path:
help_page_path
(
'user/packages/nuget_repository/index'
),
pypi_path:
pypi_registry_url
(
project
.
id
),
pypi_setup_path:
package_registry_project_url
(
project
.
id
,
:pypi
),
pypi_help_path:
help_page_path
(
'user/packages/pypi_repository/index'
),
composer_path:
composer_registry_url
(
project
&
.
group
&
.
id
),
composer_help_path:
help_page_path
(
'user/packages/composer_repository/index'
),
project_name:
project
.
name
,
project_list_url:
project_packages_path
(
project
),
group_list_url:
project
.
group
?
group_packages_path
(
project
.
group
)
:
''
,
composer_config_repository_name:
composer_config_repository_name
(
project
.
group
&
.
id
)
}
end
end
end
app/views/projects/packages/packages/show.html.haml
View file @
629820f0
...
@@ -6,23 +6,7 @@
...
@@ -6,23 +6,7 @@
.row
.row
.col-12
.col-12
#js-vue-packages-detail
{
data:
{
package:
package_from_presenter
(
@package
),
-
if
Feature
.
enabled?
(
:package_details_apollo
)
can_delete:
can?
(
current_user
,
:destroy_package
,
@project
).
to_s
,
#js-vue-packages-detail-new
{
data:
package_details_data
(
@project
)
}
svg_path:
image_path
(
'illustrations/no-packages.svg'
),
-
else
npm_path:
package_registry_instance_url
(
:npm
),
#js-vue-packages-detail
{
data:
package_details_data
(
@project
,
@package
)
}
npm_help_path:
help_page_path
(
'user/packages/npm_registry/index'
),
maven_path:
package_registry_project_url
(
@project
.
id
,
:maven
),
maven_help_path:
help_page_path
(
'user/packages/maven_repository/index'
),
conan_path:
package_registry_project_url
(
@project
.
id
,
:conan
),
conan_help_path:
help_page_path
(
'user/packages/conan_repository/index'
),
nuget_path:
nuget_package_registry_url
(
@project
.
id
),
nuget_help_path:
help_page_path
(
'user/packages/nuget_repository/index'
),
pypi_path:
pypi_registry_url
(
@project
.
id
),
pypi_setup_path:
package_registry_project_url
(
@project
.
id
,
:pypi
),
pypi_help_path:
help_page_path
(
'user/packages/pypi_repository/index'
),
composer_path:
composer_registry_url
(
@project
&
.
group
&
.
id
),
composer_help_path:
help_page_path
(
'user/packages/composer_repository/index'
),
project_name:
@project
.
name
,
project_list_url:
project_packages_path
(
@project
),
group_list_url:
@project
.
group
?
group_packages_path
(
@project
.
group
)
:
''
,
composer_config_repository_name:
composer_config_repository_name
(
@project
.
group
&
.
id
)}
}
config/feature_flags/development/package_details_apollo.yml
0 → 100644
View file @
629820f0
---
name
:
package_details_apollo
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64939
rollout_issue_url
:
https://gitlab.com/gitlab-org/gitlab/-/issues/334786
milestone
:
'
14.1'
type
:
development
group
:
group::package
default_enabled
:
false
spec/features/groups/packages_spec.rb
View file @
629820f0
...
@@ -44,7 +44,13 @@ RSpec.describe 'Group Packages' do
...
@@ -44,7 +44,13 @@ RSpec.describe 'Group Packages' do
it_behaves_like
'packages list'
,
check_project_name:
true
it_behaves_like
'packages list'
,
check_project_name:
true
context
'when package_details_apollo feature flag is off'
do
before
do
stub_feature_flags
(
package_details_apollo:
false
)
end
it_behaves_like
'package details link'
it_behaves_like
'package details link'
end
it
'allows you to navigate to the project page'
do
it
'allows you to navigate to the project page'
do
find
(
'[data-testid="root-link"]'
,
text:
project
.
name
).
click
find
(
'[data-testid="root-link"]'
,
text:
project
.
name
).
click
...
...
spec/features/projects/package_files_spec.rb
View file @
629820f0
...
@@ -23,6 +23,11 @@ RSpec.describe 'PackageFiles' do
...
@@ -23,6 +23,11 @@ RSpec.describe 'PackageFiles' do
expect
(
status_code
).
to
eq
(
200
)
expect
(
status_code
).
to
eq
(
200
)
end
end
context
'when package_details_apollo feature flag is off'
do
before
do
stub_feature_flags
(
package_details_apollo:
false
)
end
it
'renders the download link with the correct url'
,
:js
do
it
'renders the download link with the correct url'
,
:js
do
visit
project_package_path
(
project
,
package
)
visit
project_package_path
(
project
,
package
)
...
@@ -30,6 +35,7 @@ RSpec.describe 'PackageFiles' do
...
@@ -30,6 +35,7 @@ RSpec.describe 'PackageFiles' do
expect
(
page
).
to
have_link
(
package_file
.
file_name
,
href:
download_url
)
expect
(
page
).
to
have_link
(
package_file
.
file_name
,
href:
download_url
)
end
end
end
it
'does not allow download of package belonging to different project'
do
it
'does not allow download of package belonging to different project'
do
another_package
=
create
(
:maven_package
)
another_package
=
create
(
:maven_package
)
...
...
spec/features/projects/packages_spec.rb
View file @
629820f0
...
@@ -37,7 +37,13 @@ RSpec.describe 'Packages' do
...
@@ -37,7 +37,13 @@ RSpec.describe 'Packages' do
it_behaves_like
'packages list'
it_behaves_like
'packages list'
context
'when package_details_apollo feature flag is off'
do
before
do
stub_feature_flags
(
package_details_apollo:
false
)
end
it_behaves_like
'package details link'
it_behaves_like
'package details link'
end
context
'deleting a package'
do
context
'deleting a package'
do
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:project
)
{
create
(
:project
)
}
...
...
spec/frontend/packages_and_registries/package_registry/components/details/app_spec.js
0 → 100644
View file @
629820f0
import
{
GlEmptyState
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
PackagesApp
from
'
~/packages_and_registries/package_registry/components/details/app.vue
'
;
describe
(
'
PackagesApp
'
,
()
=>
{
let
wrapper
;
function
createComponent
()
{
wrapper
=
shallowMount
(
PackagesApp
,
{
provide
:
{
titleComponent
:
'
titleComponent
'
,
projectName
:
'
projectName
'
,
canDelete
:
'
canDelete
'
,
svgPath
:
'
svgPath
'
,
npmPath
:
'
npmPath
'
,
npmHelpPath
:
'
npmHelpPath
'
,
projectListUrl
:
'
projectListUrl
'
,
groupListUrl
:
'
groupListUrl
'
,
},
});
}
const
emptyState
=
()
=>
wrapper
.
findComponent
(
GlEmptyState
);
afterEach
(()
=>
{
wrapper
.
destroy
();
});
it
(
'
renders an empty state component
'
,
()
=>
{
createComponent
();
expect
(
emptyState
().
exists
()).
toBe
(
true
);
});
});
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