Merge view state of DIFF and EDIT into CHANGE The motivation is that we want to move more control from views into models. In particular we would like to the change model (and the change view model) to control the patch range (patchNum and basePatchNum). The DIFF/CHANGE/EDIT views already share a change model, but they still had their own view model each. We want to works towards a unified view of which patchset range is currently selected. A clearly visible sign of the current messy design is that router model still has the references to change number and patchset numbers. This change will enable us to move this information into change view model in a follow-up change. We are not super happy with how the view models deal with hierarchies. The `childView` property and lots of optional properties that only make sense for some child views do not seem to be the ultimate clean design to this problem. But we are consistent here with other views (see admin and repo views), and we believe that this is better handled in a larger, separate effort. Our change definitely makes this simpler to achieve. In a follow-up we consider to add a wrapper between app-element and change-/diff-/edit-view. That will allow us to remove the app-element dependency on change model. And we will have a clear element that can act as the change model provider. Release-Notes: skip Google-Bug-Id: b/247042673 Change-Id: Ibf04e462ee76d830dbab02003288f4d7e99ecd13
diff --git a/polygerrit-ui/app/models/views/change.ts b/polygerrit-ui/app/models/views/change.ts index 31d511a..9701b54 100644 --- a/polygerrit-ui/app/models/views/change.ts +++ b/polygerrit-ui/app/models/views/change.ts
@@ -25,19 +25,33 @@ import {define} from '../dependency'; import {Model} from '../model'; import {ViewState} from './base'; +import {createDiffUrl} from './diff'; +import {createEditUrl} from './edit'; + +export enum ChangeChildView { + OVERVIEW = 'OVERVIEW', + DIFF = 'DIFF', + EDIT = 'EDIT', +} export interface ChangeViewState extends ViewState { view: GerritView.CHANGE; + childView: ChangeChildView; changeNum: NumericChangeId; repo: RepoName; - edit?: boolean; patchNum?: RevisionPatchSetNum; basePatchNum?: BasePatchSetNum; commentId?: UrlEncodedCommentId; + + // TODO: Move properties that only apply to OVERVIEW into a submessage. + + edit?: boolean; /** This can be a string only for plugin provided tabs. */ tab?: Tab | string; + // TODO: Move properties that only apply to CHECKS tab into a submessage. + /** Checks related view state */ /** selected patchset for check runs (undefined=latest) */ @@ -61,6 +75,20 @@ forceReload?: boolean; /** triggers opening the reply dialog */ openReplyDialog?: boolean; + + /** These properties apply to the DIFF child view only. */ + diffView?: { + path?: string; + lineNum?: number; + leftSide?: boolean; + commentLink?: boolean; + }; + + /** These properties apply to the EDIT child view only. */ + editView?: { + path?: string; + lineNum?: number; + }; } /** @@ -70,7 +98,7 @@ */ export type CreateChangeUrlObject = Omit< ChangeViewState, - 'view' | 'changeNum' | 'repo' + 'view' | 'childView' | 'changeNum' | 'repo' > & { change: Pick<ChangeInfo, '_number' | 'project'>; }; @@ -82,7 +110,9 @@ } export function objToState( - obj: CreateChangeUrlObject | Omit<ChangeViewState, 'view'> + obj: + | (CreateChangeUrlObject & {childView: ChangeChildView}) + | Omit<ChangeViewState, 'view'> ): ChangeViewState { if (isCreateChangeUrlObject(obj)) { return { @@ -95,10 +125,24 @@ return {...obj, view: GerritView.CHANGE}; } +export function createChangeViewUrl(state: ChangeViewState): string { + switch (state.childView) { + case ChangeChildView.OVERVIEW: + return createChangeUrl(state); + case ChangeChildView.DIFF: + return createDiffUrl(state); + case ChangeChildView.EDIT: + return createEditUrl(state); + } +} + export function createChangeUrl( - obj: CreateChangeUrlObject | Omit<ChangeViewState, 'view'> + obj: CreateChangeUrlObject | Omit<ChangeViewState, 'view' | 'childView'> ) { - const state: ChangeViewState = objToState(obj); + const state: ChangeViewState = objToState({ + ...obj, + childView: ChangeChildView.OVERVIEW, + }); let range = getPatchRangeExpression(state); if (range.length) { range = '/' + range; @@ -156,6 +200,8 @@ define<ChangeViewModel>('change-view-model'); export class ChangeViewModel extends Model<ChangeViewState | undefined> { + public readonly childView$ = select(this.state$, state => state?.childView); + public readonly tab$ = select(this.state$, state => state?.tab); public readonly checksPatchset$ = select(