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
9222c789
Commit
9222c789
authored
Jan 24, 2018
by
Filipa Lacerda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moves more mr widget components into vue files
Adds i18n Adds better test coverage
parent
a585ae27
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
267 additions
and
256 deletions
+267
-256
app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.js
...ge_request_widget/components/states/mr_widget_checking.js
+0
-18
app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue
...e_request_widget/components/states/mr_widget_checking.vue
+23
-0
app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.js
...erge_request_widget/components/states/mr_widget_closed.js
+0
-35
app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.vue
...rge_request_widget/components/states/mr_widget_closed.vue
+48
-0
app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.js
...e_request_widget/components/states/mr_widget_conflicts.js
+0
-47
app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
..._request_widget/components/states/mr_widget_conflicts.vue
+61
-0
app/assets/javascripts/vue_merge_request_widget/dependencies.js
...sets/javascripts/vue_merge_request_widget/dependencies.js
+3
-3
changelogs/unreleased/fl-mr-widget-refactor.yml
changelogs/unreleased/fl-mr-widget-refactor.yml
+5
-0
spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js
...ue_mr_widget/components/states/mr_widget_checking_spec.js
+23
-13
spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js
.../vue_mr_widget/components/states/mr_widget_closed_spec.js
+45
-61
spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
...e_mr_widget/components/states/mr_widget_conflicts_spec.js
+59
-79
No files found.
app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.js
deleted
100644 → 0
View file @
a585ae27
import
statusIcon
from
'
../mr_widget_status_icon
'
;
export
default
{
name
:
'
MRWidgetChecking
'
,
components
:
{
statusIcon
,
},
template
:
`
<div class="mr-widget-body media">
<status-icon status="loading" :show-disabled-button="true" />
<div class="media-body space-children">
<span class="bold">
Checking ability to merge automatically
</span>
</div>
</div>
`
,
};
app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue
0 → 100644
View file @
9222c789
<
script
>
import
statusIcon
from
'
../mr_widget_status_icon
'
;
export
default
{
name
:
'
MRWidgetChecking
'
,
components
:
{
statusIcon
,
},
};
</
script
>
<
template
>
<div
class=
"mr-widget-body media"
>
<status-icon
status=
"loading"
:show-disabled-button=
"true"
/>
<div
class=
"media-body space-children"
>
<span
class=
"bold"
>
{{
s__
(
"
mrWidget|Checking ability to merge automatically
"
)
}}
</span>
</div>
</div>
</
template
>
app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.js
deleted
100644 → 0
View file @
a585ae27
import
mrWidgetAuthorTime
from
'
../../components/mr_widget_author_time
'
;
import
statusIcon
from
'
../mr_widget_status_icon
'
;
export
default
{
name
:
'
MRWidgetClosed
'
,
props
:
{
mr
:
{
type
:
Object
,
required
:
true
},
},
components
:
{
'
mr-widget-author-and-time
'
:
mrWidgetAuthorTime
,
statusIcon
,
},
template
:
`
<div class="mr-widget-body media">
<status-icon status="warning" />
<div class="media-body">
<mr-widget-author-and-time
actionText="Closed by"
:author="mr.metrics.closedBy"
:dateTitle="mr.metrics.closedAt"
:dateReadable="mr.metrics.readableClosedAt"
/>
<section class="mr-info-list">
<p>
The changes were not merged into
<a
:href="mr.targetBranchPath"
class="label-branch">
{{mr.targetBranch}}</a>
</p>
</section>
</div>
</div>
`
,
};
app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.vue
0 → 100644
View file @
9222c789
<
script
>
import
mrWidgetAuthorTime
from
'
../../components/mr_widget_author_time
'
;
import
statusIcon
from
'
../mr_widget_status_icon
'
;
export
default
{
name
:
'
MRWidgetClosed
'
,
components
:
{
mrWidgetAuthorTime
,
statusIcon
,
},
props
:
{
/* TODO: This is providing all store and service down when it
only needs metrics and targetBranch */
mr
:
{
type
:
Object
,
required
:
true
,
default
:
()
=>
({}),
},
},
};
</
script
>
<
template
>
<div
class=
"mr-widget-body media"
>
<status-icon
status=
"warning"
/>
<div
class=
"media-body"
>
<mr-widget-author-time
:action-text=
"s__('mrWidget|Closed by')"
:author=
"mr.metrics.closedBy"
:date-title=
"mr.metrics.closedAt"
:date-readable=
"mr.metrics.readableClosedAt"
/>
<section
class=
"mr-info-list"
>
<p>
{{
s__
(
"
mrWidget|The changes were not merged into
"
)
}}
<a
:href=
"mr.targetBranchPath"
class=
"label-branch"
>
{{
mr
.
targetBranch
}}
</a>
</p>
</section>
</div>
</div>
</
template
>
app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.js
deleted
100644 → 0
View file @
a585ae27
import
statusIcon
from
'
../mr_widget_status_icon
'
;
export
default
{
name
:
'
MRWidgetConflicts
'
,
props
:
{
mr
:
{
type
:
Object
,
required
:
true
},
},
components
:
{
statusIcon
,
},
template
:
`
<div class="mr-widget-body media">
<status-icon
status="warning"
:show-disabled-button="true" />
<div class="media-body space-children">
<span
v-if="mr.shouldBeRebased"
class="bold">
Fast-forward merge is not possible.
To merge this request, first rebase locally.
</span>
<template v-else>
<span class="bold">
There are merge conflicts<span v-if="!mr.canMerge">.</span>
<span v-if="!mr.canMerge">
Resolve these conflicts or ask someone with write access to this repository to merge it locally
</span>
</span>
<a
v-if="mr.canMerge && mr.conflictResolutionPath"
:href="mr.conflictResolutionPath"
class="js-resolve-conflicts-button btn btn-default btn-xs">
Resolve conflicts
</a>
<a
v-if="mr.canMerge"
class="js-merge-locally-button btn btn-default btn-xs"
data-toggle="modal"
href="#modal_merge_info">
Merge locally
</a>
</template>
</div>
</div>
`
,
};
app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
0 → 100644
View file @
9222c789
<
script
>
import
statusIcon
from
'
../mr_widget_status_icon
'
;
export
default
{
name
:
'
MRWidgetConflicts
'
,
components
:
{
statusIcon
,
},
props
:
{
/* TODO: This is providing all store and service down when it
only needs a few props */
mr
:
{
type
:
Object
,
required
:
true
,
default
:
()
=>
({}),
},
},
};
</
script
>
<
template
>
<div
class=
"mr-widget-body media"
>
<status-icon
status=
"warning"
:show-disabled-button=
"true"
/>
<div
class=
"media-body space-children"
>
<span
v-if=
"mr.shouldBeRebased"
class=
"bold"
>
{{
s__
(
`mrWidget|Fast-forward merge is not possible.
To merge this request, first rebase locally.`
)
}}
</span>
<template
v-else
>
<span
class=
"bold"
>
{{
s__
(
"
mrWidget|There are merge conflicts
"
)
}}
<span
v-if=
"!mr.canMerge"
>
.
</span>
<span
v-if=
"!mr.canMerge"
>
{{
s__
(
`mrWidget|Resolve these conflicts or ask someone
with write access to this repository to merge it locally`
)
}}
</span>
</span>
<a
v-if=
"mr.canMerge && mr.conflictResolutionPath"
:href=
"mr.conflictResolutionPath"
class=
"js-resolve-conflicts-button btn btn-default btn-xs"
>
{{
s__
(
"
mrWidget|Resolve conflicts
"
)
}}
</a>
<button
v-if=
"mr.canMerge"
class=
"js-merge-locally-button btn btn-default btn-xs"
data-toggle=
"modal"
data-target=
"#modal_merge_info"
>
{{
s__
(
"
mrWidget|Merge locally
"
)
}}
</button>
</
template
>
</div>
</div>
</template>
app/assets/javascripts/vue_merge_request_widget/dependencies.js
View file @
9222c789
...
...
@@ -18,11 +18,11 @@ export { default as WidgetDeployment } from './components/mr_widget_deployment';
export
{
default
as
WidgetRelatedLinks
}
from
'
./components/mr_widget_related_links
'
;
export
{
default
as
MergedState
}
from
'
./components/states/mr_widget_merged
'
;
export
{
default
as
FailedToMerge
}
from
'
./components/states/mr_widget_failed_to_merge
'
;
export
{
default
as
ClosedState
}
from
'
./components/states/mr_widget_closed
'
;
export
{
default
as
ClosedState
}
from
'
./components/states/mr_widget_closed
.vue
'
;
export
{
default
as
MergingState
}
from
'
./components/states/mr_widget_merging
'
;
export
{
default
as
WipState
}
from
'
./components/states/mr_widget_wip
'
;
export
{
default
as
ArchivedState
}
from
'
./components/states/mr_widget_archived.vue
'
;
export
{
default
as
ConflictsState
}
from
'
./components/states/mr_widget_conflicts
'
;
export
{
default
as
ConflictsState
}
from
'
./components/states/mr_widget_conflicts
.vue
'
;
export
{
default
as
NothingToMergeState
}
from
'
./components/states/mr_widget_nothing_to_merge
'
;
export
{
default
as
MissingBranchState
}
from
'
./components/states/mr_widget_missing_branch
'
;
export
{
default
as
NotAllowedState
}
from
'
./components/states/mr_widget_not_allowed
'
;
...
...
@@ -34,7 +34,7 @@ export { default as PipelineFailedState } from './components/states/mr_widget_pi
export
{
default
as
MergeWhenPipelineSucceedsState
}
from
'
./components/states/mr_widget_merge_when_pipeline_succeeds
'
;
export
{
default
as
RebaseState
}
from
'
./components/states/mr_widget_rebase.vue
'
;
export
{
default
as
AutoMergeFailed
}
from
'
./components/states/mr_widget_auto_merge_failed.vue
'
;
export
{
default
as
CheckingState
}
from
'
./components/states/mr_widget_checking
'
;
export
{
default
as
CheckingState
}
from
'
./components/states/mr_widget_checking
.vue
'
;
export
{
default
as
MRWidgetStore
}
from
'
ee/vue_merge_request_widget/stores/mr_widget_store
'
;
export
{
default
as
MRWidgetService
}
from
'
ee/vue_merge_request_widget/services/mr_widget_service
'
;
export
{
default
as
eventHub
}
from
'
./event_hub
'
;
...
...
changelogs/unreleased/fl-mr-widget-refactor.yml
0 → 100644
View file @
9222c789
---
title
:
Refactors mr widget components into vue files and adds i18n
merge_request
:
author
:
type
:
other
spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js
View file @
9222c789
import
Vue
from
'
vue
'
;
import
checkingComponent
from
'
~/vue_merge_request_widget/components/states/mr_widget_checking
'
;
import
checkingComponent
from
'
~/vue_merge_request_widget/components/states/mr_widget_checking.vue
'
;
import
mountComponent
from
'
../../../helpers/vue_mount_component_helper
'
;
describe
(
'
MRWidgetChecking
'
,
()
=>
{
describe
(
'
template
'
,
()
=>
{
it
(
'
should have correct elements
'
,
()
=>
{
const
Component
=
Vue
.
extend
(
checkingComponent
);
const
el
=
new
Component
({
el
:
document
.
createElement
(
'
div
'
),
}).
$el
;
let
Component
;
let
vm
;
expect
(
el
.
classList
.
contains
(
'
mr-widget-body
'
)).
toBeTruthy
();
expect
(
el
.
querySelector
(
'
button
'
).
classList
.
contains
(
'
btn-success
'
)).
toBeTruthy
();
expect
(
el
.
querySelector
(
'
button
'
).
disabled
).
toBeTruthy
();
expect
(
el
.
innerText
).
toContain
(
'
Checking ability to merge automatically
'
);
expect
(
el
.
querySelector
(
'
i
'
)).
toBeDefined
();
beforeEach
(()
=>
{
Component
=
Vue
.
extend
(
checkingComponent
);
vm
=
mountComponent
(
Component
);
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
it
(
'
renders disabled button
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
button
'
).
getAttribute
(
'
disabled
'
)).
toEqual
(
'
disabled
'
);
});
it
(
'
renders loading icon
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.mr-widget-icon i
'
).
classList
).
toContain
(
'
fa-spinner
'
);
});
it
(
'
renders information about merging
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.media-body
'
).
textContent
.
trim
()).
toEqual
(
'
Checking ability to merge automatically
'
);
});
});
spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js
View file @
9222c789
import
Vue
from
'
vue
'
;
import
closedComponent
from
'
~/vue_merge_request_widget/components/states/mr_widget_closed
'
;
import
closedComponent
from
'
~/vue_merge_request_widget/components/states/mr_widget_closed.vue
'
;
import
mountComponent
from
'
../../../helpers/vue_mount_component_helper
'
;
const
mr
=
{
targetBranch
:
'
good-branch
'
,
targetBranchPath
:
'
/good-branch
'
,
describe
(
'
MRWidgetClosed
'
,
()
=>
{
let
vm
;
beforeEach
(()
=>
{
const
Component
=
Vue
.
extend
(
closedComponent
);
vm
=
mountComponent
(
Component
,
{
mr
:
{
metrics
:
{
mergedBy
:
{},
mergedAt
:
'
mergedUpdatedAt
'
,
closedBy
:
{
name
:
'
Fatih Acet
'
,
username
:
'
fatihacet
'
,
name
:
'
Administrator
'
,
username
:
'
root
'
,
webUrl
:
'
http://localhost:3000/root
'
,
avatarUrl
:
'
http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon
'
,
},
closedAt
:
'
closedEventUpdatedAt
'
,
mergedAt
:
'
Jan 24, 2018 1:02pm GMT+0000
'
,
closedAt
:
'
Jan 24, 2018 1:02pm GMT+0000
'
,
readableMergedAt
:
''
,
readableClosedAt
:
'
'
,
readableClosedAt
:
'
less than a minute ago
'
,
},
updatedAt
:
'
mrUpdatedAt
'
,
closedAt
:
'
1 day ago
'
,
};
const
createComponent
=
()
=>
{
const
Component
=
Vue
.
extend
(
closedComponent
);
return
new
Component
({
el
:
document
.
createElement
(
'
div
'
),
propsData
:
{
mr
},
targetBranchPath
:
'
/twitter/flight/commits/so_long_jquery
'
,
targetBranch
:
'
so_long_jquery
'
,
}
});
});
};
describe
(
'
MRWidgetClosed
'
,
()
=>
{
describe
(
'
props
'
,
()
=>
{
it
(
'
should have props
'
,
()
=>
{
const
mrProp
=
closedComponent
.
props
.
mr
;
expect
(
mrProp
.
type
instanceof
Object
).
toBeTruthy
();
expect
(
mrProp
.
required
).
toBeTruthy
();
});
});
describe
(
'
components
'
,
()
=>
{
it
(
'
should have components added
'
,
()
=>
{
expect
(
closedComponent
.
components
[
'
mr-widget-author-and-time
'
]).
toBeDefined
();
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
describe
(
'
template
'
,
()
=>
{
let
vm
;
let
el
;
beforeEach
(()
=>
{
vm
=
createComponent
();
el
=
vm
.
$el
;
it
(
'
renders warning icon
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-ci-status-icon-warning
'
)).
not
.
toBeNull
();
});
afterEach
(()
=>
{
vm
.
$destroy
();
it
(
'
renders closed by information with author and time
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-mr-widget-author
'
).
textContent
.
trim
().
replace
(
/
\s\s
+/g
,
'
'
),
).
toContain
(
'
Closed by Administrator less than a minute ago
'
,
);
});
it
(
'
should have correct elements
'
,
()
=>
{
expect
(
el
.
querySelector
(
'
h4
'
).
textContent
).
toContain
(
'
Closed by
'
);
expect
(
el
.
querySelector
(
'
h4
'
).
textContent
).
toContain
(
mr
.
metrics
.
closedBy
.
name
);
expect
(
el
.
textContent
).
toContain
(
'
The changes were not merged into
'
);
expect
(
el
.
querySelector
(
'
.label-branch
'
).
getAttribute
(
'
href
'
)).
toEqual
(
mr
.
targetBranchPath
);
expect
(
el
.
querySelector
(
'
.label-branch
'
).
textContent
).
toContain
(
mr
.
targetBranch
);
it
(
'
links to the user that closed the MR
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.author-link
'
).
getAttribute
(
'
href
'
)).
toEqual
(
'
http://localhost:3000/root
'
);
});
it
(
'
should use closedEvent updatedAt as tooltip title
'
,
()
=>
{
it
(
'
renders information about the changes not being merged
'
,
()
=>
{
expect
(
el
.
querySelector
(
'
time
'
).
getAttribute
(
'
title
'
),
).
toBe
(
'
closedEventUpdatedAt
'
);
vm
.
$el
.
querySelector
(
'
.mr-info-list
'
).
textContent
.
trim
().
replace
(
/
\s\s
+/g
,
'
'
),
).
toContain
(
'
The changes were not merged into so_long_jquery
'
);
});
it
(
'
renders link for target branch
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.label-branch
'
).
getAttribute
(
'
href
'
)).
toEqual
(
'
/twitter/flight/commits/so_long_jquery
'
);
});
});
spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
View file @
9222c789
import
Vue
from
'
vue
'
;
import
conflictsComponent
from
'
~/vue_merge_request_widget/components/states/mr_widget_conflicts
'
;
import
conflictsComponent
from
'
~/vue_merge_request_widget/components/states/mr_widget_conflicts
.vue
'
;
import
mountComponent
from
'
../../../helpers/vue_mount_component_helper
'
;
const
ConflictsComponent
=
Vue
.
extend
(
conflictsComponent
);
const
path
=
'
/conflicts
'
;
describe
(
'
MRWidgetConflicts
'
,
()
=>
{
describe
(
'
props
'
,
()
=>
{
it
(
'
should have props
'
,
()
=>
{
const
{
mr
}
=
conflictsComponent
.
props
;
let
Component
;
let
vm
;
const
path
=
'
/conflicts
'
;
expect
(
mr
.
type
instanceof
Object
).
toBeTruthy
();
expect
(
mr
.
required
).
toBeTruthy
(
);
beforeEach
(()
=>
{
Component
=
Vue
.
extend
(
conflictsComponent
);
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
describe
(
'
template
'
,
()
=>
{
describe
(
'
when allowed to merge
'
,
()
=>
{
let
vm
;
beforeEach
(()
=>
{
vm
=
mountComponent
(
Conflicts
Component
,
{
vm
=
mountComponent
(
Component
,
{
mr
:
{
canMerge
:
true
,
conflictResolutionPath
:
path
,
...
...
@@ -28,10 +25,6 @@ describe('MRWidgetConflicts', () => {
});
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
it
(
'
should tell you about conflicts without bothering other people
'
,
()
=>
{
expect
(
vm
.
$el
.
textContent
).
toContain
(
'
There are merge conflicts
'
);
expect
(
vm
.
$el
.
textContent
).
not
.
toContain
(
'
ask someone with write access
'
);
...
...
@@ -56,22 +49,16 @@ describe('MRWidgetConflicts', () => {
});
describe
(
'
when user does not have permission to merge
'
,
()
=>
{
let
vm
;
beforeEach
(()
=>
{
vm
=
mountComponent
(
Conflicts
Component
,
{
vm
=
mountComponent
(
Component
,
{
mr
:
{
canMerge
:
false
,
},
});
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
it
(
'
should show proper message
'
,
()
=>
{
expect
(
vm
.
$el
.
textContent
).
toContain
(
'
ask someone with write access
'
);
expect
(
vm
.
$el
.
textContent
.
trim
().
replace
(
/
\s\s
+/g
,
'
'
)
).
toContain
(
'
ask someone with write access
'
);
});
it
(
'
should not have action buttons
'
,
()
=>
{
...
...
@@ -82,24 +69,17 @@ describe('MRWidgetConflicts', () => {
});
describe
(
'
when fast-forward or semi-linear merge enabled
'
,
()
=>
{
let
vm
;
beforeEach
(()
=>
{
vm
=
mountComponent
(
Conflicts
Component
,
{
vm
=
mountComponent
(
Component
,
{
mr
:
{
shouldBeRebased
:
true
,
},
});
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
it
(
'
should tell you to rebase locally
'
,
()
=>
{
expect
(
vm
.
$el
.
textContent
).
toContain
(
'
Fast-forward merge is not possible.
'
);
expect
(
vm
.
$el
.
textContent
).
toContain
(
'
To merge this request, first rebase locally
'
);
});
expect
(
vm
.
$el
.
textContent
.
trim
().
replace
(
/
\s\s
+/g
,
'
'
)).
toContain
(
'
Fast-forward merge is not possible.
'
);
expect
(
vm
.
$el
.
textContent
.
trim
().
replace
(
/
\s\s
+/g
,
'
'
)).
toContain
(
'
To merge this request, first rebase locally
'
);
});
});
});
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