• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CenterForOpenScience / ember-osf-web / 13772013636

10 Mar 2025 06:25PM UTC coverage: 66.561% (-0.04%) from 66.602%
13772013636

Pull #2522

github

web-flow
Merge 0d3673ad9 into 36dbe1bd5
Pull Request #2522: Feature/b and i 25 01

3132 of 5141 branches covered (60.92%)

Branch coverage included in aggregate %.

56 of 80 new or added lines in 15 files covered. (70.0%)

2 existing lines in 2 files now uncovered.

7947 of 11504 relevant lines covered (69.08%)

190.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.59
/lib/osf-components/addon/components/node-card/component.ts
1
import { tagName } from '@ember-decorators/component';
2
import Component from '@ember/component';
3
import { action, computed } from '@ember/object';
4
import { inject as service } from '@ember/service';
5
import config from 'ember-osf-web/config/environment';
6
import Store from '@ember-data/store';
7

8
import { layout } from 'ember-osf-web/decorators/component';
9
import Node, { NodeType } from 'ember-osf-web/models/node';
10
import Registration, {
11
    RegistrationReviewStates,
12
} from 'ember-osf-web/models/registration';
13
import Analytics from 'ember-osf-web/services/analytics';
14
import pathJoin from 'ember-osf-web/utils/path-join';
15
import Toast from 'ember-toastr/services/toast';
16

17
import { tracked } from '@glimmer/tracking';
18
import { task } from 'ember-concurrency';
19
import { waitFor } from '@ember/test-waiters';
20
import RouterService from '@ember/routing/router-service';
21
import SchemaResponseModel, {
22
    RevisionReviewStates,
23
} from 'ember-osf-web/models/schema-response';
24
import Intl from 'ember-intl/services/intl';
25
import RegistrationModel from 'ember-osf-web/models/registration';
26
import { taskFor } from 'ember-concurrency-ts';
27
import captureException, {
28
    getApiErrorMessage,
29
} from 'ember-osf-web/utils/capture-exception';
30
import CustomItemMetadataRecordModel from 'ember-osf-web/models/custom-item-metadata-record';
31
import { assert } from '@ember/debug';
32
import Media from 'ember-responsive';
33
import template from './template';
34
import styles from './styles';
35

36
const {
37
    OSF: { url: baseURL },
38
} = config;
1✔
39

40
@layout(template, styles)
41
@tagName('')
42
export default class NodeCard extends Component {
43
    @service analytics!: Analytics;
44
    @service router!: RouterService;
45
    @service store!: Store;
46
    @service toast!: Toast;
47
    @service intl!: Intl;
48
    @service media!: Media;
49

50
    // Optional parameters
51
    node?: Node | Registration;
52
    delete?: (node: Node) => void;
53
    showTags = false;
330✔
54
    readOnly = false;
330✔
55

56
    // Private properties
57
    searchUrl = pathJoin(baseURL, 'search');
330✔
58
    @tracked resourceType?: string;
59
    @tracked latestSchemaResponse!: SchemaResponseModel;
60
    @tracked showNewUpdateModal = false;
38✔
61
    @tracked isOpenResourceType = false;
29✔
62

63
    @computed('readOnly', 'node', 'node.{nodeType,userHasWritePermission}')
64
    get showDropdown() {
65
        return (
67✔
66
            !this.readOnly &&
229✔
67
            this.node &&
68
            this.node.nodeType === NodeType.Fork &&
69
            this.node.userHasWritePermission
70
        );
71
    }
72

73
    @task
74
    @waitFor
75
    async getLatestRevision(registration: RegistrationModel) {
76
        assert('getLatestRevision requires a registration', registration);
38✔
77
        if (
38✔
78
            registration.reviewsState === RegistrationReviewStates.Accepted ||
50✔
79
            registration.reviewsState === RegistrationReviewStates.Embargo
80
        ) {
81
            try {
27✔
82
                const revisions = await registration.queryHasMany(
27✔
83
                    'schemaResponses',
84
                );
85
                if (revisions) {
27!
86
                    this.latestSchemaResponse = revisions[0];
27✔
87
                }
88
            } catch (e) {
NEW
89
                const errorMessage = this.intl.t(
×
90
                    'node_card.schema_response_error',
91
                );
NEW
92
                captureException(e, { errorMessage });
×
UNCOV
93
                this.toast.error(getApiErrorMessage(e), errorMessage);
×
94
            }
95
        }
96
    }
97

98
    @task
99
    @waitFor
100
    async getGuidMetadata() {
NEW
101
        const guidRecord = await this.store.findRecord('guid', this.node?.id, {
×
102
            include: 'custom_metadata',
103
            resolve: false,
104
        });
105

106
        const metadataRecord =
NEW
107
            (await guidRecord.customMetadata) as CustomItemMetadataRecordModel;
×
NEW
108
        this.resourceType =
×
109
            metadataRecord?.resourceTypeGeneral ||
×
110
            this.intl.t('node_card.resource-type.none-selected');
111
    }
112

113
    @action
114
    toggleResourceType() {
NEW
115
        this.isOpenResourceType = !this.isOpenResourceType;
×
NEW
116
        if (this.isOpenResourceType && !this.resourceType) {
×
NEW
117
            taskFor(this.getGuidMetadata).perform();
×
118
        }
119
    }
120

121
    didReceiveAttrs() {
122
        if (this.node?.isRegistration) {
330✔
123
            taskFor(this.getLatestRevision).perform(this.node as Registration);
38✔
124
        }
125
    }
126

127
    get isMobile() {
128
        return this.media.isMobile;
67✔
129
    }
130

131
    get shouldAllowUpdate() {
132
        if (this.node instanceof RegistrationModel) {
28!
133
            return (
28✔
134
                this.node.reviewsState === RegistrationReviewStates.Accepted ||
29✔
135
                this.node.reviewsState === RegistrationReviewStates.Embargo
136
            );
137
        }
138
        return false;
×
139
    }
140

141
    get shouldShowViewChangesButton() {
142
        if (this.node instanceof RegistrationModel) {
27!
143
            return (
27✔
144
                this.shouldAllowUpdate &&
108✔
145
                (this.node.revisionState ===
146
                    RevisionReviewStates.RevisionInProgress ||
147
                    this.node.revisionState ===
148
                        RevisionReviewStates.RevisionPendingModeration ||
149
                    this.node.revisionState === RevisionReviewStates.Unapproved)
150
            );
151
        }
152
        return false;
×
153
    }
154

155
    get shouldShowUpdateButton() {
156
        if (
67✔
157
            this.node instanceof RegistrationModel &&
105✔
158
            this.node.userHasAdminPermission
159
        ) {
160
            return (
6✔
161
                this.node.revisionState === RevisionReviewStates.Approved &&
7✔
162
                this.shouldAllowUpdate
163
            );
164
        }
165
        return false;
61✔
166
    }
167
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc