summaryrefslogtreecommitdiffstats
path: root/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
diff options
context:
space:
mode:
Diffstat (limited to 'polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html')
-rw-r--r--polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html432
1 files changed, 413 insertions, 19 deletions
diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
index 2ed7952a90..36507073ff 100644
--- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
+++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
@@ -1,4 +1,5 @@
<!--
+@license
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,8 +25,19 @@ limitations under the License.
//
// - Gerrit.Nav.View.CHANGE:
// - `changeNum`, required, String: the numeric ID of the change.
+ // - `project`, optional, String: the project name.
+ // - `patchNum`, optional, Number: the patch for the right-hand-side of
+ // the diff.
+ // - `basePatchNum`, optional, Number: the patch for the left-hand-side
+ // of the diff. If `basePatchNum` is provided, then `patchNum` must
+ // also be provided.
+ // - `edit`, optional, Boolean: whether or not to load the file list with
+ // edit controls.
//
// - Gerrit.Nav.View.SEARCH:
+ // - `query`, optional, String: the literal search query. If provided,
+ // the string will be used as the query, and all other params will be
+ // ignored.
// - `owner`, optional, String: the owner name.
// - `project`, optional, String: the project name.
// - `branch`, optional, String: the branch name.
@@ -34,19 +46,39 @@ limitations under the License.
// - `statuses`, optional, Array<String>: the list of change statuses to
// search for. If more than one is provided, the search will OR them
// together.
+ // - `offset`, optional, Number: the offset for the query.
//
// - Gerrit.Nav.View.DIFF:
// - `changeNum`, required, String: the numeric ID of the change.
// - `path`, required, String: the filepath of the diff.
- // - `patchNum`, required, Number, the patch for the right-hand-side of
+ // - `patchNum`, required, Number: the patch for the right-hand-side of
// the diff.
- // - `basePatchNum`, optional, Number, the patch for the left-hand-side
+ // - `basePatchNum`, optional, Number: the patch for the left-hand-side
// of the diff. If `basePatchNum` is provided, then `patchNum` must
// also be provided.
- // - `lineNum`, optional, Number, the line number to be selected on load.
- // - `leftSide`, optional, Boolean, if a `lineNum` is provided, a value
+ // - `lineNum`, optional, Number: the line number to be selected on load.
+ // - `leftSide`, optional, Boolean: if a `lineNum` is provided, a value
// of true selects the line from base of the patch range. False by
// default.
+ //
+ // - Gerrit.Nav.View.GROUP:
+ // - `groupId`, required, String: the ID of the group.
+ // - `detail`, optional, String: the name of the group detail view.
+ // Takes any value from Gerrit.Nav.GroupDetailView.
+ //
+ // - Gerrit.Nav.View.REPO:
+ // - `repoName`, required, String: the name of the repo
+ // - `detail`, optional, String: the name of the repo detail view.
+ // Takes any value from Gerrit.Nav.RepoDetailView.
+ //
+ // - Gerrit.Nav.View.DASHBOARD
+ // - `repo`, optional, String.
+ // - `sections`, optional, Array of objects with `title` and `query`
+ // strings.
+ // - `user`, optional, String.
+ //
+ // - Gerrit.Nav.View.ROOT:
+ // - no possible parameters.
window.Gerrit = window.Gerrit || {};
@@ -57,27 +89,122 @@ limitations under the License.
console.warn('Use of uninitialized routing');
};
+ const EDIT_PATCHNUM = 'edit';
const PARENT_PATCHNUM = 'PARENT';
+ const USER_PLACEHOLDER_PATTERN = /\$\{user\}/g;
+
+ // NOTE: These queries are tested in Java. Any changes made to definitions
+ // here require corresponding changes to:
+ // javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
+ const DEFAULT_SECTIONS = [
+ {
+ // Changes with unpublished draft comments. This section is omitted when
+ // viewing other users, so we don't need to filter anything out.
+ name: 'Has draft comments',
+ query: 'has:draft',
+ selfOnly: true,
+ hideIfEmpty: true,
+ suffixForDashboard: 'limit:10',
+ },
+ {
+ // Changes that are assigned to the viewed user.
+ name: 'Assigned reviews',
+ query: 'assignee:${user} (-is:wip OR owner:self OR assignee:self) ' +
+ 'is:open -is:ignored',
+ hideIfEmpty: true,
+ },
+ {
+ // WIP open changes owned by viewing user. This section is omitted when
+ // viewing other users, so we don't need to filter anything out.
+ name: 'Work in progress',
+ query: 'is:open owner:${user} is:wip',
+ selfOnly: true,
+ hideIfEmpty: true,
+ },
+ {
+ // Non-WIP open changes owned by viewed user. Filter out changes ignored
+ // by the viewing user.
+ name: 'Outgoing reviews',
+ query: 'is:open owner:${user} -is:wip -is:ignored',
+ isOutgoing: true,
+ },
+ {
+ // Non-WIP open changes not owned by the viewed user, that the viewed user
+ // is associated with (as either a reviewer or the assignee). Changes
+ // ignored by the viewing user are filtered out.
+ name: 'Incoming reviews',
+ query: 'is:open -owner:${user} -is:wip -is:ignored ' +
+ '(reviewer:${user} OR assignee:${user})',
+ },
+ {
+ // Open changes the viewed user is CCed on. Changes ignored by the viewing
+ // user are filtered out.
+ name: 'CCed on',
+ query: 'is:open -is:ignored cc:${user}',
+ },
+ {
+ name: 'Recently closed',
+ // Closed changes where viewed user is owner, reviewer, or assignee.
+ // Changes ignored by the viewing user are filtered out, and so are WIP
+ // changes not owned by the viewing user (the one instance of
+ // 'owner:self' is intentional and implements this logic).
+ query: 'is:closed -is:ignored (-is:wip OR owner:self) ' +
+ '(owner:${user} OR reviewer:${user} OR assignee:${user} ' +
+ 'OR cc:${user})',
+ suffixForDashboard: '-age:4w limit:10',
+ },
+ ];
+
window.Gerrit.Nav = {
View: {
ADMIN: 'admin',
- CHANGE: 'change',
AGREEMENTS: 'agreements',
+ CHANGE: 'change',
DASHBOARD: 'dashboard',
DIFF: 'diff',
+ DOCUMENTATION_SEARCH: 'documentation-search',
EDIT: 'edit',
+ GROUP: 'group',
+ PLUGIN_SCREEN: 'plugin-screen',
+ REPO: 'repo',
+ ROOT: 'root',
SEARCH: 'search',
SETTINGS: 'settings',
},
+ GroupDetailView: {
+ MEMBERS: 'members',
+ LOG: 'log',
+ },
+
+ RepoDetailView: {
+ ACCESS: 'access',
+ BRANCHES: 'branches',
+ COMMANDS: 'commands',
+ DASHBOARDS: 'dashboards',
+ TAGS: 'tags',
+ },
+
+ WeblinkType: {
+ CHANGE: 'change',
+ FILE: 'file',
+ PATCHSET: 'patchset',
+ },
+
/** @type {Function} */
_navigate: uninitialized,
/** @type {Function} */
_generateUrl: uninitialized,
+ /** @type {Function} */
+ _generateWeblinks: uninitialized,
+
+ /** @type {Function} */
+ mapCommentlinks: uninitialized,
+
/**
* @param {number=} patchNum
* @param {number|string=} basePatchNum
@@ -90,17 +217,38 @@ limitations under the License.
/**
* Setup router implementation.
- * @param {Function} navigate
- * @param {Function} generateUrl
+ * @param {function(!string)} navigate the router-abstracted equivalent of
+ * `window.location.href = ...`. Takes a string.
+ * @param {function(!Object): string} generateUrl generates a URL given
+ * navigation parameters, detailed in the file header.
+ * @param {function(!Object): string} generateWeblinks weblinks generator
+ * function takes single payload parameter with type property that
+ * determines which
+ * part of the UI is the consumer of the weblinks. type property can
+ * be one of file, change, or patchset.
+ * - For file type, payload will also contain string properties: repo,
+ * commit, file.
+ * - For patchset type, payload will also contain string properties:
+ * repo, commit.
+ * - For change type, payload will also contain string properties:
+ * repo, commit. If server provides weblinks, those will be passed
+ * as options.weblinks property on the main payload object.
+ * @param {function(!Object): Object} mapCommentlinks provides an escape
+ * hatch to modify the commentlinks object, e.g. if it contains any
+ * relative URLs.
*/
- setup(navigate, generateUrl) {
+ setup(navigate, generateUrl, generateWeblinks, mapCommentlinks) {
this._navigate = navigate;
this._generateUrl = generateUrl;
+ this._generateWeblinks = generateWeblinks;
+ this.mapCommentlinks = mapCommentlinks;
},
destroy() {
this._navigate = uninitialized;
this._generateUrl = uninitialized;
+ this._generateWeblinks = uninitialized;
+ this.mapCommentlinks = uninitialized;
},
/**
@@ -112,17 +260,27 @@ limitations under the License.
return this._generateUrl(params);
},
+ getUrlForSearchQuery(query, opt_offset) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.SEARCH,
+ query,
+ offset: opt_offset,
+ });
+ },
+
/**
* @param {!string} project The name of the project.
* @param {boolean=} opt_openOnly When true, only search open changes in
* the project.
+ * @param {string=} opt_host The host in which to search.
* @return {string}
*/
- getUrlForProject(project, opt_openOnly) {
+ getUrlForProjectChanges(project, opt_openOnly, opt_host) {
return this._getUrlFor({
view: Gerrit.Nav.View.SEARCH,
project,
statuses: opt_openOnly ? ['open'] : [],
+ host: opt_host,
});
},
@@ -130,26 +288,30 @@ limitations under the License.
* @param {string} branch The name of the branch.
* @param {string} project The name of the project.
* @param {string=} opt_status The status to search.
+ * @param {string=} opt_host The host in which to search.
* @return {string}
*/
- getUrlForBranch(branch, project, opt_status) {
+ getUrlForBranch(branch, project, opt_status, opt_host) {
return this._getUrlFor({
view: Gerrit.Nav.View.SEARCH,
branch,
project,
statuses: opt_status ? [opt_status] : undefined,
+ host: opt_host,
});
},
/**
* @param {string} topic The name of the topic.
+ * @param {string=} opt_host The host in which to search.
* @return {string}
*/
- getUrlForTopic(topic) {
+ getUrlForTopic(topic, opt_host) {
return this._getUrlFor({
view: Gerrit.Nav.View.SEARCH,
topic,
statuses: ['open', 'merged'],
+ host: opt_host,
});
},
@@ -166,13 +328,34 @@ limitations under the License.
},
/**
+ * Navigate to a search for changes with the given status.
+ * @param {string} status
+ */
+ navigateToStatusSearch(status) {
+ this._navigate(this._getUrlFor({
+ view: Gerrit.Nav.View.SEARCH,
+ statuses: [status],
+ }));
+ },
+
+ /**
+ * Navigate to a search query
+ * @param {string} query
+ * @param {number=} opt_offset
+ */
+ navigateToSearchQuery(query, opt_offset) {
+ return this._navigate(this.getUrlForSearchQuery(query, opt_offset));
+ },
+
+ /**
* @param {!Object} change The change object.
* @param {number=} opt_patchNum
* @param {number|string=} opt_basePatchNum The string 'PARENT' can be
* used for none.
+ * @param {boolean=} opt_isEdit
* @return {string}
*/
- getUrlForChange(change, opt_patchNum, opt_basePatchNum) {
+ getUrlForChange(change, opt_patchNum, opt_basePatchNum, opt_isEdit) {
if (opt_basePatchNum === PARENT_PATCHNUM) {
opt_basePatchNum = undefined;
}
@@ -184,6 +367,8 @@ limitations under the License.
project: change.project,
patchNum: opt_patchNum,
basePatchNum: opt_basePatchNum,
+ edit: opt_isEdit,
+ host: change.internalHost || undefined,
});
},
@@ -207,10 +392,11 @@ limitations under the License.
* @param {number=} opt_patchNum
* @param {number|string=} opt_basePatchNum The string 'PARENT' can be
* used for none.
+ * @param {boolean=} opt_isEdit
*/
- navigateToChange(change, opt_patchNum, opt_basePatchNum) {
+ navigateToChange(change, opt_patchNum, opt_basePatchNum, opt_isEdit) {
this._navigate(this.getUrlForChange(change, opt_patchNum,
- opt_basePatchNum));
+ opt_basePatchNum, opt_isEdit));
},
/**
@@ -219,11 +405,12 @@ limitations under the License.
* @param {number=} opt_patchNum
* @param {number|string=} opt_basePatchNum The string 'PARENT' can be
* used for none.
+ * @param {number|string=} opt_lineNum
* @return {string}
*/
- getUrlForDiff(change, path, opt_patchNum, opt_basePatchNum) {
+ getUrlForDiff(change, path, opt_patchNum, opt_basePatchNum, opt_lineNum) {
return this.getUrlForDiffById(change._number, change.project, path,
- opt_patchNum, opt_basePatchNum);
+ opt_patchNum, opt_basePatchNum, opt_lineNum);
},
/**
@@ -259,24 +446,29 @@ limitations under the License.
/**
* @param {{ _number: number, project: string }} change The change object.
* @param {string} path The file path.
+ * @param {number=} opt_patchNum
* @return {string}
*/
- getEditUrlForDiff(change, path) {
- return this.getEditUrlForDiffById(change._number, change.project, path);
+ getEditUrlForDiff(change, path, opt_patchNum) {
+ return this.getEditUrlForDiffById(change._number, change.project, path,
+ opt_patchNum);
},
/**
* @param {number} changeNum
* @param {string} project The name of the project.
* @param {string} path The file path.
+ * @param {number|string=} opt_patchNum The patchNum the file content
+ * should be based on, or ${EDIT_PATCHNUM} if left undefined.
* @return {string}
*/
- getEditUrlForDiffById(changeNum, project, path) {
+ getEditUrlForDiffById(changeNum, project, path, opt_patchNum) {
return this._getUrlFor({
view: Gerrit.Nav.View.EDIT,
changeNum,
project,
path,
+ patchNum: opt_patchNum || EDIT_PATCHNUM,
});
},
@@ -315,6 +507,29 @@ limitations under the License.
},
/**
+ * @return {string}
+ */
+ getUrlForRoot() {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.ROOT,
+ });
+ },
+
+ /**
+ * @param {string} repo The name of the repo.
+ * @param {string} dashboard The ID of the dashboard, in the form of
+ * '<ref>:<path>'.
+ * @return {string}
+ */
+ getUrlForRepoDashboard(repo, dashboard) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.DASHBOARD,
+ repo,
+ dashboard,
+ });
+ },
+
+ /**
* Navigate to an arbitrary relative URL.
* @param {string} relativeUrl
*/
@@ -325,9 +540,188 @@ limitations under the License.
this._navigate(relativeUrl);
},
+ /**
+ * @param {string} repoName
+ * @return {string}
+ */
+ getUrlForRepo(repoName) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.REPO,
+ repoName,
+ });
+ },
+
+ /**
+ * Navigate to a repo settings page.
+ * @param {string} repoName
+ */
+ navigateToRepo(repoName) {
+ this._navigate(this.getUrlForRepo(repoName));
+ },
+
+ /**
+ * @param {string} repoName
+ * @return {string}
+ */
+ getUrlForRepoTags(repoName) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.REPO,
+ repoName,
+ detail: Gerrit.Nav.RepoDetailView.TAGS,
+ });
+ },
+
+ /**
+ * @param {string} repoName
+ * @return {string}
+ */
+ getUrlForRepoBranches(repoName) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.REPO,
+ repoName,
+ detail: Gerrit.Nav.RepoDetailView.BRANCHES,
+ });
+ },
+
+ /**
+ * @param {string} repoName
+ * @return {string}
+ */
+ getUrlForRepoAccess(repoName) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.REPO,
+ repoName,
+ detail: Gerrit.Nav.RepoDetailView.ACCESS,
+ });
+ },
+
+ /**
+ * @param {string} repoName
+ * @return {string}
+ */
+ getUrlForRepoCommands(repoName) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.REPO,
+ repoName,
+ detail: Gerrit.Nav.RepoDetailView.COMMANDS,
+ });
+ },
+
+ /**
+ * @param {string} repoName
+ * @return {string}
+ */
+ getUrlForRepoDashboards(repoName) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.REPO,
+ repoName,
+ detail: Gerrit.Nav.RepoDetailView.DASHBOARDS,
+ });
+ },
+
+ /**
+ * @param {string} groupId
+ * @return {string}
+ */
+ getUrlForGroup(groupId) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.GROUP,
+ groupId,
+ });
+ },
+
+ /**
+ * @param {string} groupId
+ * @return {string}
+ */
+ getUrlForGroupLog(groupId) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.GROUP,
+ groupId,
+ detail: Gerrit.Nav.GroupDetailView.LOG,
+ });
+ },
+
+ /**
+ * @param {string} groupId
+ * @return {string}
+ */
+ getUrlForGroupMembers(groupId) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.GROUP,
+ groupId,
+ detail: Gerrit.Nav.GroupDetailView.MEMBERS,
+ });
+ },
+
getUrlForSettings() {
return this._getUrlFor({view: Gerrit.Nav.View.SETTINGS});
},
+
+ /**
+ * @param {string} repo
+ * @param {string} commit
+ * @param {string} file
+ * @param {Object=} opt_options
+ * @return {
+ * Array<{label: string, url: string}>|
+ * {label: string, url: string}
+ * }
+ */
+ getFileWebLinks(repo, commit, file, opt_options) {
+ const params = {type: Gerrit.Nav.WeblinkType.FILE, repo, commit, file};
+ if (opt_options) {
+ params.options = opt_options;
+ }
+ return [].concat(this._generateWeblinks(params));
+ },
+
+ /**
+ * @param {string} repo
+ * @param {string} commit
+ * @param {Object=} opt_options
+ * @return {{label: string, url: string}}
+ */
+ getPatchSetWeblink(repo, commit, opt_options) {
+ const params = {type: Gerrit.Nav.WeblinkType.PATCHSET, repo, commit};
+ if (opt_options) {
+ params.options = opt_options;
+ }
+ const result = this._generateWeblinks(params);
+ if (Array.isArray(result)) {
+ return result.pop();
+ } else {
+ return result;
+ }
+ },
+
+ /**
+ * @param {string} repo
+ * @param {string} commit
+ * @param {Object=} opt_options
+ * @return {
+ * Array<{label: string, url: string}>|
+ * {label: string, url: string}
+ * }
+ */
+ getChangeWeblinks(repo, commit, opt_options) {
+ const params = {type: Gerrit.Nav.WeblinkType.CHANGE, repo, commit};
+ if (opt_options) {
+ params.options = opt_options;
+ }
+ return [].concat(this._generateWeblinks(params));
+ },
+
+ getUserDashboard(user = 'self', sections = DEFAULT_SECTIONS,
+ title = '') {
+ sections = sections
+ .filter(section => (user === 'self' || !section.selfOnly))
+ .map(section => Object.assign({}, section, {
+ name: section.name,
+ query: section.query.replace(USER_PLACEHOLDER_PATTERN, user),
+ }));
+ return {title, sections};
+ },
};
})(window);
</script>