UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

90 lines (89 loc) 3.7 kB
import * as React from "react"; import { ObservableValue } from '../Core/Observable'; export class BaseMasterDetailsContext { constructor(initialLayer, onExit) { this.hideDetailsPanel = new ObservableValue(false); this.getCurrentLayer = () => { return this.payload; }; this.getStack = () => { return this.payloadStack; }; this.push = (newLayer) => { this.payloadStack.push(newLayer); if (newLayer.onPushed) { newLayer.onPushed(this); } this.payload.value = this.payloadStack[this.payloadStack.length - 1]; }; this.pop = () => { const returnVal = this.payloadStack.pop(); if (returnVal && returnVal.onPopped) { returnVal.onPopped(this); } if (this.payloadStack.length > 0) { this.payload.value = this.payloadStack[this.payloadStack.length - 1]; } else { this.onExit(); } return returnVal; }; this.setDetailsPanelVisbility = (visible) => { this.hideDetailsPanel.value = !visible; }; this.payload = new ObservableValue(initialLayer); this.payloadStack = [initialLayer]; this.onExit = onExit; if (initialLayer.onPushed) { initialLayer.onPushed(this); } } } export const MasterDetailsContext = React.createContext(new BaseMasterDetailsContext({ key: "", masterPanelContent: {}, detailsContent: { renderContent: () => React.createElement("div", null) }, selectedMasterItem: new ObservableValue(null) }, () => undefined)); /** * Binds a selection, for things like Tree and List, to an Observable (usually IMasterDetailsLayer.selectedMasterItem) * When selection changes, it will update the observable * Will set selection to current payload item if it exists; works nicely with createChildPayload when drilling down * Supports single-select only */ export function bindSelectionToObservable(selection, itemProvider, observable) { const assignFunction = (selectedRanges) => { if (selectedRanges[0]) { const index = selectedRanges[0].beginIndex; observable.value = itemProvider.value[index]; } }; // Do this before we subscribe so we don't accidentally call assignFunction const matchingIndex = itemProvider.value.findIndex(x => x === observable.value); if (matchingIndex >= 0) { selection.select(matchingIndex); } selection.subscribe(assignFunction); } /** * Creates a layer that's a logical child of an existing layer * Useful for drill-down scenarios * Ensures correct typing of the child layer for common scenarios * @param key Unique identifier for the child layer * @param masterPanelDetails Master panel details for the child layer * @param detailsContent Detail rendering info for the child layer * @param initialSelectedItem Usually the clicked item from your current layer's detail view * @param parentLayer The parent layer, usually the currently displayed layer */ export function createChildLayer(key, masterPanelDetails, detailsContent, initialSelectedItem, parentLayer, onPushed, ariaLabel) { return { key: key, masterPanelContent: masterPanelDetails, detailsContent: detailsContent, selectedMasterItem: new ObservableValue(initialSelectedItem), parentItem: parentLayer.selectedMasterItem.value, onPushed: onPushed, ariaLabel: ariaLabel }; }