Merge "Collapsing related changes"
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list-experimental/gr-related-changes-list-experimental.ts b/polygerrit-ui/app/elements/change/gr-related-changes-list-experimental/gr-related-changes-list-experimental.ts
index a66bb04..5134b72 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list-experimental/gr-related-changes-list-experimental.ts
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list-experimental/gr-related-changes-list-experimental.ts
@@ -14,7 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import {html} from 'lit-html';
+import {html, nothing} from 'lit-html';
+import {classMap} from 'lit-html/directives/class-map';
import {GrLitElement} from '../../lit/gr-lit-element';
import {customElement, property, css} from 'lit-element';
import {sharedStyles} from '../../../styles/shared-styles';
@@ -34,6 +35,10 @@
): x is ChangeInfo | ParsedChangeInfo {
return (x as ChangeInfo)._number !== undefined;
}
+
+/** What is the maximum number of shown changes in collapsed list? */
+const MAX_CHANGES_WHEN_COLLAPSED = 3;
+
@customElement('gr-related-changes-list-experimental')
export class GrRelatedChangesListExperimental extends GrLitElement {
@property()
@@ -56,12 +61,14 @@
color: var(--deemphasized-text-color);
padding-left: var(--metadata-horizontal-padding);
}
- h4,
- section gr-related-change {
+ h4 {
display: flex;
}
+ /* This is a hacky solution from old gr-related-change-list
+ * TODO(milutin): find layout without needing it
+ */
h4:before,
- section gr-related-change:before {
+ gr-related-change:before {
content: ' ';
flex-shrink: 0;
width: 1.2em;
@@ -77,25 +84,48 @@
const submittedTogetherChanges = this._submittedTogether?.changes ?? [];
const countNonVisibleChanges =
this._submittedTogether?.non_visible_changes ?? 0;
+ const showWhenCollapsedPredicate = this.showWhenCollapsedPredicateFactory(
+ submittedTogetherChanges.length,
+ submittedTogetherChanges.findIndex(relatedChange =>
+ this._changesEqual(relatedChange, this.change)
+ )
+ );
return html` <section
id="submittedTogether"
?hidden=${!submittedTogetherChanges?.length &&
!this._submittedTogether?.non_visible_changes}
>
<h4 class="title">Submitted together</h4>
- ${submittedTogetherChanges.map(
- relatedChange =>
- html`<gr-related-change
- .currentChange="${this._changesEqual(relatedChange, this.change)}"
- .change="${relatedChange}"
- ></gr-related-change>`
- )}
+ <gr-related-collapse .length=${submittedTogetherChanges.length}>
+ ${submittedTogetherChanges.map(
+ (relatedChange, index) =>
+ html`<gr-related-change
+ class="${classMap({
+ ['show-when-collapsed']: showWhenCollapsedPredicate(index),
+ })}"
+ .currentChange="${this._changesEqual(relatedChange, this.change)}"
+ .change="${relatedChange}"
+ ></gr-related-change>`
+ )}
+ </gr-related-collapse>
<div class="note" ?hidden=${!countNonVisibleChanges}>
(+ ${pluralize(countNonVisibleChanges, 'non-visible change')})
</div>
</section>`;
}
+ showWhenCollapsedPredicateFactory(length: number, highlightIndex: number) {
+ return (index: number) => {
+ if (highlightIndex === 0) return index <= MAX_CHANGES_WHEN_COLLAPSED - 1;
+ if (highlightIndex === length - 1)
+ return index >= length - MAX_CHANGES_WHEN_COLLAPSED;
+ return (
+ highlightIndex - MAX_CHANGES_WHEN_COLLAPSED + 2 <= index &&
+ index <= highlightIndex + MAX_CHANGES_WHEN_COLLAPSED - 2
+ );
+ };
+ }
+
reload() {
if (!this.change) return Promise.reject(new Error('change missing'));
return this.restApiService
@@ -137,6 +167,68 @@
}
}
+@customElement('gr-related-collapse')
+export class GrRelatedCollapse extends GrLitElement {
+ @property()
+ showAll = false;
+
+ @property()
+ length = 0;
+
+ static get styles() {
+ return [
+ sharedStyles,
+ css`
+ gr-button {
+ display: flex;
+ }
+ gr-button:before {
+ content: ' ';
+ flex-shrink: 0;
+ width: 1.2em;
+ }
+ .collapsed ::slotted(gr-related-change.show-when-collapsed) {
+ display: flex;
+ }
+ .collapsed ::slotted(gr-related-change) {
+ display: none;
+ }
+ ::slotted(gr-related-change) {
+ display: flex;
+ }
+ `,
+ ];
+ }
+
+ render() {
+ const collapsible = this.length > MAX_CHANGES_WHEN_COLLAPSED;
+ const items = html` <div
+ class="${!this.showAll && collapsible ? 'collapsed' : ''}"
+ >
+ <slot></slot>
+ </div>`;
+ let button = nothing;
+ if (collapsible) {
+ if (this.showAll) {
+ button = html`<gr-button link="" @click="${this.toggle}"
+ >Show less</gr-button
+ >`;
+ } else {
+ button = html`<gr-button link="" @click="${this.toggle}"
+ >+ ${this.length - MAX_CHANGES_WHEN_COLLAPSED} more</gr-button
+ >`;
+ }
+ }
+
+ return html`${items}${button}`;
+ }
+
+ private toggle(e: MouseEvent) {
+ e.stopPropagation();
+ this.showAll = !this.showAll;
+ }
+}
+
@customElement('gr-related-change')
export class GrRelatedChange extends GrLitElement {
@property()
@@ -227,6 +319,7 @@
declare global {
interface HTMLElementTagNameMap {
'gr-related-changes-list-experimental': GrRelatedChangesListExperimental;
+ 'gr-related-collapse': GrRelatedCollapse;
'gr-related-change': GrRelatedChange;
}
}