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
00a8f465
Commit
00a8f465
authored
Apr 21, 2021
by
Zack Cuddy
Committed by
Nicolò Maria Mezzopera
Apr 21, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Geo Node Status 2.0 - Replication Details Container
parent
7172e12e
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
317 additions
and
6 deletions
+317
-6
ee/app/assets/javascripts/geo_nodes_beta/components/details/geo_node_details.vue
...ts/geo_nodes_beta/components/details/geo_node_details.vue
+3
-5
ee/app/assets/javascripts/geo_nodes_beta/components/details/secondary_node/geo_node_replication_details.vue
...s/details/secondary_node/geo_node_replication_details.vue
+110
-0
ee/app/assets/javascripts/geo_nodes_beta/constants.js
ee/app/assets/javascripts/geo_nodes_beta/constants.js
+4
-0
ee/app/assets/stylesheets/pages/geo.scss
ee/app/assets/stylesheets/pages/geo.scss
+9
-0
ee/spec/frontend/geo_nodes_beta/components/details/geo_node_details_spec.js
...eo_nodes_beta/components/details/geo_node_details_spec.js
+2
-1
ee/spec/frontend/geo_nodes_beta/components/details/secondary_node/geo_node_replication_details_spec.js
...tails/secondary_node/geo_node_replication_details_spec.js
+180
-0
locale/gitlab.pot
locale/gitlab.pot
+9
-0
No files found.
ee/app/assets/javascripts/geo_nodes_beta/components/details/geo_node_details.vue
View file @
00a8f465
<
script
>
import
{
s__
}
from
'
~/locale
'
;
import
GeoNodeCoreDetails
from
'
./geo_node_core_details.vue
'
;
import
GeoNodePrimaryOtherInfo
from
'
./primary_node/geo_node_primary_other_info.vue
'
;
import
GeoNodeVerificationInfo
from
'
./primary_node/geo_node_verification_info.vue
'
;
import
GeoNodeReplicationDetails
from
'
./secondary_node/geo_node_replication_details.vue
'
;
import
GeoNodeReplicationSummary
from
'
./secondary_node/geo_node_replication_summary.vue
'
;
import
GeoNodeSecondaryOtherInfo
from
'
./secondary_node/geo_node_secondary_other_info.vue
'
;
export
default
{
name
:
'
GeoNodeDetails
'
,
i18n
:
{
replicationDetails
:
s__
(
'
Geo|Replication Details
'
),
},
components
:
{
GeoNodeCoreDetails
,
GeoNodePrimaryOtherInfo
,
GeoNodeVerificationInfo
,
GeoNodeReplicationSummary
,
GeoNodeSecondaryOtherInfo
,
GeoNodeReplicationDetails
,
},
props
:
{
node
:
{
...
...
@@ -50,7 +48,7 @@ export default {
/>
<geo-node-secondary-other-info
class=
"gl-flex-fill-1 gl-h-full gl-w-full"
:node=
"node"
/>
</div>
<
p
data-testid=
"secondary-replication-details"
>
{{
$options
.
i18n
.
replicationDetails
}}
</p
>
<
geo-node-replication-details
:node=
"node"
/
>
</div>
</div>
</
template
>
ee/app/assets/javascripts/geo_nodes_beta/components/details/secondary_node/geo_node_replication_details.vue
0 → 100644
View file @
00a8f465
<
script
>
import
{
GlIcon
,
GlPopover
,
GlLink
,
GlButton
}
from
'
@gitlab/ui
'
;
import
{
mapGetters
,
mapState
}
from
'
vuex
'
;
import
{
GEO_REPLICATION_TYPES_URL
}
from
'
ee/geo_nodes_beta/constants
'
;
import
{
s__
,
__
}
from
'
~/locale
'
;
export
default
{
name
:
'
GeoNodeReplicationDetails
'
,
i18n
:
{
replicationDetailsDesktop
:
s__
(
'
Geo|Replication Details Desktop
'
),
replicationDetailsMobile
:
s__
(
'
Geo|Replication Details Mobile
'
),
replicationDetails
:
s__
(
'
Geo|Replication Details
'
),
popoverText
:
s__
(
'
Geo|Geo supports replication of many data types.
'
),
learnMore
:
__
(
'
Learn more
'
),
},
components
:
{
GlIcon
,
GlPopover
,
GlLink
,
GlButton
,
},
props
:
{
node
:
{
type
:
Object
,
required
:
true
,
},
},
data
()
{
return
{
collapsed
:
false
,
};
},
computed
:
{
...
mapState
([
'
replicableTypes
'
]),
...
mapGetters
([
'
verificationInfo
'
,
'
syncInfo
'
]),
replicationItems
()
{
const
syncInfoData
=
this
.
syncInfo
(
this
.
node
.
id
);
const
verificationInfoData
=
this
.
verificationInfo
(
this
.
node
.
id
);
return
this
.
replicableTypes
.
map
((
replicable
)
=>
{
const
replicableSyncInfo
=
syncInfoData
.
find
((
r
)
=>
r
.
title
===
replicable
.
titlePlural
);
const
replicableVerificationInfo
=
verificationInfoData
.
find
(
(
r
)
=>
r
.
title
===
replicable
.
titlePlural
,
);
return
{
dataTypeTitle
:
replicable
.
dataTypeTitle
,
component
:
replicable
.
titlePlural
,
syncValues
:
replicableSyncInfo
?
replicableSyncInfo
.
values
:
null
,
verificationValues
:
replicableVerificationInfo
?
replicableVerificationInfo
.
values
:
null
,
};
});
},
chevronIcon
()
{
return
this
.
collapsed
?
'
chevron-right
'
:
'
chevron-down
'
;
},
},
methods
:
{
collapseSection
()
{
this
.
collapsed
=
!
this
.
collapsed
;
},
},
GEO_REPLICATION_TYPES_URL
,
};
</
script
>
<
template
>
<div>
<div
class=
"gl-display-flex gl-align-items-center gl-cursor-pointer gl-py-5 gl-border-b-1 gl-border-b-solid gl-border-b-gray-100 gl-border-t-1 gl-border-t-solid gl-border-t-gray-100"
>
<gl-button
class=
"gl-mr-3 gl-p-0!"
category=
"tertiary"
variant=
"confirm"
:icon=
"chevronIcon"
@
click=
"collapseSection"
>
{{
$options
.
i18n
.
replicationDetails
}}
</gl-button>
<gl-icon
ref=
"replicationDetails"
tabindex=
"0"
name=
"question"
class=
"gl-text-blue-500 gl-cursor-pointer gl-ml-2"
/>
<gl-popover
:target=
"() => $refs.replicationDetails.$el"
placement=
"top"
triggers=
"hover focus"
>
<p>
{{
$options
.
i18n
.
popoverText
}}
</p>
<gl-link
:href=
"$options.GEO_REPLICATION_TYPES_URL"
target=
"_blank"
>
{{
$options
.
i18n
.
learnMore
}}
</gl-link>
</gl-popover>
</div>
<div
v-if=
"!collapsed"
>
<span
class=
"gl-display-none gl-md-display-block"
data-testid=
"replication-details-desktop"
>
{{
$options
.
i18n
.
replicationDetailsDesktop
}}
</span>
<span
class=
"gl-md-display-none!"
data-testid=
"replication-details-mobile"
>
{{
$options
.
i18n
.
replicationDetailsMobile
}}
</span>
</div>
</div>
</
template
>
ee/app/assets/javascripts/geo_nodes_beta/constants.js
View file @
00a8f465
...
...
@@ -22,6 +22,10 @@ export const REPLICATION_PAUSE_URL = helpPagePath('administration/geo/index.html
anchor
:
'
pausing-and-resuming-replication
'
,
});
export
const
GEO_REPLICATION_TYPES_URL
=
helpPagePath
(
'
administration/geo/replication/datatypes.html
'
,
);
export
const
HEALTH_STATUS_UI
=
{
healthy
:
{
icon
:
'
status_success
'
,
...
...
ee/app/assets/stylesheets/pages/geo.scss
View file @
00a8f465
...
...
@@ -50,3 +50,12 @@
grid-template-columns
:
1fr
1fr
;
grid-gap
:
$gl-spacing-scale-5
;
}
.geo-node-replication-details-grid-columns
{
grid-template-columns
:
1fr
1fr
;
grid-gap
:
1rem
;
@include
media-breakpoint-up
(
md
)
{
grid-template-columns
:
1fr
1fr
2fr
2fr
;
}
}
ee/spec/frontend/geo_nodes_beta/components/details/geo_node_details_spec.js
View file @
00a8f465
...
...
@@ -3,6 +3,7 @@ import GeoNodeCoreDetails from 'ee/geo_nodes_beta/components/details/geo_node_co
import
GeoNodeDetails
from
'
ee/geo_nodes_beta/components/details/geo_node_details.vue
'
;
import
GeoNodePrimaryOtherInfo
from
'
ee/geo_nodes_beta/components/details/primary_node/geo_node_primary_other_info.vue
'
;
import
GeoNodeVerificationInfo
from
'
ee/geo_nodes_beta/components/details/primary_node/geo_node_verification_info.vue
'
;
import
GeoNodeReplicationDetails
from
'
ee/geo_nodes_beta/components/details/secondary_node/geo_node_replication_details.vue
'
;
import
GeoNodeReplicationSummary
from
'
ee/geo_nodes_beta/components/details/secondary_node/geo_node_replication_summary.vue
'
;
import
GeoNodeSecondaryOtherInfo
from
'
ee/geo_nodes_beta/components/details/secondary_node/geo_node_secondary_other_info.vue
'
;
import
{
MOCK_NODES
}
from
'
ee_jest/geo_nodes_beta/mock_data
'
;
...
...
@@ -37,7 +38,7 @@ describe('GeoNodeDetails', () => {
wrapper
.
findComponent
(
GeoNodeReplicationSummary
);
const
findGeoNodeSecondaryOtherInfo
=
()
=>
wrapper
.
findComponent
(
GeoNodeSecondaryOtherInfo
);
const
findGeoNodeSecondaryReplicationDetails
=
()
=>
wrapper
.
find
ByTestId
(
'
secondary-replication-details
'
);
wrapper
.
find
Component
(
GeoNodeReplicationDetails
);
describe
(
'
template
'
,
()
=>
{
describe
(
'
always
'
,
()
=>
{
...
...
ee/spec/frontend/geo_nodes_beta/components/details/secondary_node/geo_node_replication_details_spec.js
0 → 100644
View file @
00a8f465
import
{
GlIcon
,
GlPopover
,
GlLink
,
GlButton
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
GeoNodeReplicationDetails
from
'
ee/geo_nodes_beta/components/details/secondary_node/geo_node_replication_details.vue
'
;
import
{
GEO_REPLICATION_TYPES_URL
}
from
'
ee/geo_nodes_beta/constants
'
;
import
{
MOCK_NODES
,
MOCK_REPLICABLE_TYPES
}
from
'
ee_jest/geo_nodes_beta/mock_data
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
Vue
.
use
(
Vuex
);
describe
(
'
GeoNodeReplicationDetails
'
,
()
=>
{
let
wrapper
;
const
defaultProps
=
{
node
:
MOCK_NODES
[
1
],
};
const
createComponent
=
(
initialState
,
props
,
getters
)
=>
{
const
store
=
new
Vuex
.
Store
({
state
:
{
replicableTypes
:
[],
...
initialState
,
},
getters
:
{
syncInfo
:
()
=>
()
=>
[],
verificationInfo
:
()
=>
()
=>
[],
...
getters
,
},
});
wrapper
=
extendedWrapper
(
shallowMount
(
GeoNodeReplicationDetails
,
{
store
,
propsData
:
{
...
defaultProps
,
...
props
,
},
}),
);
};
afterEach
(()
=>
{
wrapper
.
destroy
();
});
const
findGeoMobileReplicationDetails
=
()
=>
wrapper
.
findByTestId
(
'
replication-details-mobile
'
);
const
findGeoDesktopReplicationDetails
=
()
=>
wrapper
.
findByTestId
(
'
replication-details-desktop
'
);
const
findGlIcon
=
()
=>
wrapper
.
findComponent
(
GlIcon
);
const
findGlPopover
=
()
=>
wrapper
.
findComponent
(
GlPopover
);
const
findGlPopoverLink
=
()
=>
findGlPopover
().
findComponent
(
GlLink
);
const
findCollapseButton
=
()
=>
wrapper
.
findComponent
(
GlButton
);
describe
(
'
template
'
,
()
=>
{
describe
(
'
always
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
();
});
it
(
'
renders the question icon correctly
'
,
()
=>
{
expect
(
findGlIcon
().
exists
()).
toBe
(
true
);
expect
(
findGlIcon
().
props
(
'
name
'
)).
toBe
(
'
question
'
);
});
it
(
'
renders the GlPopover always
'
,
()
=>
{
expect
(
findGlPopover
().
exists
()).
toBe
(
true
);
});
it
(
'
renders the popover link correctly
'
,
()
=>
{
expect
(
findGlPopoverLink
().
exists
()).
toBe
(
true
);
expect
(
findGlPopoverLink
().
attributes
(
'
href
'
)).
toBe
(
GEO_REPLICATION_TYPES_URL
);
});
});
describe
(
'
when un-collapsed
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
();
});
it
(
'
renders the collapse button correctly
'
,
()
=>
{
expect
(
findCollapseButton
().
exists
()).
toBe
(
true
);
expect
(
findCollapseButton
().
attributes
(
'
icon
'
)).
toBe
(
'
chevron-down
'
);
});
it
(
'
renders mobile replication details with correct visibility class
'
,
()
=>
{
expect
(
findGeoMobileReplicationDetails
().
exists
()).
toBe
(
true
);
expect
(
findGeoMobileReplicationDetails
().
classes
()).
toStrictEqual
([
'
gl-md-display-none!
'
]);
});
it
(
'
renders desktop details with correct visibility class
'
,
()
=>
{
expect
(
findGeoDesktopReplicationDetails
().
exists
()).
toBe
(
true
);
expect
(
findGeoDesktopReplicationDetails
().
classes
()).
toStrictEqual
([
'
gl-display-none
'
,
'
gl-md-display-block
'
,
]);
});
});
describe
(
'
when collapsed
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
();
findCollapseButton
().
vm
.
$emit
(
'
click
'
);
});
it
(
'
renders the collapse button correctly
'
,
()
=>
{
expect
(
findCollapseButton
().
exists
()).
toBe
(
true
);
expect
(
findCollapseButton
().
attributes
(
'
icon
'
)).
toBe
(
'
chevron-right
'
);
});
it
(
'
does not render mobile replication details
'
,
()
=>
{
expect
(
findGeoMobileReplicationDetails
().
exists
()).
toBe
(
false
);
});
it
(
'
does not render desktop replication details
'
,
()
=>
{
expect
(
findGeoDesktopReplicationDetails
().
exists
()).
toBe
(
false
);
});
});
const
mockSync
=
{
dataTypeTitle
:
MOCK_REPLICABLE_TYPES
[
0
].
dataTypeTitle
,
title
:
MOCK_REPLICABLE_TYPES
[
0
].
titlePlural
,
values
:
{
total
:
100
,
success
:
0
},
};
const
mockVerif
=
{
dataTypeTitle
:
MOCK_REPLICABLE_TYPES
[
0
].
dataTypeTitle
,
title
:
MOCK_REPLICABLE_TYPES
[
0
].
titlePlural
,
values
:
{
total
:
50
,
success
:
50
},
};
const
mockExpectedNoValues
=
{
dataTypeTitle
:
MOCK_REPLICABLE_TYPES
[
0
].
dataTypeTitle
,
component
:
MOCK_REPLICABLE_TYPES
[
0
].
titlePlural
,
syncValues
:
null
,
verificationValues
:
null
,
};
const
mockExpectedOnlySync
=
{
dataTypeTitle
:
MOCK_REPLICABLE_TYPES
[
0
].
dataTypeTitle
,
component
:
MOCK_REPLICABLE_TYPES
[
0
].
titlePlural
,
syncValues
:
{
total
:
100
,
success
:
0
},
verificationValues
:
null
,
};
const
mockExpectedOnlyVerif
=
{
dataTypeTitle
:
MOCK_REPLICABLE_TYPES
[
0
].
dataTypeTitle
,
component
:
MOCK_REPLICABLE_TYPES
[
0
].
titlePlural
,
syncValues
:
null
,
verificationValues
:
{
total
:
50
,
success
:
50
},
};
const
mockExpectedBothTypes
=
{
dataTypeTitle
:
MOCK_REPLICABLE_TYPES
[
0
].
dataTypeTitle
,
component
:
MOCK_REPLICABLE_TYPES
[
0
].
titlePlural
,
syncValues
:
{
total
:
100
,
success
:
0
},
verificationValues
:
{
total
:
50
,
success
:
50
},
};
describe
.
each
`
description | mockSyncData | mockVerificationData | expectedData
${
'
with no data
'
}
|
${[]}
|
${[]}
|
${[
mockExpectedNoValues
]}
${
'
with no verification data
'
}
|
${[
mockSync
]}
|
${[]}
|
${[
mockExpectedOnlySync
]}
${
'
with no sync data
'
}
|
${[]}
|
${[
mockVerif
]}
|
${[
mockExpectedOnlyVerif
]}
${
'
with all data
'
}
|
${[
mockSync
]}
|
${[
mockVerif
]}
|
${[
mockExpectedBothTypes
]}
`
(
'
$description
'
,
({
mockSyncData
,
mockVerificationData
,
expectedData
})
=>
{
beforeEach
(()
=>
{
createComponent
({
replicableTypes
:
[
MOCK_REPLICABLE_TYPES
[
0
]]
},
null
,
{
syncInfo
:
()
=>
()
=>
mockSyncData
,
verificationInfo
:
()
=>
()
=>
mockVerificationData
,
});
});
// TODO: Replace this spec with a template spec, once the UI has been hooked up in the next MR.
it
(
'
creates the correct replicationItems array
'
,
()
=>
{
expect
(
wrapper
.
vm
.
replicationItems
).
toStrictEqual
(
expectedData
);
});
});
});
});
locale/gitlab.pot
View file @
00a8f465
...
...
@@ -14356,6 +14356,9 @@ msgstr ""
msgid "Geo|Geo sites"
msgstr ""
msgid "Geo|Geo supports replication of many data types."
msgstr ""
msgid "Geo|Go to the primary site"
msgstr ""
...
...
@@ -14464,6 +14467,12 @@ msgstr ""
msgid "Geo|Replication Details"
msgstr ""
msgid "Geo|Replication Details Desktop"
msgstr ""
msgid "Geo|Replication Details Mobile"
msgstr ""
msgid "Geo|Replication details"
msgstr ""
...
...
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