Skip to content

Commit 9330ce6

Browse files
authored
Merge pull request #2298 from uditijmehta/feature/my-preprints-preprint-card
[ENG-6009] Create Preprint Card
2 parents 586d4e5 + 2853cd4 commit 9330ce6

File tree

11 files changed

+484
-26
lines changed

11 files changed

+484
-26
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { render } from '@ember/test-helpers';
2+
import { hbs } from 'ember-cli-htmlbars';
3+
import { setupMirage } from 'ember-cli-mirage/test-support';
4+
import { setupIntl, TestContext } from 'ember-intl/test-support';
5+
import { setupRenderingTest } from 'ember-qunit';
6+
import { module, test } from 'qunit';
7+
8+
import { OsfLinkRouterStub } from 'ember-osf-web/tests/integration/helpers/osf-link-router-stub';
9+
10+
module('Integration | Component | preprint-card', hooks => {
11+
setupRenderingTest(hooks);
12+
setupMirage(hooks);
13+
setupIntl(hooks);
14+
15+
hooks.beforeEach(function(this: TestContext) {
16+
this.store = this.owner.lookup('service:store');
17+
this.intl = this.owner.lookup('service:intl');
18+
});
19+
20+
test('it renders', async function(this: TestContext, assert) {
21+
this.owner.unregister('service:router');
22+
this.owner.register('service:router', OsfLinkRouterStub);
23+
const preprint = server.create('preprint', {
24+
tags: ['a', 'b', 'c'],
25+
description: 'Through the night',
26+
});
27+
server.create('contributor', { preprint, index: 0, bibliographic: true });
28+
server.create('contributor', { preprint, index: 1, bibliographic: true });
29+
server.create('contributor', { preprint, index: 2, bibliographic: true });
30+
const preprintModel = await this.store.findRecord(
31+
'preprint', preprint.id, { include: ['bibliographic_contributors'] },
32+
);
33+
this.set('preprint', preprintModel);
34+
35+
await render(hbs`
36+
<Preprints::-Components::PreprintCard
37+
@preprint={{this.preprint}}
38+
@showTags={{true}}
39+
/>
40+
`);
41+
assert.dom('[data-test-preprint-title]').exists('Preprint title exists');
42+
assert.dom('[data-test-preprint-title]').hasText(preprintModel.title, 'Node title is corrent');
43+
assert.dom('[data-test-contributors-label]').exists('Contributors label exists');
44+
assert.dom('[data-test-contributors-label]').hasText(
45+
this.intl.t('node_card.contributors'),
46+
'Contributors label is correct',
47+
);
48+
});
49+
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { tagName } from '@ember-decorators/component';
2+
import Component from '@ember/component';
3+
import config from 'ember-osf-web/config/environment';
4+
5+
import { layout } from 'ember-osf-web/decorators/component';
6+
import Preprint from 'ember-osf-web/models/preprint';
7+
import pathJoin from 'ember-osf-web/utils/path-join';
8+
import { Permission } from 'ember-osf-web/models/osf-model';
9+
10+
import template from './template';
11+
import styles from './styles';
12+
13+
const { OSF: { url: baseURL } } = config;
14+
15+
@layout(template, styles)
16+
@tagName('')
17+
export default class PreprintCard extends Component {
18+
19+
preprint?: Preprint;
20+
delete?: (preprint: Preprint) => void;
21+
showTags = false;
22+
readOnly = false;
23+
24+
searchUrl = pathJoin(baseURL, 'search');
25+
26+
get shouldShowUpdateButton() {
27+
return this.preprint && this.preprint.currentUserPermissions.includes(Permission.Admin);
28+
}
29+
30+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// stylelint-disable max-nesting-depth, selector-max-compound-selectors
2+
3+
.preprint-card {
4+
width: 100%;
5+
margin: 1px 0;
6+
7+
.card-contents {
8+
display: block;
9+
flex-direction: row;
10+
position: relative;
11+
display: block;
12+
padding: 10px 15px;
13+
margin-bottom: -1px;
14+
background-color: #fff;
15+
border: 1px solid #ddd;
16+
17+
.heading {
18+
display: flex;
19+
flex-direction: column;
20+
flex-wrap: wrap;
21+
justify-content: flex-start;
22+
align-items: flex-start;
23+
width: 100%;
24+
25+
:global .ember-content-placeholders-heading__title {
26+
height: 1em;
27+
margin-top: 5px;
28+
margin-bottom: 5px;
29+
30+
&:first-child {
31+
width: 100%;
32+
}
33+
}
34+
}
35+
}
36+
}
37+
38+
.label-danger {
39+
background-color: $brand-danger;
40+
}
41+
42+
.heading > span {
43+
line-height: 1.5;
44+
}
45+
46+
.label-info {
47+
background-color: darken($brand-info, 15%);
48+
}
49+
50+
.label-primary {
51+
background-color: #337ab7;
52+
}
53+
54+
.label {
55+
padding: 0.2em 0.6em 0.3em;
56+
font-size: 75%;
57+
font-weight: 700;
58+
color: #fff;
59+
text-align: center;
60+
white-space: nowrap;
61+
vertical-align: baseline;
62+
border-radius: 0.25em;
63+
display: block;
64+
margin-top: 5px;
65+
}
66+
67+
.osf-link {
68+
margin-left: 5px;
69+
margin-top: 2px;
70+
font-weight: bold;
71+
}
72+
73+
.osf-link.mobile {
74+
margin-left: 0;
75+
}
76+
77+
.body {
78+
width: 80%;
79+
80+
&.mobile {
81+
width: 90%;
82+
}
83+
}
84+
85+
dl {
86+
margin-bottom: 10px;
87+
88+
div {
89+
display: flex;
90+
91+
dt {
92+
width: 110px;
93+
margin-right: 5px;
94+
}
95+
96+
dd {
97+
flex: 1;
98+
}
99+
}
100+
}
101+
102+
.tags {
103+
margin-top: 2px;
104+
}
105+
106+
.link {
107+
composes: Button from 'osf-components/components/button/styles.scss';
108+
composes: SecondaryButton from 'osf-components/components/button/styles.scss';
109+
composes: MediumButton from 'osf-components/components/button/styles.scss';
110+
111+
&:hover {
112+
text-decoration: none !important;
113+
}
114+
}
115+
116+
.list-group-item-heading {
117+
margin-top: 0;
118+
margin-bottom: 5px;
119+
}
120+
121+
.update-button {
122+
color: $color-text-blue-dark;
123+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<div
2+
data-test-preprint-card
3+
data-analytics-scope='Preprint Card'
4+
local-class='preprint-card'
5+
>
6+
<div local-class='card-contents'>
7+
<div
8+
local-class='card-body {{if (is-mobile) 'mobile'}}'
9+
>
10+
<h4 local-class='list-group-item-heading heading' data-test-preprint-card-heading>
11+
{{#unless @preprint.public}}
12+
<span>
13+
<FaIcon @icon='lock' />
14+
<EmberTooltip>
15+
{{t 'preprints.preprint_card.private_tooltip'}}
16+
</EmberTooltip>
17+
</span> |
18+
{{/unless}}
19+
<OsfLink
20+
local-class='osf-link {{if (is-mobile) 'mobile'}}'
21+
data-analytics-name='Title'
22+
data-test-preprint-title='{{@preprint.id}}'
23+
@route='resolve-guid'
24+
@models={{array @preprint.id}}
25+
>
26+
{{@preprint.title}}
27+
</OsfLink>
28+
<div local-class='status-label'>
29+
{{#if (eq @preprint.reviewsState 'pending')}}
30+
<span local-class='label label-info'>{{t 'preprints.preprint_card.statuses.pending'}}</span>
31+
{{else if (eq @preprint.reviewsState 'accepted')}}
32+
<span local-class='label label-primary'>{{t 'preprints.preprint_card.statuses.accepted'}}</span>
33+
{{else if (eq @preprint.reviewsState 'rejected')}}
34+
<span local-class='label label-danger'>{{t 'preprints.preprint_card.statuses.rejected'}}</span>
35+
{{/if}}
36+
</div>
37+
</h4>
38+
<div data-test-preprint-card-body local-class='body'>
39+
<dl>
40+
<div>
41+
<dt data-test-provider-label>
42+
{{t 'preprints.preprint_card.provider'}}
43+
</dt>
44+
<dd data-test-provider-value>
45+
{{@preprint.provider.name}}
46+
</dd>
47+
</div>
48+
<div>
49+
<dt data-test-created-timestamp-label>
50+
{{t 'preprints.preprint_card.date_created'}}
51+
</dt>
52+
<dd data-test-created-timestamp-value>
53+
{{moment-format @preprint.dateCreated 'YYYY-MM-DD'}}
54+
</dd>
55+
</div>
56+
<div>
57+
<dt data-test-updated-timestamp-label>
58+
{{t 'preprints.preprint_card.date_modified'}}
59+
</dt>
60+
<dd data-test-updated-timestamp-value>
61+
{{moment-format @preprint.dateModified 'YYYY-MM-DD'}}
62+
</dd>
63+
</div>
64+
<div>
65+
<dt data-test-contributors-label>
66+
{{t 'preprints.preprint_card.contributors'}}
67+
</dt>
68+
<dd>
69+
<ContributorList
70+
@model={{@preprint}}
71+
@shouldLinkUsers={{true}}
72+
/>
73+
</dd>
74+
</div>
75+
{{#if (and this.showTags @preprint.tags)}}
76+
<div>
77+
<dt local-class='tags' data-test-tags-label>
78+
{{t 'preprints.preprint_card.tags'}}
79+
</dt>
80+
<dd>
81+
<TagsWidget
82+
@taggable={{@preprint}}
83+
@inline={{true}}
84+
/>
85+
</dd>
86+
</div>
87+
{{/if}}
88+
</dl>
89+
<div local-class='PreprintButtons'>
90+
<OsfLink
91+
local-class='link'
92+
data-analytics-name='View Preprint'
93+
data-test-view-button='{{@preprint.id}}'
94+
@route='resolve-guid'
95+
@models={{array @preprint.id}}
96+
>
97+
{{t 'preprints.preprint_card.view_button'}}
98+
</OsfLink>
99+
{{#if this.shouldShowUpdateButton}}
100+
<OsfLink
101+
local-class='link update-button'
102+
data-analytics-name='Edit Preprint'
103+
data-test-update-button='{{@preprint.id}}'
104+
@route='preprints.edit'
105+
@models={{array @preprint.provider.id @preprint.id}}
106+
>
107+
{{t 'preprints.preprint_card.update_button'}}
108+
</OsfLink>
109+
{{/if}}
110+
</div>
111+
</div>
112+
</div>
113+
</div>
114+
</div>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Route from '@ember/routing/route';
2+
import requireAuth from 'ember-osf-web/decorators/require-auth';
3+
import { inject as service } from '@ember/service';
4+
import Store from '@ember-data/store';
5+
6+
@requireAuth()
7+
export default class PreprintsMyPreprintsRoute extends Route {
8+
@service store!: Store;
9+
10+
async model() {
11+
const preprints = await this.store.findAll('preprint');
12+
return preprints;
13+
}
14+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// stylelint-disable declaration-property-value-blacklist
2+
// stylelint-disable selector-no-qualifying-type
3+
4+
.ContentBackground {
5+
display: flex;
6+
flex-grow: 1;
7+
z-index: 1;
8+
justify-content: center;
9+
position: relative;
10+
11+
&::before {
12+
content: '';
13+
position: absolute;
14+
top: 0;
15+
left: 0;
16+
width: 100%;
17+
height: 100%;
18+
background-image: url('images/preprints/bg-light.jpg');
19+
background-repeat: no-repeat;
20+
background-size: cover;
21+
filter: grayscale(1);
22+
}
23+
24+
:global(.list-group-item) {
25+
margin-bottom: 20px;
26+
}
27+
28+
:global(.media-desktop),
29+
:global(.media-tablet),
30+
:global(.media-mobile) {
31+
margin-top: -38px;
32+
}
33+
34+
}
35+
36+
.Hero {
37+
display: flex;
38+
flex-direction: column;
39+
width: 100%;
40+
height: 100%;
41+
min-width: 100%;
42+
min-height: 100%;
43+
position: relative;
44+
background: url('images/default-brand/bg-dark.jpg');
45+
background-size: cover;
46+
47+
.Title {
48+
min-height: 150px;
49+
50+
h1 {
51+
color: $color-text-white;
52+
font-weight: 400;
53+
margin-top: 0;
54+
margin-bottom: 0;
55+
padding: 1em 2em;
56+
}
57+
}
58+
}
59+
60+
.GutterBody {
61+
padding-top: 85px;
62+
padding-bottom: 85px;
63+
}

0 commit comments

Comments
 (0)