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
6d27b228
Commit
6d27b228
authored
Dec 02, 2021
by
Sheldon Led
Committed by
Brandon Labuschagne
Dec 02, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move project related usage quotas code to a shared folder
parent
fb66f975
Changes
29
Show whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
350 additions
and
335 deletions
+350
-335
ee/app/assets/javascripts/pages/projects/usage_quotas/index.js
...p/assets/javascripts/pages/projects/usage_quotas/index.js
+2
-2
ee/app/assets/javascripts/storage_counter/components/app.vue
ee/app/assets/javascripts/storage_counter/components/app.vue
+3
-3
ee/app/assets/javascripts/storage_counter/components/storage_row.vue
...ts/javascripts/storage_counter/components/storage_row.vue
+0
-34
ee/app/assets/javascripts/storage_counter/constants.js
ee/app/assets/javascripts/storage_counter/constants.js
+0
-2
ee/app/assets/javascripts/usage_quotas/storage/components/collapsible_project_storage_detail.vue
...storage/components/collapsible_project_storage_detail.vue
+23
-60
ee/app/assets/javascripts/usage_quotas/storage/components/project_list.vue
...ascripts/usage_quotas/storage/components/project_list.vue
+17
-16
ee/app/assets/javascripts/usage_quotas/storage/components/project_storage_app.vue
...s/usage_quotas/storage/components/project_storage_app.vue
+6
-6
ee/app/assets/javascripts/usage_quotas/storage/components/project_storage_detail.vue
...sage_quotas/storage/components/project_storage_detail.vue
+8
-4
ee/app/assets/javascripts/usage_quotas/storage/components/projects_skeleton_loader.vue
...ge_quotas/storage/components/projects_skeleton_loader.vue
+0
-0
ee/app/assets/javascripts/usage_quotas/storage/components/storage_type_icon.vue
...pts/usage_quotas/storage/components/storage_type_icon.vue
+0
-0
ee/app/assets/javascripts/usage_quotas/storage/constants.js
ee/app/assets/javascripts/usage_quotas/storage/constants.js
+17
-16
ee/app/assets/javascripts/usage_quotas/storage/init_project_storage.js
.../javascripts/usage_quotas/storage/init_project_storage.js
+2
-2
ee/app/assets/javascripts/usage_quotas/storage/queries/project_storage.query.graphql
...sage_quotas/storage/queries/project_storage.query.graphql
+1
-1
ee/app/assets/javascripts/usage_quotas/storage/utils.js
ee/app/assets/javascripts/usage_quotas/storage/utils.js
+17
-14
ee/spec/frontend/fixtures/projects.rb
ee/spec/frontend/fixtures/projects.rb
+43
-0
ee/spec/frontend/storage_counter/components/app_spec.js
ee/spec/frontend/storage_counter/components/app_spec.js
+9
-9
ee/spec/frontend/storage_counter/components/storage_row_spec.js
...c/frontend/storage_counter/components/storage_row_spec.js
+0
-32
ee/spec/frontend/storage_counter/mock_data.js
ee/spec/frontend/storage_counter/mock_data.js
+1
-59
ee/spec/frontend/storage_counter/utils_spec.js
ee/spec/frontend/storage_counter/utils_spec.js
+2
-1
ee/spec/frontend/usage_quotas/storage/components/collapsible_project_storage_detail_spec.js
...age/components/collapsible_project_storage_detail_spec.js
+9
-9
ee/spec/frontend/usage_quotas/storage/components/project_list_spec.js
...tend/usage_quotas/storage/components/project_list_spec.js
+5
-5
ee/spec/frontend/usage_quotas/storage/components/project_storage_app_spec.js
...age_quotas/storage/components/project_storage_app_spec.js
+14
-14
ee/spec/frontend/usage_quotas/storage/components/project_storage_detail_spec.js
..._quotas/storage/components/project_storage_detail_spec.js
+5
-5
ee/spec/frontend/usage_quotas/storage/components/projects_skeleton_loader_spec.js
...uotas/storage/components/projects_skeleton_loader_spec.js
+1
-1
ee/spec/frontend/usage_quotas/storage/components/storage_type_icon_spec.js
...usage_quotas/storage/components/storage_type_icon_spec.js
+1
-1
ee/spec/frontend/usage_quotas/storage/mock_data.js
ee/spec/frontend/usage_quotas/storage/mock_data.js
+154
-0
ee/spec/frontend/usage_quotas/storage/utils_spec.js
ee/spec/frontend/usage_quotas/storage/utils_spec.js
+10
-7
locale/gitlab.pot
locale/gitlab.pot
+0
-6
spec/frontend/fixtures/projects.rb
spec/frontend/fixtures/projects.rb
+0
-26
No files found.
app/assets/javascripts/pages/projects/usage_quotas/index.js
→
ee/
app/assets/javascripts/pages/projects/usage_quotas/index.js
View file @
6d27b228
import
LinkedTabs
from
'
~/lib/utils/bootstrap_linked_tabs
'
;
import
LinkedTabs
from
'
~/lib/utils/bootstrap_linked_tabs
'
;
import
storageCounter
from
'
~/projects/storage_counter
'
;
import
initProjectStorage
from
'
ee/usage_quotas/storage/init_project_storage
'
;
import
initSearchSettings
from
'
~/search_settings
'
;
import
initSearchSettings
from
'
~/search_settings
'
;
const
initLinkedTabs
=
()
=>
{
const
initLinkedTabs
=
()
=>
{
...
@@ -15,7 +15,7 @@ const initLinkedTabs = () => {
...
@@ -15,7 +15,7 @@ const initLinkedTabs = () => {
};
};
const
initVueApp
=
()
=>
{
const
initVueApp
=
()
=>
{
storageCounter
(
'
js-project-storage-count-app
'
);
initProjectStorage
(
'
js-project-storage-count-app
'
);
};
};
initVueApp
();
initVueApp
();
...
...
ee/app/assets/javascripts/storage_counter/components/app.vue
View file @
6d27b228
...
@@ -10,10 +10,10 @@ import {
...
@@ -10,10 +10,10 @@ import {
import
{
parseBoolean
}
from
'
~/lib/utils/common_utils
'
;
import
{
parseBoolean
}
from
'
~/lib/utils/common_utils
'
;
import
UsageGraph
from
'
~/vue_shared/components/storage_counter/usage_graph.vue
'
;
import
UsageGraph
from
'
~/vue_shared/components/storage_counter/usage_graph.vue
'
;
import
glFeatureFlagsMixin
from
'
~/vue_shared/mixins/gl_feature_flags_mixin
'
;
import
glFeatureFlagsMixin
from
'
~/vue_shared/mixins/gl_feature_flags_mixin
'
;
import
ProjectList
from
'
ee/usage_quotas/storage/components/project_list.vue
'
;
import
{
PROJECTS_PER_PAGE
}
from
'
../constants
'
;
import
{
PROJECTS_PER_PAGE
}
from
'
../constants
'
;
import
query
from
'
../queries/storage.query.graphql
'
;
import
query
from
'
../queries/storage.query.graphql
'
;
import
{
formatUsageSize
,
parseGetStorageResults
}
from
'
../utils
'
;
import
{
formatUsageSize
,
parseGetStorageResults
}
from
'
../utils
'
;
import
ProjectsTable
from
'
./projects_table.vue
'
;
import
StorageInlineAlert
from
'
./storage_inline_alert.vue
'
;
import
StorageInlineAlert
from
'
./storage_inline_alert.vue
'
;
import
TemporaryStorageIncreaseModal
from
'
./temporary_storage_increase_modal.vue
'
;
import
TemporaryStorageIncreaseModal
from
'
./temporary_storage_increase_modal.vue
'
;
import
UsageStatistics
from
'
./usage_statistics.vue
'
;
import
UsageStatistics
from
'
./usage_statistics.vue
'
;
...
@@ -26,7 +26,7 @@ export default {
...
@@ -26,7 +26,7 @@ export default {
GlButton
,
GlButton
,
GlSprintf
,
GlSprintf
,
UsageGraph
,
UsageGraph
,
Project
sTable
,
Project
List
,
UsageStatistics
,
UsageStatistics
,
StorageInlineAlert
,
StorageInlineAlert
,
GlKeysetPagination
,
GlKeysetPagination
,
...
@@ -230,7 +230,7 @@ export default {
...
@@ -230,7 +230,7 @@ export default {
/>
/>
</div>
</div>
</div>
</div>
<project
s-table
<project
-list
:projects=
"namespaceProjects"
:projects=
"namespaceProjects"
:is-loading=
"isQueryLoading"
:is-loading=
"isQueryLoading"
:additional-purchased-storage-size=
"namespace.additionalPurchasedStorageSize || 0"
:additional-purchased-storage-size=
"namespace.additionalPurchasedStorageSize || 0"
...
...
ee/app/assets/javascripts/storage_counter/components/storage_row.vue
deleted
100644 → 0
View file @
fb66f975
<
script
>
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_utils
'
;
export
default
{
props
:
{
name
:
{
type
:
String
,
required
:
true
,
},
value
:
{
type
:
Number
,
required
:
true
,
},
},
computed
:
{
formattedValue
()
{
return
numberToHumanSize
(
this
.
value
);
},
},
};
</
script
>
<
template
>
<div
class=
"gl-responsive-table-row gl-line-height-normal"
role=
"row"
>
<div
class=
"table-section section-wrap section-70 text-truncate pl-2 ml-3"
role=
"gridcell"
>
<div
class=
"table-mobile-header"
role=
"rowheader"
></div>
<div
class=
"table-mobile-content ml-1"
>
{{
name
}}
</div>
</div>
<div
class=
"table-section section-wrap section-30 text-truncate"
role=
"gridcell"
>
<div
class=
"table-mobile-header"
role=
"rowheader"
></div>
<div
class=
"table-mobile-content"
>
{{
formattedValue
}}
</div>
</div>
</div>
</
template
>
ee/app/assets/javascripts/storage_counter/constants.js
View file @
6d27b228
...
@@ -13,5 +13,3 @@ export const STORAGE_USAGE_THRESHOLDS = {
...
@@ -13,5 +13,3 @@ export const STORAGE_USAGE_THRESHOLDS = {
};
};
export
const
PROJECTS_PER_PAGE
=
20
;
export
const
PROJECTS_PER_PAGE
=
20
;
export
const
SKELETON_LOADER_ROWS
=
5
;
ee/app/assets/javascripts/
storage_counter/components/project
.vue
→
ee/app/assets/javascripts/
usage_quotas/storage/components/collapsible_project_storage_detail
.vue
View file @
6d27b228
<
script
>
<
script
>
import
{
GlLink
,
GlIcon
}
from
'
@gitlab/ui
'
;
import
{
GlLink
,
GlIcon
}
from
'
@gitlab/ui
'
;
import
{
getIdFromGraphQLId
}
from
'
~/graphql_shared/
utils
'
;
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_
utils
'
;
import
{
numberToHumanSize
,
isOdd
}
from
'
~/lib/utils/number_utils
'
;
import
ProjectAvatar
from
'
~/vue_shared/components/project_avatar.vue
'
;
import
{
s__
}
from
'
~/locale
'
;
import
{
getStorageTypesFromProjectStatistics
}
from
'
../utils
'
;
import
ProjectAvatar
from
'
~/vue_shared/components/deprecated_project_avatar/default.vue
'
;
import
{
PROJECT_TABLE_LABEL_PROJECT
,
PROJECT_TABLE_LABEL_USAGE
}
from
'
../constants
'
;
import
StorageRow
from
'
./storage_row
.vue
'
;
import
ProjectStorageDetail
from
'
./project_storage_detail
.vue
'
;
export
default
{
export
default
{
name
:
'
CollapsibleProjectStorageDetail
'
,
components
:
{
components
:
{
GlIcon
,
GlIcon
,
GlLink
,
GlLink
,
ProjectAvatar
,
ProjectAvatar
,
StorageRow
,
ProjectStorageDetail
,
},
},
props
:
{
props
:
{
project
:
{
project
:
{
...
@@ -25,15 +26,6 @@ export default {
...
@@ -25,15 +26,6 @@ export default {
};
};
},
},
computed
:
{
computed
:
{
projectAvatar
()
{
const
{
name
,
id
,
avatarUrl
,
webUrl
}
=
this
.
project
;
return
{
name
,
id
:
Number
(
getIdFromGraphQLId
(
id
)),
avatar_url
:
avatarUrl
,
path
:
webUrl
,
};
},
name
()
{
name
()
{
return
this
.
project
.
nameWithNamespace
;
return
this
.
project
.
nameWithNamespace
;
},
},
...
@@ -43,14 +35,8 @@ export default {
...
@@ -43,14 +35,8 @@ export default {
iconName
()
{
iconName
()
{
return
this
.
isOpen
?
'
angle-down
'
:
'
angle-right
'
;
return
this
.
isOpen
?
'
angle-down
'
:
'
angle-right
'
;
},
},
statistics
()
{
projectStorageTypes
()
{
const
statisticsCopy
=
{
...
this
.
project
.
statistics
};
return
getStorageTypesFromProjectStatistics
(
this
.
project
.
statistics
);
delete
statisticsCopy
.
storageSize
;
// eslint-disable-next-line no-underscore-dangle
delete
statisticsCopy
.
__typename
;
delete
statisticsCopy
.
commitCount
;
return
statisticsCopy
;
},
},
},
},
methods
:
{
methods
:
{
...
@@ -63,28 +49,10 @@ export default {
...
@@ -63,28 +49,10 @@ export default {
}
}
this
.
isOpen
=
!
this
.
isOpen
;
this
.
isOpen
=
!
this
.
isOpen
;
},
},
getFormattedName
(
name
)
{
return
this
.
$options
.
i18nStatisticsMap
[
name
];
},
isOdd
(
num
)
{
return
isOdd
(
num
);
},
/**
* Some values can be `nil`
* for those, we send 0 instead
*/
getValue
(
val
)
{
return
val
||
0
;
},
},
},
i18n
:
{
i18nStatisticsMap
:
{
PROJECT_TABLE_LABEL_PROJECT
,
repositorySize
:
s__
(
'
UsageQuota|Repository
'
),
PROJECT_TABLE_LABEL_USAGE
,
lfsObjectsSize
:
s__
(
'
UsageQuota|LFS Storage
'
),
buildArtifactsSize
:
s__
(
'
UsageQuota|Artifacts
'
),
packagesSize
:
s__
(
'
UsageQuota|Packages
'
),
wikiSize
:
s__
(
'
UsageQuota|Wiki
'
),
snippetsSize
:
s__
(
'
UsageQuota|Snippets
'
),
uploadsSize
:
s__
(
'
UsageQuota|Uploads
'
),
},
},
};
};
</
script
>
</
script
>
...
@@ -101,16 +69,20 @@ export default {
...
@@ -101,16 +69,20 @@ export default {
role=
"gridcell"
role=
"gridcell"
>
>
<div
class=
"table-mobile-header gl-font-weight-bold"
role=
"rowheader"
>
<div
class=
"table-mobile-header gl-font-weight-bold"
role=
"rowheader"
>
{{
__
(
'
Project
'
)
}}
{{
$options
.
i18n
.
PROJECT_TABLE_LABEL_PROJECT
}}
</div>
</div>
<div
class=
"table-mobile-content gl-display-flex gl-align-items-center"
>
<div
class=
"table-mobile-content gl-display-flex gl-align-items-center"
>
<div
class=
"gl-display-flex gl-mr-3 gl-align-items-center"
>
<div
class=
"gl-display-flex gl-mr-3 gl-align-items-center"
>
<gl-icon
:size=
"12"
:name=
"iconName"
class=
"gl-mr-2"
/>
<gl-icon
:size=
"12"
:name=
"iconName"
/>
<gl-icon
name=
"bookmark"
/>
<gl-icon
name=
"bookmark"
/>
</div>
</div>
<div>
<project-avatar
<project-avatar
:project=
"projectAvatar"
:size=
"32"
/>
:project-name=
"project.name"
</div>
:project-avatar-url=
"project.avatarUrl"
:size=
"32"
:alt=
"project.name"
class=
"gl-mr-3"
/>
<gl-link
<gl-link
:href=
"project.webUrl"
:href=
"project.webUrl"
class=
"js-project-link gl-font-weight-bold gl-text-gray-900!"
class=
"js-project-link gl-font-weight-bold gl-text-gray-900!"
...
@@ -123,20 +95,11 @@ export default {
...
@@ -123,20 +95,11 @@ export default {
role=
"gridcell"
role=
"gridcell"
>
>
<div
class=
"table-mobile-header gl-font-weight-bold"
role=
"rowheader"
>
<div
class=
"table-mobile-header gl-font-weight-bold"
role=
"rowheader"
>
{{
__
(
'
Usage
'
)
}}
{{
$options
.
i18n
.
PROJECT_TABLE_LABEL_USAGE
}}
</div>
</div>
<div
class=
"table-mobile-content gl-text-gray-900"
>
{{
storageSize
}}
</div>
<div
class=
"table-mobile-content gl-text-gray-900"
>
{{
storageSize
}}
</div>
</div>
</div>
</div>
</div>
<project-storage-detail
v-if=
"isOpen"
:storage-types=
"projectStorageTypes"
/>
<template
v-if=
"isOpen"
>
<storage-row
v-for=
"(value, statisticsName, index) in statistics"
:key=
"index"
:name=
"getFormattedName(statisticsName)"
:value=
"getValue(value)"
:class=
"
{ 'gl-bg-gray-10': isOdd(index) }"
/>
</
template
>
</div>
</div>
</
template
>
</
template
>
ee/app/assets/javascripts/
storage_counter/components/projects_table
.vue
→
ee/app/assets/javascripts/
usage_quotas/storage/components/project_list
.vue
View file @
6d27b228
<
script
>
<
script
>
import
{
SEARCH_DEBOUNCE_MS
}
from
'
~/ref/constants
'
;
import
{
PROJECT_TABLE_LABEL_PROJECT
,
PROJECT_TABLE_LABEL_USAGE
}
from
'
../constants
'
;
import
glFeatureFlagsMixin
from
'
~/vue_shared/mixins/gl_feature_flags_mixin
'
;
import
CollapsibleProjectStorageDetail
from
'
./collapsible_project_storage_detail.vue
'
;
import
Project
from
'
./project.vue
'
;
import
ProjectsSkeletonLoader
from
'
./projects_skeleton_loader.vue
'
;
import
ProjectsSkeletonLoader
from
'
./projects_skeleton_loader.vue
'
;
export
default
{
export
default
{
name
:
'
ProjectList
'
,
components
:
{
components
:
{
Project
,
CollapsibleProjectStorageDetail
,
ProjectsSkeletonLoader
,
ProjectsSkeletonLoader
,
},
},
mixins
:
[
glFeatureFlagsMixin
()],
props
:
{
props
:
{
projects
:
{
projects
:
{
type
:
Array
,
type
:
Array
,
...
@@ -25,7 +24,10 @@ export default {
...
@@ -25,7 +24,10 @@ export default {
default
:
false
,
default
:
false
,
},
},
},
},
searchDebounceValue
:
SEARCH_DEBOUNCE_MS
,
i18n
:
{
PROJECT_TABLE_LABEL_PROJECT
,
PROJECT_TABLE_LABEL_USAGE
,
},
};
};
</
script
>
</
script
>
...
@@ -36,20 +38,19 @@ export default {
...
@@ -36,20 +38,19 @@ export default {
role=
"row"
role=
"row"
>
>
<div
class=
"table-section section-70 gl-font-weight-bold"
role=
"columnheader"
>
<div
class=
"table-section section-70 gl-font-weight-bold"
role=
"columnheader"
>
{{
__
(
'
Project
'
)
}}
{{
$options
.
i18n
.
PROJECT_TABLE_LABEL_PROJECT
}}
</div>
</div>
<div
class=
"table-section section-30 gl-font-weight-bold"
role=
"columnheader"
>
<div
class=
"table-section section-30 gl-font-weight-bold"
role=
"columnheader"
>
{{
__
(
'
Usage
'
)
}}
{{
$options
.
i18n
.
PROJECT_TABLE_LABEL_USAGE
}}
</div>
</div>
</div>
</div>
<projects-skeleton-loader
v-if=
"isLoading"
/>
<projects-skeleton-loader
v-if=
"isLoading"
/>
<template
v-else
>
<collapsible-project-storage-detail
<project
v-for=
"project in projects"
v-for=
"project in projects"
v-else
:key=
"project.id"
:key=
"project.id"
:project=
"project"
:project=
"project"
:additional-purchased-storage-size=
"additionalPurchasedStorageSize"
:additional-purchased-storage-size=
"additionalPurchasedStorageSize"
/>
/>
</
template
>
</div>
</div>
</
template
>
</
template
>
app/assets/javascripts/projects/storage_counter/components/
app.vue
→
ee/app/assets/javascripts/usage_quotas/storage/components/project_storage_
app.vue
View file @
6d27b228
...
@@ -11,23 +11,23 @@ import {
...
@@ -11,23 +11,23 @@ import {
TOTAL_USAGE_DEFAULT_TEXT
,
TOTAL_USAGE_DEFAULT_TEXT
,
HELP_LINK_ARIA_LABEL
,
HELP_LINK_ARIA_LABEL
,
}
from
'
../constants
'
;
}
from
'
../constants
'
;
import
getProjectStorage
Count
from
'
../queries/project_storage.query.graphql
'
;
import
getProjectStorage
Statistics
from
'
../queries/project_storage.query.graphql
'
;
import
{
parseGetProjectStorageResults
}
from
'
../utils
'
;
import
{
parseGetProjectStorageResults
}
from
'
../utils
'
;
import
StorageTable
from
'
./storage_table
.vue
'
;
import
ProjectStorageDetail
from
'
./project_storage_detail
.vue
'
;
export
default
{
export
default
{
name
:
'
StorageCounter
App
'
,
name
:
'
ProjectStorage
App
'
,
components
:
{
components
:
{
GlAlert
,
GlAlert
,
GlLink
,
GlLink
,
GlLoadingIcon
,
GlLoadingIcon
,
StorageTable
,
UsageGraph
,
UsageGraph
,
ProjectStorageDetail
,
},
},
inject
:
[
'
projectPath
'
,
'
helpLinks
'
],
inject
:
[
'
projectPath
'
,
'
helpLinks
'
],
apollo
:
{
apollo
:
{
project
:
{
project
:
{
query
:
getProjectStorage
Count
,
query
:
getProjectStorage
Statistics
,
variables
()
{
variables
()
{
return
{
return
{
fullPath
:
this
.
projectPath
,
fullPath
:
this
.
projectPath
,
...
@@ -101,6 +101,6 @@ export default {
...
@@ -101,6 +101,6 @@ export default {
<div
v-if=
"project.statistics"
class=
"gl-w-full"
>
<div
v-if=
"project.statistics"
class=
"gl-w-full"
>
<usage-graph
:root-storage-statistics=
"project.statistics"
:limit=
"0"
/>
<usage-graph
:root-storage-statistics=
"project.statistics"
:limit=
"0"
/>
</div>
</div>
<
storage-table
:storage-types=
"storageTypes"
/>
<
project-storage-detail
:storage-types=
"storageTypes"
/>
</div>
</div>
</
template
>
</
template
>
app/assets/javascripts/projects/storage_counter/components/storage_table
.vue
→
ee/app/assets/javascripts/usage_quotas/storage/components/project_storage_detail
.vue
View file @
6d27b228
...
@@ -3,11 +3,15 @@ import { GlLink, GlIcon, GlTableLite as GlTable, GlSprintf } from '@gitlab/ui';
...
@@ -3,11 +3,15 @@ import { GlLink, GlIcon, GlTableLite as GlTable, GlSprintf } from '@gitlab/ui';
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_utils
'
;
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_utils
'
;
import
{
thWidthClass
}
from
'
~/lib/utils/table_utility
'
;
import
{
thWidthClass
}
from
'
~/lib/utils/table_utility
'
;
import
{
sprintf
}
from
'
~/locale
'
;
import
{
sprintf
}
from
'
~/locale
'
;
import
{
PROJECT_TABLE_LABELS
,
HELP_LINK_ARIA_LABEL
}
from
'
../constants
'
;
import
{
PROJECT_TABLE_LABEL_STORAGE_TYPE
,
PROJECT_TABLE_LABEL_USAGE
,
HELP_LINK_ARIA_LABEL
,
}
from
'
../constants
'
;
import
StorageTypeIcon
from
'
./storage_type_icon.vue
'
;
import
StorageTypeIcon
from
'
./storage_type_icon.vue
'
;
export
default
{
export
default
{
name
:
'
StorageTable
'
,
name
:
'
ProjectStorageDetail
'
,
components
:
{
components
:
{
GlLink
,
GlLink
,
GlIcon
,
GlIcon
,
...
@@ -31,13 +35,13 @@ export default {
...
@@ -31,13 +35,13 @@ export default {
projectTableFields
:
[
projectTableFields
:
[
{
{
key
:
'
storageType
'
,
key
:
'
storageType
'
,
label
:
PROJECT_TABLE_LABEL
S
.
STORAGE_TYPE
,
label
:
PROJECT_TABLE_LABEL
_
STORAGE_TYPE
,
thClass
:
thWidthClass
(
90
),
thClass
:
thWidthClass
(
90
),
sortable
:
true
,
sortable
:
true
,
},
},
{
{
key
:
'
value
'
,
key
:
'
value
'
,
label
:
PROJECT_TABLE_LABEL
S
.
VALU
E
,
label
:
PROJECT_TABLE_LABEL
_USAG
E
,
thClass
:
thWidthClass
(
10
),
thClass
:
thWidthClass
(
10
),
sortable
:
true
,
sortable
:
true
,
formatter
:
(
value
)
=>
{
formatter
:
(
value
)
=>
{
...
...
ee/app/assets/javascripts/
storage_counter
/components/projects_skeleton_loader.vue
→
ee/app/assets/javascripts/
usage_quotas/storage
/components/projects_skeleton_loader.vue
View file @
6d27b228
File moved
app/assets/javascripts/projects/storage_counter
/components/storage_type_icon.vue
→
ee/app/assets/javascripts/usage_quotas/storage
/components/storage_type_icon.vue
View file @
6d27b228
File moved
app/assets/javascripts/projects/storage_counter
/constants.js
→
ee/app/assets/javascripts/usage_quotas/storage
/constants.js
View file @
6d27b228
import
{
s__
,
__
}
from
'
~/locale
'
;
import
{
s__
,
__
}
from
'
~/locale
'
;
export
const
ERROR_MESSAGE
=
s__
(
'
UsageQuota|Something went wrong while fetching project storage statistics
'
,
);
export
const
LEARN_MORE_LABEL
=
__
(
'
Learn more.
'
);
export
const
USAGE_QUOTAS_LABEL
=
s__
(
'
UsageQuota|Usage Quotas
'
);
export
const
HELP_LINK_ARIA_LABEL
=
s__
(
'
UsageQuota|%{linkTitle} help link
'
);
export
const
TOTAL_USAGE_DEFAULT_TEXT
=
__
(
'
N/A
'
);
export
const
TOTAL_USAGE_TITLE
=
s__
(
'
UsageQuota|Usage breakdown
'
);
export
const
TOTAL_USAGE_SUBTITLE
=
s__
(
'
UsageQuota|Includes artifacts, repositories, wiki, uploads, and other items.
'
,
);
export
const
PROJECT_STORAGE_TYPES
=
[
export
const
PROJECT_STORAGE_TYPES
=
[
{
{
id
:
'
buildArtifactsSize
'
,
id
:
'
buildArtifactsSize
'
,
...
@@ -42,20 +55,8 @@ export const PROJECT_STORAGE_TYPES = [
...
@@ -42,20 +55,8 @@ export const PROJECT_STORAGE_TYPES = [
},
},
];
];
export
const
PROJECT_TABLE_LABELS
=
{
export
const
PROJECT_TABLE_LABEL_PROJECT
=
__
(
'
Project
'
);
STORAGE_TYPE
:
s__
(
'
UsageQuota|Storage type
'
),
export
const
PROJECT_TABLE_LABEL_STORAGE_TYPE
=
s__
(
'
UsageQuota|Storage type
'
);
VALUE
:
s__
(
'
UsageQuota|Usage
'
),
export
const
PROJECT_TABLE_LABEL_USAGE
=
s__
(
'
UsageQuota|Usage
'
);
};
export
const
ERROR_MESSAGE
=
s__
(
export
const
SKELETON_LOADER_ROWS
=
5
;
'
UsageQuota|Something went wrong while fetching project storage statistics
'
,
);
export
const
LEARN_MORE_LABEL
=
__
(
'
Learn more.
'
);
export
const
USAGE_QUOTAS_LABEL
=
s__
(
'
UsageQuota|Usage Quotas
'
);
export
const
HELP_LINK_ARIA_LABEL
=
s__
(
'
UsageQuota|%{linkTitle} help link
'
);
export
const
TOTAL_USAGE_DEFAULT_TEXT
=
__
(
'
N/A
'
);
export
const
TOTAL_USAGE_TITLE
=
s__
(
'
UsageQuota|Usage breakdown
'
);
export
const
TOTAL_USAGE_SUBTITLE
=
s__
(
'
UsageQuota|Includes artifacts, repositories, wiki, uploads, and other items.
'
,
);
app/assets/javascripts/projects/storage_counter/index
.js
→
ee/app/assets/javascripts/usage_quotas/storage/init_project_storage
.js
View file @
6d27b228
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
createDefaultClient
from
'
~/lib/graphql
'
;
import
createDefaultClient
from
'
~/lib/graphql
'
;
import
StorageCounterApp
from
'
./components/
app.vue
'
;
import
ProjectStorageApp
from
'
./components/project_storage_
app.vue
'
;
Vue
.
use
(
VueApollo
);
Vue
.
use
(
VueApollo
);
...
@@ -45,7 +45,7 @@ export default (containerId = 'js-project-storage-count-app') => {
...
@@ -45,7 +45,7 @@ export default (containerId = 'js-project-storage-count-app') => {
},
},
},
},
render
(
createElement
)
{
render
(
createElement
)
{
return
createElement
(
StorageCounter
App
);
return
createElement
(
ProjectStorage
App
);
},
},
});
});
};
};
app/assets/javascripts/projects/storage_counter
/queries/project_storage.query.graphql
→
ee/app/assets/javascripts/usage_quotas/storage
/queries/project_storage.query.graphql
View file @
6d27b228
query
getProjectStorage
Count
(
$fullPath
:
ID
!)
{
query
getProjectStorage
Statistics
(
$fullPath
:
ID
!)
{
project
(
fullPath
:
$fullPath
)
{
project
(
fullPath
:
$fullPath
)
{
id
id
statistics
{
statistics
{
...
...
app/assets/javascripts/projects/storage_counter
/utils.js
→
ee/app/assets/javascripts/usage_quotas/storage
/utils.js
View file @
6d27b228
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_utils
'
;
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_utils
'
;
import
{
PROJECT_STORAGE_TYPES
}
from
'
./constants
'
;
import
{
PROJECT_STORAGE_TYPES
}
from
'
./constants
'
;
/**
export
const
getStorageTypesFromProjectStatistics
=
(
projectStatistics
,
helpLinks
=
{})
=>
* This method parses the results from `getProjectStorageCount` call.
PROJECT_STORAGE_TYPES
.
reduce
((
types
,
currentType
)
=>
{
*
* @param {Object} data graphql result
* @returns {Object}
*/
export
const
parseGetProjectStorageResults
=
(
data
,
helpLinks
)
=>
{
const
projectStatistics
=
data
?.
project
?.
statistics
;
if
(
!
projectStatistics
)
{
return
{};
}
const
{
storageSize
,
...
storageStatistics
}
=
projectStatistics
;
const
storageTypes
=
PROJECT_STORAGE_TYPES
.
reduce
((
types
,
currentType
)
=>
{
const
helpPathKey
=
currentType
.
id
.
replace
(
`Size`
,
`HelpPagePath`
);
const
helpPathKey
=
currentType
.
id
.
replace
(
`Size`
,
`HelpPagePath`
);
const
helpPath
=
helpLinks
[
helpPathKey
];
const
helpPath
=
helpLinks
[
helpPathKey
];
...
@@ -22,10 +11,24 @@ export const parseGetProjectStorageResults = (data, helpLinks) => {
...
@@ -22,10 +11,24 @@ export const parseGetProjectStorageResults = (data, helpLinks) => {
...
currentType
,
...
currentType
,
helpPath
,
helpPath
,
},
},
value
:
storage
Statistics
[
currentType
.
id
],
value
:
project
Statistics
[
currentType
.
id
],
});
});
},
[]);
},
[]);
/**
* This method parses the results from `getProjectStorageStatistics` call.
*
* @param {Object} data graphql result
* @returns {Object}
*/
export
const
parseGetProjectStorageResults
=
(
data
,
helpLinks
)
=>
{
const
projectStatistics
=
data
?.
project
?.
statistics
;
if
(
!
projectStatistics
)
{
return
{};
}
const
{
storageSize
}
=
projectStatistics
;
const
storageTypes
=
getStorageTypesFromProjectStatistics
(
projectStatistics
,
helpLinks
);
return
{
return
{
storage
:
{
storage
:
{
totalUsage
:
numberToHumanSize
(
storageSize
,
1
),
totalUsage
:
numberToHumanSize
(
storageSize
,
1
),
...
...
ee/spec/frontend/fixtures/projects.rb
0 → 100644
View file @
6d27b228
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
'Projects (JavaScript fixtures)'
,
type: :controller
do
include
ApiHelpers
include
JavaScriptFixturesHelpers
runners_token
=
'runnerstoken:intabulasreferre'
let
(
:namespace
)
{
create
(
:namespace
,
name:
'frontend-fixtures'
)}
let
(
:project
)
{
create
(
:project
,
namespace:
namespace
,
path:
'builds-project'
,
runners_token:
runners_token
,
avatar:
fixture_file_upload
(
'spec/fixtures/dk.png'
,
'image/png'
))
}
let
(
:user
)
{
project
.
owner
}
describe
GraphQL
::
Query
,
type: :request
do
include
GraphqlHelpers
context
'project storage statistics query'
do
before
do
project
.
statistics
.
update!
(
repository_size:
3900000
,
lfs_objects_size:
4800000
,
build_artifacts_size:
400000
,
pipeline_artifacts_size:
400000
,
wiki_size:
300000
,
packages_size:
3800000
,
uploads_size:
900000
)
end
base_input_path
=
'usage_quotas/storage/queries/'
base_output_path
=
'graphql/usage_quotas/storage/'
query_name
=
'project_storage.query.graphql'
it
"
#{
base_output_path
}#{
query_name
}
.json"
do
query
=
get_graphql_query_as_string
(
"
#{
base_input_path
}#{
query_name
}
"
,
ee:
true
)
post_graphql
(
query
,
current_user:
user
,
variables:
{
fullPath:
project
.
full_path
})
expect_graphql_errors_to_be_empty
end
end
end
end
ee/spec/frontend/storage_counter/components/app_spec.js
View file @
6d27b228
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
StorageApp
from
'
ee/storage_counter/components/app.vue
'
;
import
StorageApp
from
'
ee/storage_counter/components/app.vue
'
;
import
Project
from
'
ee/storage_counter/components/project
.vue
'
;
import
CollapsibleProjectStorageDetail
from
'
ee/usage_quotas/storage/components/collapsible_project_storage_detail
.vue
'
;
import
Project
sTable
from
'
ee/storage_counter/components/projects_table
.vue
'
;
import
Project
List
from
'
ee/usage_quotas/storage/components/project_list
.vue
'
;
import
StorageInlineAlert
from
'
ee/storage_counter/components/storage_inline_alert.vue
'
;
import
StorageInlineAlert
from
'
ee/storage_counter/components/storage_inline_alert.vue
'
;
import
TemporaryStorageIncreaseModal
from
'
ee/storage_counter/components/temporary_storage_increase_modal.vue
'
;
import
TemporaryStorageIncreaseModal
from
'
ee/storage_counter/components/temporary_storage_increase_modal.vue
'
;
import
UsageStatistics
from
'
ee/storage_counter/components/usage_statistics.vue
'
;
import
UsageStatistics
from
'
ee/storage_counter/components/usage_statistics.vue
'
;
...
@@ -22,7 +22,7 @@ describe('Storage counter app', () => {
...
@@ -22,7 +22,7 @@ describe('Storage counter app', () => {
const
findUsageGraph
=
()
=>
wrapper
.
find
(
UsageGraph
);
const
findUsageGraph
=
()
=>
wrapper
.
find
(
UsageGraph
);
const
findUsageStatistics
=
()
=>
wrapper
.
find
(
UsageStatistics
);
const
findUsageStatistics
=
()
=>
wrapper
.
find
(
UsageStatistics
);
const
findStorageInlineAlert
=
()
=>
wrapper
.
find
(
StorageInlineAlert
);
const
findStorageInlineAlert
=
()
=>
wrapper
.
find
(
StorageInlineAlert
);
const
findProject
sTable
=
()
=>
wrapper
.
find
(
ProjectsTable
);
const
findProject
List
=
()
=>
wrapper
.
find
(
ProjectList
);
const
findPrevButton
=
()
=>
wrapper
.
find
(
'
[data-testid="prevButton"]
'
);
const
findPrevButton
=
()
=>
wrapper
.
find
(
'
[data-testid="prevButton"]
'
);
const
findNextButton
=
()
=>
wrapper
.
find
(
'
[data-testid="nextButton"]
'
);
const
findNextButton
=
()
=>
wrapper
.
find
(
'
[data-testid="nextButton"]
'
);
...
@@ -74,7 +74,7 @@ describe('Storage counter app', () => {
...
@@ -74,7 +74,7 @@ describe('Storage counter app', () => {
await
wrapper
.
vm
.
$nextTick
();
await
wrapper
.
vm
.
$nextTick
();
expect
(
wrapper
.
findAll
(
Project
)).
toHaveLength
(
3
);
expect
(
wrapper
.
findAll
(
CollapsibleProjectStorageDetail
)).
toHaveLength
(
3
);
});
});
describe
(
'
limit
'
,
()
=>
{
describe
(
'
limit
'
,
()
=>
{
...
@@ -232,21 +232,21 @@ describe('Storage counter app', () => {
...
@@ -232,21 +232,21 @@ describe('Storage counter app', () => {
it
(
'
triggers search if user enters search input
'
,
()
=>
{
it
(
'
triggers search if user enters search input
'
,
()
=>
{
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
''
);
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
''
);
findProject
sTable
().
vm
.
$emit
(
'
search
'
,
sampleSearchTerm
);
findProject
List
().
vm
.
$emit
(
'
search
'
,
sampleSearchTerm
);
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
sampleSearchTerm
);
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
sampleSearchTerm
);
});
});
it
(
'
triggers search if user clears the entered search input
'
,
()
=>
{
it
(
'
triggers search if user clears the entered search input
'
,
()
=>
{
const
project
sTable
=
findProjectsTable
();
const
project
List
=
findProjectList
();
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
''
);
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
''
);
project
sTable
.
vm
.
$emit
(
'
search
'
,
sampleSearchTerm
);
project
List
.
vm
.
$emit
(
'
search
'
,
sampleSearchTerm
);
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
sampleSearchTerm
);
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
sampleSearchTerm
);
project
sTable
.
vm
.
$emit
(
'
search
'
,
''
);
project
List
.
vm
.
$emit
(
'
search
'
,
''
);
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
''
);
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
''
);
});
});
...
@@ -254,7 +254,7 @@ describe('Storage counter app', () => {
...
@@ -254,7 +254,7 @@ describe('Storage counter app', () => {
it
(
'
does not trigger search if user enters short search input
'
,
()
=>
{
it
(
'
does not trigger search if user enters short search input
'
,
()
=>
{
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
''
);
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
''
);
findProject
sTable
().
vm
.
$emit
(
'
search
'
,
sampleShortSearchTerm
);
findProject
List
().
vm
.
$emit
(
'
search
'
,
sampleShortSearchTerm
);
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
''
);
expect
(
wrapper
.
vm
.
searchTerm
).
toBe
(
''
);
});
});
...
...
ee/spec/frontend/storage_counter/components/storage_row_spec.js
deleted
100644 → 0
View file @
fb66f975
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
StorageRow
from
'
ee/storage_counter/components/storage_row.vue
'
;
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_utils
'
;
let
wrapper
;
const
data
=
{
name
:
'
LFS Package
'
,
value
:
1293346
,
};
function
factory
({
name
,
value
})
{
wrapper
=
shallowMount
(
StorageRow
,
{
propsData
:
{
name
,
value
,
},
});
}
describe
(
'
Storage Counter row component
'
,
()
=>
{
beforeEach
(()
=>
{
factory
(
data
);
});
it
(
'
renders provided name
'
,
()
=>
{
expect
(
wrapper
.
text
()).
toContain
(
data
.
name
);
});
it
(
'
renders formatted value
'
,
()
=>
{
expect
(
wrapper
.
text
()).
toContain
(
numberToHumanSize
(
data
.
value
));
});
});
ee/spec/frontend/storage_counter/mock_data.js
View file @
6d27b228
export
const
projects
=
[
import
{
projects
}
from
'
ee_jest/usage_quotas/storage/mock_data
'
;
{
id
:
'
24
'
,
fullPath
:
'
h5bp/dummy-project
'
,
nameWithNamespace
:
'
H5bp / dummy project
'
,
avatarUrl
:
null
,
webUrl
:
'
http://localhost:3001/h5bp/dummy-project
'
,
name
:
'
dummy project
'
,
statistics
:
{
commitCount
:
1
,
storageSize
:
41943
,
repositorySize
:
41943
,
lfsObjectsSize
:
0
,
buildArtifactsSize
:
0
,
packagesSize
:
0
,
},
actualRepositorySizeLimit
:
100000
,
totalCalculatedUsedStorage
:
41943
,
totalCalculatedStorageLimit
:
41943000
,
},
{
id
:
'
8
'
,
fullPath
:
'
h5bp/html5-boilerplate
'
,
nameWithNamespace
:
'
H5bp / Html5 Boilerplate
'
,
avatarUrl
:
null
,
webUrl
:
'
http://localhost:3001/h5bp/html5-boilerplate
'
,
name
:
'
Html5 Boilerplate
'
,
statistics
:
{
commitCount
:
0
,
storageSize
:
99000
,
repositorySize
:
0
,
lfsObjectsSize
:
0
,
buildArtifactsSize
:
1272375
,
packagesSize
:
0
,
},
actualRepositorySizeLimit
:
100000
,
totalCalculatedUsedStorage
:
89000
,
totalCalculatedStorageLimit
:
99430
,
},
{
id
:
'
80
'
,
fullPath
:
'
twit/twitter
'
,
nameWithNamespace
:
'
Twitter
'
,
avatarUrl
:
null
,
webUrl
:
'
http://localhost:3001/twit/twitter
'
,
name
:
'
Twitter
'
,
statistics
:
{
commitCount
:
0
,
storageSize
:
12933460
,
repositorySize
:
209710
,
lfsObjectsSize
:
209720
,
buildArtifactsSize
:
1272375
,
packagesSize
:
0
,
},
actualRepositorySizeLimit
:
100000
,
totalCalculatedUsedStorage
:
13143170
,
totalCalculatedStorageLimit
:
12143170
,
},
];
export
const
namespaceData
=
{
export
const
namespaceData
=
{
totalUsage
:
'
N/A
'
,
totalUsage
:
'
N/A
'
,
...
...
ee/spec/frontend/storage_counter/utils_spec.js
View file @
6d27b228
...
@@ -4,7 +4,8 @@ import {
...
@@ -4,7 +4,8 @@ import {
parseProjects
,
parseProjects
,
calculateUsedAndRemStorage
,
calculateUsedAndRemStorage
,
}
from
'
ee/storage_counter/utils
'
;
}
from
'
ee/storage_counter/utils
'
;
import
{
projects
as
mockProjectsData
,
mockGetStorageCounterGraphQLResponse
}
from
'
./mock_data
'
;
import
{
projects
as
mockProjectsData
}
from
'
ee_jest/usage_quotas/storage/mock_data
'
;
import
{
mockGetStorageCounterGraphQLResponse
}
from
'
./mock_data
'
;
describe
(
'
UsageThreshold
'
,
()
=>
{
describe
(
'
UsageThreshold
'
,
()
=>
{
it
.
each
`
it
.
each
`
...
...
ee/spec/frontend/
storage_counter/components/project
_spec.js
→
ee/spec/frontend/
usage_quotas/storage/components/collapsible_project_storage_detail
_spec.js
View file @
6d27b228
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Project
from
'
ee/storage_counter/components/project
.vue
'
;
import
CollapsibleProjectStorageDetail
from
'
ee/usage_quotas/storage/components/collapsible_project_storage_detail
.vue
'
;
import
StorageRow
from
'
ee/storage_counter/components/storage_row
.vue
'
;
import
ProjectStorageDetail
from
'
ee/usage_quotas/storage/components/project_storage_detail
.vue
'
;
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_utils
'
;
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_utils
'
;
import
ProjectAvatar
from
'
~/vue_shared/components/
deprecated_project_avatar/default
.vue
'
;
import
ProjectAvatar
from
'
~/vue_shared/components/
project_avatar
.vue
'
;
import
{
projects
}
from
'
../mock_data
'
;
import
{
projects
}
from
'
../mock_data
'
;
let
wrapper
;
let
wrapper
;
const
createComponent
=
()
=>
{
const
createComponent
=
()
=>
{
wrapper
=
shallowMount
(
Project
,
{
wrapper
=
shallowMount
(
CollapsibleProjectStorageDetail
,
{
propsData
:
{
propsData
:
{
project
:
projects
[
1
],
project
:
projects
[
1
],
},
},
...
@@ -15,9 +15,9 @@ const createComponent = () => {
...
@@ -15,9 +15,9 @@ const createComponent = () => {
};
};
const
findTableRow
=
()
=>
wrapper
.
find
(
'
[data-testid="projectTableRow"]
'
);
const
findTableRow
=
()
=>
wrapper
.
find
(
'
[data-testid="projectTableRow"]
'
);
const
find
StorageRow
=
()
=>
wrapper
.
find
(
StorageRow
);
const
find
ProjectStorageDetail
=
()
=>
wrapper
.
find
(
ProjectStorageDetail
);
describe
(
'
Storage Counter project component
'
,
()
=>
{
describe
(
'
CollapsibleProjectStorageDetail
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
createComponent
();
createComponent
();
});
});
...
@@ -37,16 +37,16 @@ describe('Storage Counter project component', () => {
...
@@ -37,16 +37,16 @@ describe('Storage Counter project component', () => {
describe
(
'
toggle row
'
,
()
=>
{
describe
(
'
toggle row
'
,
()
=>
{
describe
(
'
on click
'
,
()
=>
{
describe
(
'
on click
'
,
()
=>
{
it
(
'
toggles isOpen
'
,
()
=>
{
it
(
'
toggles isOpen
'
,
()
=>
{
expect
(
find
StorageRow
().
exists
()).
toBe
(
false
);
expect
(
find
ProjectStorageDetail
().
exists
()).
toBe
(
false
);
findTableRow
().
trigger
(
'
click
'
);
findTableRow
().
trigger
(
'
click
'
);
wrapper
.
vm
.
$nextTick
(()
=>
{
wrapper
.
vm
.
$nextTick
(()
=>
{
expect
(
find
StorageRow
().
exists
()).
toBe
(
true
);
expect
(
find
ProjectStorageDetail
().
exists
()).
toBe
(
true
);
findTableRow
().
trigger
(
'
click
'
);
findTableRow
().
trigger
(
'
click
'
);
wrapper
.
vm
.
$nextTick
(()
=>
{
wrapper
.
vm
.
$nextTick
(()
=>
{
expect
(
find
StorageRow
().
exists
()).
toBe
(
false
);
expect
(
find
ProjectStorageDetail
().
exists
()).
toBe
(
false
);
});
});
});
});
});
});
...
...
ee/spec/frontend/
storage_counter/components/projects_table
_spec.js
→
ee/spec/frontend/
usage_quotas/storage/components/project_list
_spec.js
View file @
6d27b228
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Project
from
'
ee/storage_counter/components/project
.vue
'
;
import
CollapsibleProjectStorageDetail
from
'
ee/usage_quotas/storage/components/collapsible_project_storage_detail
.vue
'
;
import
Project
sTable
from
'
ee/storage_counter/components/projects_table
.vue
'
;
import
Project
List
from
'
ee/usage_quotas/storage/components/project_list
.vue
'
;
import
{
projects
}
from
'
../mock_data
'
;
import
{
projects
}
from
'
../mock_data
'
;
let
wrapper
;
let
wrapper
;
const
createComponent
=
({
additionalRepoStorageByNamespace
=
false
}
=
{})
=>
{
const
createComponent
=
({
additionalRepoStorageByNamespace
=
false
}
=
{})
=>
{
wrapper
=
shallowMount
(
Project
sTable
,
{
wrapper
=
shallowMount
(
Project
List
,
{
propsData
:
{
propsData
:
{
projects
,
projects
,
additionalPurchasedStorageSize
:
0
,
additionalPurchasedStorageSize
:
0
,
...
@@ -19,9 +19,9 @@ const createComponent = ({ additionalRepoStorageByNamespace = false } = {}) => {
...
@@ -19,9 +19,9 @@ const createComponent = ({ additionalRepoStorageByNamespace = false } = {}) => {
});
});
};
};
const
findTableRows
=
()
=>
wrapper
.
findAll
(
Project
);
const
findTableRows
=
()
=>
wrapper
.
findAll
(
CollapsibleProjectStorageDetail
);
describe
(
'
Usage Quotas project table componen
t
'
,
()
=>
{
describe
(
'
ProjectLis
t
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
createComponent
();
createComponent
();
});
});
...
...
spec/frontend/projects/storage_counter/components/
app_spec.js
→
ee/spec/frontend/usage_quotas/storage/components/project_storage_
app_spec.js
View file @
6d27b228
...
@@ -4,21 +4,21 @@ import VueApollo from 'vue-apollo';
...
@@ -4,21 +4,21 @@ import VueApollo from 'vue-apollo';
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
StorageCounterApp
from
'
~/projects/storage_counter/components/
app.vue
'
;
import
ProjectStorageApp
from
'
ee/usage_quotas/storage/components/project_storage_
app.vue
'
;
import
{
TOTAL_USAGE_DEFAULT_TEXT
}
from
'
~/projects/storage_counter
/constants
'
;
import
{
TOTAL_USAGE_DEFAULT_TEXT
}
from
'
ee/usage_quotas/storage
/constants
'
;
import
getProjectStorage
Count
from
'
~/projects/storage_counter
/queries/project_storage.query.graphql
'
;
import
getProjectStorage
Statistics
from
'
ee/usage_quotas/storage
/queries/project_storage.query.graphql
'
;
import
UsageGraph
from
'
~/vue_shared/components/storage_counter/usage_graph.vue
'
;
import
UsageGraph
from
'
~/vue_shared/components/storage_counter/usage_graph.vue
'
;
import
{
import
{
mockGetProjectStorageCountGraphQLResponse
,
mockEmptyResponse
,
projectData
,
projectData
,
defaultProvideValues
,
mockGetProjectStorageStatisticsGraphQLResponse
,
mockEmptyResponse
,
defaultProjectProvideValues
,
}
from
'
../mock_data
'
;
}
from
'
../mock_data
'
;
const
localVue
=
createLocalVue
();
const
localVue
=
createLocalVue
();
localVue
.
use
(
VueApollo
);
localVue
.
use
(
VueApollo
);
describe
(
'
Storage counter a
pp
'
,
()
=>
{
describe
(
'
ProjectStorageA
pp
'
,
()
=>
{
let
wrapper
;
let
wrapper
;
const
createMockApolloProvider
=
({
reject
=
false
,
mockedValue
}
=
{})
=>
{
const
createMockApolloProvider
=
({
reject
=
false
,
mockedValue
}
=
{})
=>
{
...
@@ -30,18 +30,18 @@ describe('Storage counter app', () => {
...
@@ -30,18 +30,18 @@ describe('Storage counter app', () => {
response
=
jest
.
fn
().
mockResolvedValue
(
mockedValue
);
response
=
jest
.
fn
().
mockResolvedValue
(
mockedValue
);
}
}
const
requestHandlers
=
[[
getProjectStorage
Count
,
response
]];
const
requestHandlers
=
[[
getProjectStorage
Statistics
,
response
]];
return
createMockApollo
(
requestHandlers
);
return
createMockApollo
(
requestHandlers
);
};
};
const
createComponent
=
({
provide
=
{},
mockApollo
}
=
{})
=>
{
const
createComponent
=
({
provide
=
{},
mockApollo
}
=
{})
=>
{
wrapper
=
extendedWrapper
(
wrapper
=
extendedWrapper
(
shallowMount
(
StorageCounter
App
,
{
shallowMount
(
ProjectStorage
App
,
{
localVue
,
localVue
,
apolloProvider
:
mockApollo
,
apolloProvider
:
mockApollo
,
provide
:
{
provide
:
{
...
defaultProvideValues
,
...
defaultPro
jectPro
videValues
,
...
provide
,
...
provide
,
},
},
}),
}),
...
@@ -63,7 +63,7 @@ describe('Storage counter app', () => {
...
@@ -63,7 +63,7 @@ describe('Storage counter app', () => {
beforeEach
(
async
()
=>
{
beforeEach
(
async
()
=>
{
mockApollo
=
createMockApolloProvider
({
mockApollo
=
createMockApolloProvider
({
mockedValue
:
mockGetProjectStorage
Count
GraphQLResponse
,
mockedValue
:
mockGetProjectStorage
Statistics
GraphQLResponse
,
});
});
createComponent
({
mockApollo
});
createComponent
({
mockApollo
});
await
waitForPromises
();
await
waitForPromises
();
...
@@ -75,7 +75,7 @@ describe('Storage counter app', () => {
...
@@ -75,7 +75,7 @@ describe('Storage counter app', () => {
it
(
'
renders correct usage quotas help link
'
,
()
=>
{
it
(
'
renders correct usage quotas help link
'
,
()
=>
{
expect
(
findUsageQuotasHelpLink
().
attributes
(
'
href
'
)).
toBe
(
expect
(
findUsageQuotasHelpLink
().
attributes
(
'
href
'
)).
toBe
(
defaultProvideValues
.
helpLinks
.
usageQuotasHelpPagePath
,
defaultPro
jectPro
videValues
.
helpLinks
.
usageQuotasHelpPagePath
,
);
);
});
});
});
});
...
@@ -129,7 +129,7 @@ describe('Storage counter app', () => {
...
@@ -129,7 +129,7 @@ describe('Storage counter app', () => {
beforeEach
(
async
()
=>
{
beforeEach
(
async
()
=>
{
mockApollo
=
createMockApolloProvider
({
mockApollo
=
createMockApolloProvider
({
mockedValue
:
mockGetProjectStorage
Count
GraphQLResponse
,
mockedValue
:
mockGetProjectStorage
Statistics
GraphQLResponse
,
});
});
createComponent
({
mockApollo
});
createComponent
({
mockApollo
});
await
waitForPromises
();
await
waitForPromises
();
...
@@ -143,7 +143,7 @@ describe('Storage counter app', () => {
...
@@ -143,7 +143,7 @@ describe('Storage counter app', () => {
const
{
const
{
__typename
,
__typename
,
...
statistics
...
statistics
}
=
mockGetProjectStorage
Count
GraphQLResponse
.
data
.
project
.
statistics
;
}
=
mockGetProjectStorage
Statistics
GraphQLResponse
.
data
.
project
.
statistics
;
expect
(
findUsageGraph
().
props
(
'
rootStorageStatistics
'
)).
toMatchObject
(
statistics
);
expect
(
findUsageGraph
().
props
(
'
rootStorageStatistics
'
)).
toMatchObject
(
statistics
);
});
});
});
});
...
...
spec/frontend/projects/storage_counter/components/storage_table
_spec.js
→
ee/spec/frontend/usage_quotas/storage/components/project_storage_detail
_spec.js
View file @
6d27b228
import
{
GlTableLite
}
from
'
@gitlab/ui
'
;
import
{
GlTableLite
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
StorageTable
from
'
~/projects/storage_counter/components/storage_table
.vue
'
;
import
ProjectStorageDetail
from
'
ee/usage_quotas/storage/components/project_storage_detail
.vue
'
;
import
{
projectData
,
defaultProvideValue
s
}
from
'
../mock_data
'
;
import
{
projectData
,
projectHelpLink
s
}
from
'
../mock_data
'
;
describe
(
'
StorageTable
'
,
()
=>
{
describe
(
'
ProjectStorageDetail
'
,
()
=>
{
let
wrapper
;
let
wrapper
;
const
defaultProps
=
{
const
defaultProps
=
{
...
@@ -13,7 +13,7 @@ describe('StorageTable', () => {
...
@@ -13,7 +13,7 @@ describe('StorageTable', () => {
const
createComponent
=
(
props
=
{})
=>
{
const
createComponent
=
(
props
=
{})
=>
{
wrapper
=
extendedWrapper
(
wrapper
=
extendedWrapper
(
mount
(
StorageTable
,
{
mount
(
ProjectStorageDetail
,
{
propsData
:
{
propsData
:
{
...
defaultProps
,
...
defaultProps
,
...
props
,
...
props
,
...
@@ -39,7 +39,7 @@ describe('StorageTable', () => {
...
@@ -39,7 +39,7 @@ describe('StorageTable', () => {
expect
(
wrapper
.
findByTestId
(
`
${
id
}
-description`
).
text
()).
toBe
(
description
);
expect
(
wrapper
.
findByTestId
(
`
${
id
}
-description`
).
text
()).
toBe
(
description
);
expect
(
wrapper
.
findByTestId
(
`
${
id
}
-icon`
).
props
(
'
name
'
)).
toBe
(
id
);
expect
(
wrapper
.
findByTestId
(
`
${
id
}
-icon`
).
props
(
'
name
'
)).
toBe
(
id
);
expect
(
wrapper
.
findByTestId
(
`
${
id
}
-help-link`
).
attributes
(
'
href
'
)).
toBe
(
expect
(
wrapper
.
findByTestId
(
`
${
id
}
-help-link`
).
attributes
(
'
href
'
)).
toBe
(
defaultProvideValues
.
h
elpLinks
[
id
.
replace
(
`Size`
,
`HelpPagePath`
)]
projectH
elpLinks
[
id
.
replace
(
`Size`
,
`HelpPagePath`
)]
.
replace
(
`Size`
,
``
)
.
replace
(
`Size`
,
``
)
.
replace
(
/
[
A-Z
]
/g
,
(
m
)
=>
`-
${
m
.
toLowerCase
()}
`
),
.
replace
(
/
[
A-Z
]
/g
,
(
m
)
=>
`-
${
m
.
toLowerCase
()}
`
),
);
);
...
...
ee/spec/frontend/
storage_counter
/components/projects_skeleton_loader_spec.js
→
ee/spec/frontend/
usage_quotas/storage
/components/projects_skeleton_loader_spec.js
View file @
6d27b228
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
ProjectsSkeletonLoader
from
'
ee/
storage_counter
/components/projects_skeleton_loader.vue
'
;
import
ProjectsSkeletonLoader
from
'
ee/
usage_quotas/storage
/components/projects_skeleton_loader.vue
'
;
describe
(
'
ProjectsSkeletonLoader
'
,
()
=>
{
describe
(
'
ProjectsSkeletonLoader
'
,
()
=>
{
let
wrapper
;
let
wrapper
;
...
...
spec/frontend/projects/storage_counter
/components/storage_type_icon_spec.js
→
ee/spec/frontend/usage_quotas/storage
/components/storage_type_icon_spec.js
View file @
6d27b228
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
GlIcon
}
from
'
@gitlab/ui
'
;
import
{
GlIcon
}
from
'
@gitlab/ui
'
;
import
StorageTypeIcon
from
'
~/projects/storage_counter
/components/storage_type_icon.vue
'
;
import
StorageTypeIcon
from
'
ee/usage_quotas/storage
/components/storage_type_icon.vue
'
;
describe
(
'
StorageTypeIcon
'
,
()
=>
{
describe
(
'
StorageTypeIcon
'
,
()
=>
{
let
wrapper
;
let
wrapper
;
...
...
spec/frontend/projects/storage_counter
/mock_data.js
→
ee/spec/frontend/usage_quotas/storage
/mock_data.js
View file @
6d27b228
import
mockGetProjectStorage
CountGraphQLResponse
from
'
test_fixtures/graphql/projects/storage_counter
/project_storage.query.graphql.json
'
;
import
mockGetProjectStorage
StatisticsGraphQLResponse
from
'
test_fixtures/graphql/usage_quotas/storage
/project_storage.query.graphql.json
'
;
export
{
mockGetProjectStorage
Count
GraphQLResponse
};
export
{
mockGetProjectStorage
Statistics
GraphQLResponse
};
export
const
mockEmptyResponse
=
{
data
:
{
project
:
null
}
};
export
const
mockEmptyResponse
=
{
data
:
{
project
:
null
}
};
export
const
defaultProvideValues
=
{
export
const
projects
=
[
projectPath
:
'
/project-path
'
,
{
helpLinks
:
{
id
:
'
24
'
,
usageQuotasHelpPagePath
:
'
/usage-quotas
'
,
fullPath
:
'
h5bp/dummy-project
'
,
buildArtifactsHelpPagePath
:
'
/build-artifacts
'
,
nameWithNamespace
:
'
H5bp / dummy project
'
,
lfsObjectsHelpPagePath
:
'
/lsf-objects
'
,
avatarUrl
:
null
,
packagesHelpPagePath
:
'
/packages
'
,
webUrl
:
'
http://localhost:3001/h5bp/dummy-project
'
,
repositoryHelpPagePath
:
'
/repository
'
,
name
:
'
dummy project
'
,
snippetsHelpPagePath
:
'
/snippets
'
,
statistics
:
{
uploadsHelpPagePath
:
'
/uploads
'
,
commitCount
:
1
,
wikiHelpPagePath
:
'
/wiki
'
,
storageSize
:
41943
,
repositorySize
:
41943
,
lfsObjectsSize
:
0
,
buildArtifactsSize
:
0
,
packagesSize
:
0
,
},
actualRepositorySizeLimit
:
100000
,
totalCalculatedUsedStorage
:
41943
,
totalCalculatedStorageLimit
:
41943000
,
},
},
};
{
id
:
'
8
'
,
fullPath
:
'
h5bp/html5-boilerplate
'
,
nameWithNamespace
:
'
H5bp / Html5 Boilerplate
'
,
avatarUrl
:
null
,
webUrl
:
'
http://localhost:3001/h5bp/html5-boilerplate
'
,
name
:
'
Html5 Boilerplate
'
,
statistics
:
{
commitCount
:
0
,
storageSize
:
99000
,
repositorySize
:
0
,
lfsObjectsSize
:
0
,
buildArtifactsSize
:
1272375
,
packagesSize
:
0
,
},
actualRepositorySizeLimit
:
100000
,
totalCalculatedUsedStorage
:
89000
,
totalCalculatedStorageLimit
:
99430
,
},
{
id
:
'
80
'
,
fullPath
:
'
twit/twitter
'
,
nameWithNamespace
:
'
Twitter
'
,
avatarUrl
:
null
,
webUrl
:
'
http://localhost:3001/twit/twitter
'
,
name
:
'
Twitter
'
,
statistics
:
{
commitCount
:
0
,
storageSize
:
12933460
,
repositorySize
:
209710
,
lfsObjectsSize
:
209720
,
buildArtifactsSize
:
1272375
,
packagesSize
:
0
,
},
actualRepositorySizeLimit
:
100000
,
totalCalculatedUsedStorage
:
13143170
,
totalCalculatedStorageLimit
:
12143170
,
},
];
export
const
projectData
=
{
export
const
projectData
=
{
storage
:
{
storage
:
{
...
@@ -90,3 +136,19 @@ export const projectData = {
...
@@ -90,3 +136,19 @@ export const projectData = {
],
],
},
},
};
};
export
const
projectHelpLinks
=
{
usageQuotasHelpPagePath
:
'
/usage-quotas
'
,
buildArtifactsHelpPagePath
:
'
/build-artifacts
'
,
lfsObjectsHelpPagePath
:
'
/lsf-objects
'
,
packagesHelpPagePath
:
'
/packages
'
,
repositoryHelpPagePath
:
'
/repository
'
,
snippetsHelpPagePath
:
'
/snippets
'
,
uploadsHelpPagePath
:
'
/uploads
'
,
wikiHelpPagePath
:
'
/wiki
'
,
};
export
const
defaultProjectProvideValues
=
{
projectPath
:
'
/project-path
'
,
helpLinks
:
projectHelpLinks
,
};
spec/frontend/projects/storage_counter
/utils_spec.js
→
ee/spec/frontend/usage_quotas/storage
/utils_spec.js
View file @
6d27b228
import
{
parseGetProjectStorageResults
}
from
'
~/projects/storage_counter
/utils
'
;
import
{
parseGetProjectStorageResults
}
from
'
ee/usage_quotas/storage
/utils
'
;
import
{
import
{
mockGetProjectStorageCountGraphQLResponse
,
projectData
,
projectData
,
defaultProvideValues
,
mockGetProjectStorageStatisticsGraphQLResponse
,
defaultProjectProvideValues
,
}
from
'
./mock_data
'
;
}
from
'
./mock_data
'
;
describe
(
'
parseGetProjectStorageResults
'
,
()
=>
{
describe
(
'
parseGetProjectStorageResults
'
,
()
=>
{
it
(
'
parses project statistics correctly
'
,
()
=>
{
it
(
'
parses project statistics correctly
'
,
()
=>
{
expect
(
expect
(
parseGetProjectStorageResults
(
parseGetProjectStorageResults
(
mockGetProjectStorage
Count
GraphQLResponse
.
data
,
mockGetProjectStorage
Statistics
GraphQLResponse
.
data
,
defaultProvideValues
.
helpLinks
,
defaultPro
jectPro
videValues
.
helpLinks
,
),
),
).
toMatchObject
(
projectData
);
).
toMatchObject
(
projectData
);
});
});
it
(
'
includes storage type with size of 0 in returned value
'
,
()
=>
{
it
(
'
includes storage type with size of 0 in returned value
'
,
()
=>
{
const
mockedResponse
=
mockGetProjectStorage
Count
GraphQLResponse
.
data
;
const
mockedResponse
=
mockGetProjectStorage
Statistics
GraphQLResponse
.
data
;
// ensuring a specific storage type item has size of 0
// ensuring a specific storage type item has size of 0
mockedResponse
.
project
.
statistics
.
repositorySize
=
0
;
mockedResponse
.
project
.
statistics
.
repositorySize
=
0
;
const
response
=
parseGetProjectStorageResults
(
mockedResponse
,
defaultProvideValues
.
helpLinks
);
const
response
=
parseGetProjectStorageResults
(
mockedResponse
,
defaultProjectProvideValues
.
helpLinks
,
);
expect
(
response
.
storage
.
storageTypes
).
toEqual
(
expect
(
response
.
storage
.
storageTypes
).
toEqual
(
expect
.
arrayContaining
([
expect
.
arrayContaining
([
...
...
locale/gitlab.pot
View file @
6d27b228
...
@@ -37424,9 +37424,6 @@ msgstr ""
...
@@ -37424,9 +37424,6 @@ msgstr ""
msgid "Upvotes"
msgid "Upvotes"
msgstr ""
msgstr ""
msgid "Usage"
msgstr ""
msgid "Usage Trends"
msgid "Usage Trends"
msgstr ""
msgstr ""
...
@@ -37484,9 +37481,6 @@ msgstr ""
...
@@ -37484,9 +37481,6 @@ msgstr ""
msgid "UsageQuota|LFS Objects"
msgid "UsageQuota|LFS Objects"
msgstr ""
msgstr ""
msgid "UsageQuota|LFS Storage"
msgstr ""
msgid "UsageQuota|LFS storage"
msgid "UsageQuota|LFS storage"
msgstr ""
msgstr ""
...
...
spec/frontend/fixtures/projects.rb
View file @
6d27b228
...
@@ -65,31 +65,5 @@ RSpec.describe 'Projects (JavaScript fixtures)', type: :controller do
...
@@ -65,31 +65,5 @@ RSpec.describe 'Projects (JavaScript fixtures)', type: :controller do
expect_graphql_errors_to_be_empty
expect_graphql_errors_to_be_empty
end
end
end
end
context
'project storage count query'
do
before
do
project
.
statistics
.
update!
(
repository_size:
3900000
,
lfs_objects_size:
4800000
,
build_artifacts_size:
400000
,
pipeline_artifacts_size:
400000
,
wiki_size:
300000
,
packages_size:
3800000
,
uploads_size:
900000
)
end
base_input_path
=
'projects/storage_counter/queries/'
base_output_path
=
'graphql/projects/storage_counter/'
query_name
=
'project_storage.query.graphql'
it
"
#{
base_output_path
}#{
query_name
}
.json"
do
query
=
get_graphql_query_as_string
(
"
#{
base_input_path
}#{
query_name
}
"
)
post_graphql
(
query
,
current_user:
user
,
variables:
{
fullPath:
project
.
full_path
})
expect_graphql_errors_to_be_empty
end
end
end
end
end
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