blob: 46d4380133e77684b1142bcf2bd268f1273c8e77 [file] [log] [blame]
// Copyright (C) 2024 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import m from 'mithril';
import {Gate} from '../base/mithril_utils';
import {exists} from '../base/utils';
import {Actions} from '../common/actions';
import {EmptyState} from '../widgets/empty_state';
import {
DragHandle,
getDetailsHeight,
Tab,
TabDropdownEntry,
} from './drag_handle';
import {globals} from './globals';
interface TabWithContent extends Tab {
content: m.Children;
}
export class TabPanel implements m.ClassComponent {
private detailsHeight = getDetailsHeight();
view() {
const tabMan = globals.tabManager;
const tabList = globals.store.state.tabs.openTabs;
const resolvedTabs = tabMan.resolveTabs(tabList);
const tabs = resolvedTabs.map(({uri, tab: tabDesc}): TabWithContent => {
if (tabDesc) {
return {
key: uri,
hasCloseButton: true,
title: tabDesc.content.getTitle(),
content: tabDesc.content.render(),
};
} else {
return {
key: uri,
hasCloseButton: true,
title: 'Tab does not exist',
content: undefined,
};
}
});
// Add the permanent current selection tab to the front of the list of tabs
tabs.unshift({
key: 'current_selection',
title: 'Current Selection',
content: this.renderCurrentSelectionTabContent(),
});
const tabDropdownEntries =
globals.tabManager.tabs.filter((tab) => tab.isEphemeral === false)
.map(({content, uri}): TabDropdownEntry => {
return {
key: uri,
title: content.getTitle(),
onClick: () => globals.dispatch(Actions.showTab({uri})),
};
});
return [
m(DragHandle, {
resize: (height: number) => {
this.detailsHeight = Math.max(height, 0);
},
height: this.detailsHeight,
tabs,
currentTabKey: globals.state.tabs.currentTab,
tabDropdownEntries,
onTabClick: (key) => globals.dispatch(Actions.showTab({uri: key})),
onTabClose: (key) => globals.dispatch(Actions.hideTab({uri: key})),
}),
m(
'.details-panel-container',
{
style: {height: `${this.detailsHeight}px`},
},
tabs.map(({key, content}) => {
const active = key === globals.state.tabs.currentTab;
return m(Gate, {open: active}, content);
}),
),
];
}
private renderCurrentSelectionTabContent(): m.Children {
const cs = globals.state.currentSelection;
if (!exists(cs)) {
return m(EmptyState, {
className: 'pf-noselection',
header: 'No selection',
detail: 'Please select something',
});
}
const sectionReg = globals.tabManager.currentSelectionSections;
const allSections = Array.from(sectionReg.values());
// Get the first "truthy" current selection section
const section =
allSections.map((dp) => dp.render(cs)).find((panel) => panel);
if (!Boolean(section)) {
return m(EmptyState, {
className: 'pf-noselection',
header: 'No details available',
detail: `Selection kind: '${cs.kind}'`,
icon: 'warning',
});
} else {
return section;
}
}
}