Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Add copy story ID to clipboard at collapsed story card #789

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions app/assets/javascripts/components/story/StoryCopyIdClipboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from "react";
import Clipboard from "react-clipboard.js";

const StoryCopyIdClipboard = ({ id }) => {
return (
<Clipboard
data-clipboard-text={`#${id}`}
component="button"
className="story-id"
title={I18n.t("story.events.copy_id")}
>
#{id}
</Clipboard>
);
};

export default StoryCopyIdClipboard;
1 change: 1 addition & 0 deletions app/assets/javascripts/templates/story.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
</span>
</div>
<div class="story-title">
<div data-story-id-copy-clipboard></div>
<% if (story.get('labels')) { %>
<span class="tags">
<% _.each(story.labels(), function(value) { %>
Expand Down
23 changes: 9 additions & 14 deletions app/assets/javascripts/views/story_view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import storyTemplate from 'templates/story.ejs';
import alertTemplate from 'templates/alert.ejs';
import storyHoverTemplate from 'templates/story_hover.ejs';
import noteTemplate from 'templates/note.ejs';
import StoryCopyIdClipboard from '../components/story/StoryCopyIdClipboard';

const LOCAL_STORY_REGEXP = /(?!\s|\b)(#\d+)(?!\w)/g;

Expand Down Expand Up @@ -541,34 +542,28 @@ const StoryView = FormView.extend({
},

renderCollapsed: function(isGuest) {

this.$el.removeClass('editing');
this.$el.html(this.template({story: this.model, view: this}));
this.$el.toggleClass('collapsed-iteration',
!this.model.get('isVisible') &&
!this.isSearchResult);
this.$el.toggleClass('collapsed-iteration', !this.model.get('isVisible') && !this.isSearchResult);

const stateButtons = this.$('[data-story-state-buttons]').get(0)
if(stateButtons) {
ReactDOM.render(
<StoryStateButtons
events={this.model.events()}
/>,
stateButtons
);
ReactDOM.render(<StoryStateButtons events={this.model.events()} />, stateButtons);
}

const estimateButtons = this.$('[data-story-estimate-buttons]').get(0)
if(estimateButtons) {
ReactDOM.render(
<StoryEstimateButtons
points={this.model.point_values()}
onClick={this.estimate}
/>,
<StoryEstimateButtons points={this.model.point_values()} onClick={this.estimate} />,
estimateButtons
);
}

const copyStoryIdClipboardLink = this.$('[data-story-id-copy-clipboard]').get(0)
if(copyStoryIdClipboardLink) {
ReactDOM.render(<StoryCopyIdClipboard id={this.id} />, copyStoryIdClipboardLink)
}

if (isGuest) { this.$el.find('.state-actions').find('.transition').prop('disabled', true) }
},

Expand Down
19 changes: 18 additions & 1 deletion app/assets/stylesheets/_screen.scss
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,14 @@ div.story-controls {
}

div.story-title {
margin-left: 65px;
margin-left: 50px;
word-wrap: break-word;
}

div.story-title div[data-story-id-copy-clipboard] {
display: inline;
}

.unestimated div.story-title {
font-style: italic;
}
Expand All @@ -239,6 +243,19 @@ div.story-title abbr.initials {
border: none;
}

div.story-title {
.story-id {
cursor: pointer;
color: $blue-4;
font-weight: bold;
border: none;

&:hover {
text-decoration: underline;
}
}
}

.input-group-btn .btn-clipboard-id {
padding-top: 6px;
}
Expand Down
36 changes: 36 additions & 0 deletions spec/javascripts/components/story/story_copy_id_clipboard_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { mount, shallow } from 'enzyme';

import StoryCopyIdClipboard from 'components/story/StoryCopyIdClipboard';

describe('<StoryCopyIdClipboard />', function() {
beforeEach(function() {
sinon.stub(I18n, 't');
});

afterEach(function() {
I18n.t.restore();
});

it("should render story id text", function() {
const wrapper = mount(
<StoryCopyIdClipboard id={70} />
);
expect(wrapper.find('.story-id').at(0).text()).toBe('#70');
});

it("should render story id data-clipboard-text", function() {
const wrapper = mount(
<StoryCopyIdClipboard id={70} />
);
expect(wrapper.find('[data-clipboard-text]')).toExist();
});

it("should render copy id title", function() {
shallow(
<StoryCopyIdClipboard id={70} />
);
expect(I18n.t).toHaveBeenCalledWith('story.events.copy_id');
});

});
Loading