@kui-shell/plugin-client-common
Version:
Kui plugin that offers stylesheets
161 lines • 7.83 kB
JavaScript
/*
* Copyright 2020 The Kubernetes Authors
*
* 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.
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import React from 'react';
import { decodeHTML } from 'entities/lib/decode.js';
import { i18n } from '@kui-shell/core/mdist/api/i18n';
import { eventBus, eventChannelUnsafe } from '@kui-shell/core/mdist/api/Events';
import { ExecType } from '@kui-shell/core/mdist/api/Command';
import { findThemeByName, getPersistedThemeChoice, getDefaultTheme } from '@kui-shell/core/mdist/api/Themes';
import { NavItem } from '@patternfly/react-core/dist/esm/components/Nav';
import Icons from '../../spi/Icons';
import Tooltip from '../../spi/Tooltip';
import ctrlOrMeta from './ctrlOrMeta';
const strings = i18n('plugin-core-support');
const strings2 = i18n('plugin-client-common');
export default class Tab extends React.PureComponent {
constructor(props) {
super(props);
this._unmounted = false;
this.closeTabRef = React.createRef();
this._onMouseDown = (evt) => {
evt.preventDefault();
evt.stopPropagation();
};
this._onClickNavItem = () => this.props.onSwitchTab(this.props.idx);
this._onKeyPress = (evt) => {
if (evt.key === 'Enter') {
evt.currentTarget.blur();
}
};
this._onClickCloseButton = (evt) => {
evt.stopPropagation();
evt.preventDefault();
this.props.onCloseTab(this.props.idx);
};
this.state = {
title: props.title || strings('Tab'),
processing: false,
isFreshlyCreated: true,
topTabNames: props.topTabNames || 'fixed'
};
this.addCommandEvaluationListeners();
}
componentDidMount() {
if (!this.props.topTabNames) {
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
const { theme } = yield findThemeByName((yield getPersistedThemeChoice()) || (yield getDefaultTheme()));
if (theme.topTabNames && !this._unmounted) {
this.setState({
topTabNames: theme.topTabNames
});
}
}));
}
}
componentWillUnmount() {
this._unmounted = true;
this.removeCommandEvaluationListeners();
}
removeCommandEvaluationListeners() {
eventBus.offCommandStart(this.props.uuid, this.onCommandStart);
eventBus.offCommandComplete(this.props.uuid, this.onCommandStart);
eventChannelUnsafe.off('/theme/change', this.onThemeChange);
}
/**
* Register any command evaluation listeners, i.e. when the REPL finishes evaluating a command.
*
*/
addCommandEvaluationListeners() {
this.onCommandComplete = (event) => {
if (this.props.uuid === event.tab.state.uuid && !this._unmounted) {
if (event.execType !== undefined && event.execType !== ExecType.Nested && event.route) {
// ignore nested, which means one plugin calling another
this.setState({ processing: false });
}
this.setState({ processing: false });
}
};
this.onCommandStart = (event) => {
if (this.props.uuid === event.tab.state.uuid && !this._unmounted) {
if (event.execType !== undefined && event.execType !== ExecType.Nested && event.route) {
// ignore nested, which means one plugin calling another
// debug('got event', event)
if (event.route !== undefined &&
!event.route.match(/^\/(tab|getting\/started)/) // ignore our own events and help
) {
if (this.isUsingCommandName()) {
this.setState({ processing: true, title: event.command || this.state.title, isFreshlyCreated: false });
return;
}
}
this.setState({ processing: true, isFreshlyCreated: false });
}
}
};
this.onThemeChange = ({ themeModel }) => {
if (!this._unmounted) {
this.setState({
topTabNames: themeModel.topTabNames || 'fixed'
});
}
};
eventBus.onCommandStart(this.props.uuid, this.onCommandStart);
eventBus.onCommandComplete(this.props.uuid, this.onCommandComplete);
eventChannelUnsafe.on('/theme/change', this.onThemeChange);
}
isUsingCommandName() {
return this.state.topTabNames === 'command'; // && !document.body.classList.contains('kui--alternate')
}
titleText() {
const content = this.props.title ? this.props.title : strings('Tab');
return decodeHTML(content); // decode html entities such as —
}
get hasCustomLabel() {
return !!this.props.title;
}
get tabIndex() {
return this.props.idx + 1;
}
title() {
if (this.isUsingCommandName()) {
return this.state.title;
}
else {
return this.titleText() + (this.hasCustomLabel ? '' : ' ' + this.tabIndex);
}
}
render() {
const title = this.title();
return (React.createElement(NavItem, { key: title, href: "#", "data-tab-names": this.state.topTabNames, "data-fresh": this.state.isFreshlyCreated, "data-custom-label": this.hasCustomLabel || undefined, "data-custom-label-text": this.props.title || undefined, isActive: this.props.active, styleChildren: false, className: 'kui--tab kui--tab-navigatable' +
(this.props.active ? ' kui--tab--active' : '') +
(this.state.processing ? ' processing' : ''), "data-tab-button-index": this.tabIndex, "aria-label": "tab", onClick: this._onClickNavItem },
React.createElement("input", { tabIndex: -1, className: "kui--tab--label", defaultValue: title, onKeyPress: this._onKeyPress }),
this.props.closeable && (React.createElement(React.Fragment, null,
React.createElement("div", { className: "kui--tab-close", ref: this.closeTabRef, onClick: this._onClickCloseButton, onMouseDown: this._onMouseDown },
React.createElement(Icons, { icon: "WindowClose", focusable: "false", preserveAspectRatio: "xMidYMid meet", "aria-hidden": "true" })),
React.createElement(Tooltip, { reference: this.closeTabRef, position: "bottom" }, strings2('Close this tab', ctrlOrMeta('W')))))));
}
}
//# sourceMappingURL=Tab.js.map