PageSourceSearch

https://mozilla-cordova.github.io/status/js/app.js

js mozilla-cordova.github.io collected 2026-10-03 09:38:18 UTC 6,885 bytes, 185 lines download raw bytes

1"use strict";
2
3var dom = React.DOM;
4
5var IssueList = React.createClass({
6    getInitialState: function() {
7        return { onlyPRs: false,
8            filter: '',
9            issues: [] };
10    },
11
12    togglePRs: function() {
13        this.setState({ onlyPRs: !this.state.onlyPRs });
14    },
15
16    applyFilter: function(value) {
17        this.setState({ filter: value });
18    },
19
20    componentDidMount: function() {
21        var issues = [];
22
23        if (window.CORDOVA_STATUS) {
24            issues = issues.concat(CORDOVA_STATUS.issues.map(function(issue) {
25                issue.created_at = new Date(issue.created_at);
26                issue.updated_at = new Date(issue.updated_at);
27                issue.origin = 'github';
28                issue.assigneeName = issue.assignee && issue.assignee.login;
29                issue.assigneeAvatar = issue.assignee && issue.assignee.avatar_url;
30                return issue;
31            }));
32
33        }
34
35        if (window.JIRA_ISSUES) {
36            issues = issues.concat(JIRA_ISSUES.issues.map(function(issue) {
37                issue.created_at = new Date(issue.fields.created);
38                issue.updated_at = new Date(issue.fields.updated);
39                issue.title = issue.fields.summary;
40                issue.html_url = 'https://issues.apache.org/jira/browse/' + issue.key;
41                issue.origin = 'jira';
42                issue.status = issue.fields.status.name;
43                issue.assigneeName = issue.fields.assignee && issue.fields.assignee.name;
44                issue.assigneeAvatar = issue.fields.assignee && issue.fields.assignee.avatarUrls["32x32"];
45                return issue;
46            }));
47        }
48
49        this.setState({ issues: issues });
50    },
51
52    render: function() {
53        var s = this.state;
54        var issues = Array.prototype.slice.call(this.state.issues);
55        issues.sort(function(a, b) {
56            return a.updated_at < b.updated_at ? 1 : -1;
57        });
58
59        return dom.div(
60            null,
61            Toolbar({ togglePRs: this.togglePRs,
62                onlyPRs: s.onlyPRs,
63                onFilter: this.applyFilter,
64                filter: this.state.filter.toLowerCase() }),
65            dom.div(
66                { className: 'issues list-group' },
67                issues.map(function(issue) {
68                    if (s.onlyPRs && (!issue.pull_request || !issue.pull_request.html_url)) {
69                        return null;
70                    }
71
72                    if (s.filter &&
73                        issue.title.toLowerCase().indexOf(s.filter) === -1 &&
74                        (!issue.repo || issue.repo.toLowerCase().indexOf(s.filter) === -1)) {
75                        return null;
76                    }
77
78                    return dom.a(
79                        {
80                            className: 'issue list-group-item',
81                            href: issue.html_url
82                        },
83                        dom.i({ className: "icon " + issue.origin }),
84                        dom.span({className: "updated-at"}, moment(issue.updated_at).format('MM-DD-YYYY')),
85                        dom.span(null, issue.title),
86                        issue.repo ?
87                            dom.span({ className: "label label-default" }, issue.repo) :
88                            dom.span({ className: "label label-info" }, issue.status),
89                        (issue.pull_request && issue.pull_request.html_url) ?
90                            dom.span({ className: "label label-danger" }, 'PR') : null,
91                        issue.assigneeName ?
92                            dom.span(null,
93                                dom.span(null, "Assigned to:"),
94                                dom.img({className: "avatar", src: issue.assigneeAvatar}),
95                                issue.assigneeName) :
96                            null
97                    );
98                }.bind(this))
99            )
100        );
101    }
102});
103
104var RepoList = React.createClass({
105    getInitialState: function() {
106        return { issues: [],
107            repos: [] };
108    },
109
110    componentDidMount: function() {
111        this.setState({ repos: window.CORDOVA_STATUS.repos || [] });
112    },
113
114    render: function() {
115        var repos = this.state.repos.sort(function(a, b) {
116            return a.repo.localeCompare(b.repo);
117        });
118
119        return dom.div(
120            null,
121            repos.map(function(repo) {
122                var nodes = [],
123                    prs = [];
124
125                nodes.push(dom.div({ className: '5u status-table-name'},
126                    dom.a({ href: "http://github.com/apache/" + repo.repo },
127                        repo.repo)
128                ));
129
130                if (repo.apachePullRequests && repo.apachePullRequests.length > 0) {
131
132                    repo.apachePullRequests.forEach(function(pr) {
133                        prs.push(
134                            dom.div({ className: 'truncate'},
135                                dom.a({href: pr.user_url}, pr.user),
136                                ': ',
137                                dom.a({href: pr.url, title: pr.title}, pr.title)
138                            ));
139                    });
140                }
141
142                if (repo.mentionsPullRequests && repo.mentionsPullRequests.length > 0) {
143
144                    prs.push(dom.span(null, 'Firefox mentions:'));
145
146                    repo.mentionsPullRequests.forEach(function(pr) {
147                        prs.push(
148                            dom.div({ className: 'truncate'},
149                                dom.a({href: pr.user_url}, pr.user),
150                                ': ',
151                                dom.a({href: pr.url, title: pr.title}, pr.title)
152                            ));
153                    });
154                }
155
156                nodes.push(dom.div({ className: '7u status-table-status'}, prs.length && prs || dom.span(null, 'none')));
157
158                return dom.div({ className: 'row flush list-group-item' }, nodes);
159            })
160        );
161    }
162});
163
164var Toolbar = React.createClass({
165    onFilter: function(e) {
166        this.props.onFilter(e.target.value);
167    },
168
169    render: function() {
170        return dom.div(
171            { className: 'clearfix toolbar form-inline' },
172            dom.div({ className: 'col-sm-6 form-group' },
173                dom.label(null, 'Filter:'),
174                dom.input({ className: 'form-control',
175                    value: this.props.filter,
176                    onChange: this.onFilter })),
177            dom.div({ className: 'col-sm-6' },
178                dom.button({ className: 'btn ' + (this.props.onlyPRs ? 'btn-warning' : 'btn-info'),
179                    onClick: this.props.togglePRs }, 'Only PRs'))
180        );
181    }
182});
183
184React.renderComponent(RepoList(), document.getElementById('repos'));
185React.renderComponent(IssueList(), document.getElementById('issues'));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.