mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Code] Add localization for Code (#42368)
This commit is contained in:
parent
31492e1c12
commit
d423420b90
33 changed files with 1085 additions and 214 deletions
|
@ -17,4 +17,4 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
module.exports = require('../node_modules/moment/min/moment.min.js');
|
||||
module.exports = require('../node_modules/moment/min/moment-with-locales.min.js');
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import GitUrlParse from 'git-url-parse';
|
||||
|
||||
// return true if the git url is valid, otherwise throw Error with
|
||||
|
@ -18,14 +19,22 @@ export function validateGitUrl(
|
|||
if (hostWhitelist && hostWhitelist.length > 0) {
|
||||
const hostSet = new Set(hostWhitelist);
|
||||
if (!hostSet.has(repo.source)) {
|
||||
throw new Error('Git url host is not whitelisted.');
|
||||
throw new Error(
|
||||
i18n.translate('xpack.code.gitUrlUtil.urlNotWhitelistedMessage', {
|
||||
defaultMessage: 'Git url host is not whitelisted.',
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (protocolWhitelist && protocolWhitelist.length > 0) {
|
||||
const protocolSet = new Set(protocolWhitelist);
|
||||
if (!protocolSet.has(repo.protocol)) {
|
||||
throw new Error('Git url protocol is not whitelisted.');
|
||||
throw new Error(
|
||||
i18n.translate('xpack.code.gitUrlUtil.protocolNotWhitelistedMessage', {
|
||||
defaultMessage: 'Git url protocol is not whitelisted.',
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export enum RepoFileStatus {
|
||||
LANG_SERVER_IS_INITIALIZING = 'Language server is initializing.',
|
||||
LANG_SERVER_INITIALIZED = 'Language server initialized.',
|
||||
|
@ -27,6 +29,63 @@ export enum LangServerType {
|
|||
DEDICATED = 'Current file is covered by dedicated language server',
|
||||
}
|
||||
|
||||
export const RepoFileStatusText = {
|
||||
[RepoFileStatus.LANG_SERVER_IS_INITIALIZING]: i18n.translate(
|
||||
'xpack.code.repoFileStatus.langugageServerIsInitializitingMessage',
|
||||
{
|
||||
defaultMessage: 'Language server is initializing.',
|
||||
}
|
||||
),
|
||||
[RepoFileStatus.LANG_SERVER_INITIALIZED]: i18n.translate(
|
||||
'xpack.code.repoFileStatus.languageServerInitializedMessage',
|
||||
{
|
||||
defaultMessage: 'Language server initialized.',
|
||||
}
|
||||
),
|
||||
[RepoFileStatus.INDEXING]: i18n.translate('xpack.code.repoFileStatus.IndexingInProgressMessage', {
|
||||
defaultMessage: 'Indexing in progress.',
|
||||
}),
|
||||
[RepoFileStatus.FILE_NOT_SUPPORTED]: i18n.translate(
|
||||
'xpack.code.repoFileStatus.fileNotSupportedMessage',
|
||||
{
|
||||
defaultMessage: 'Current file is not of a supported language.',
|
||||
}
|
||||
),
|
||||
[RepoFileStatus.REVISION_NOT_INDEXED]: i18n.translate(
|
||||
'xpack.code.repoFileStatus.revisionNotIndexedMessage',
|
||||
{
|
||||
defaultMessage: 'Current revision is not indexed.',
|
||||
}
|
||||
),
|
||||
[RepoFileStatus.LANG_SERVER_NOT_INSTALLED]: i18n.translate(
|
||||
'xpack.code.repoFileStatus.langServerNotInstalledMessage',
|
||||
{
|
||||
defaultMessage: 'Install additional language server to support current file.',
|
||||
}
|
||||
),
|
||||
[RepoFileStatus.FILE_IS_TOO_BIG]: i18n.translate(
|
||||
'xpack.code.repoFileStatus.fileIsTooBigMessage',
|
||||
{
|
||||
defaultMessage: 'Current file is too big.',
|
||||
}
|
||||
),
|
||||
[LangServerType.NONE]: i18n.translate('xpack.code.repoFileStatus.langserverType.noneMessage', {
|
||||
defaultMessage: 'Current file is not supported by any language server.',
|
||||
}),
|
||||
[LangServerType.GENERIC]: i18n.translate(
|
||||
'xpack.code.repoFileStatus.langserverType.genericMessage',
|
||||
{
|
||||
defaultMessage: 'Current file is only covered by generic language server.',
|
||||
}
|
||||
),
|
||||
[LangServerType.DEDICATED]: i18n.translate(
|
||||
'xpack.code.repoFileStatus.langserverType.dedicatedMessage',
|
||||
{
|
||||
defaultMessage: 'Current file is covered by dedicated language server.',
|
||||
}
|
||||
),
|
||||
};
|
||||
|
||||
export enum CTA {
|
||||
SWITCH_TO_HEAD,
|
||||
GOTO_LANG_MANAGE_PAGE,
|
||||
|
|
|
@ -7,17 +7,26 @@
|
|||
import React from 'react';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
import moment from 'moment';
|
||||
|
||||
import 'ui/autoload/all';
|
||||
import 'ui/autoload/styles';
|
||||
import chrome from 'ui/chrome';
|
||||
// @ts-ignore
|
||||
import { uiModules } from 'ui/modules';
|
||||
|
||||
import { APP_TITLE } from '../common/constants';
|
||||
import { App } from './components/app';
|
||||
import { HelpMenu } from './components/help_menu';
|
||||
import { store } from './stores';
|
||||
|
||||
if (chrome.getInjected('codeUiEnabled')) {
|
||||
// TODO the entire Kibana uses moment, we might need to move it to a more common place
|
||||
moment.locale(i18n.getLocale());
|
||||
|
||||
const app = uiModules.get('apps/code');
|
||||
|
||||
app.config(($locationProvider: any) => {
|
||||
|
@ -34,9 +43,11 @@ if (chrome.getInjected('codeUiEnabled')) {
|
|||
|
||||
// render react to DOM
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
</Provider>,
|
||||
<I18nProvider>
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
</Provider>
|
||||
</I18nProvider>,
|
||||
domNode
|
||||
);
|
||||
|
||||
|
@ -55,7 +66,12 @@ if (chrome.getInjected('codeUiEnabled')) {
|
|||
]);
|
||||
|
||||
chrome.helpExtension.set(domNode => {
|
||||
render(<HelpMenu />, domNode);
|
||||
render(
|
||||
<I18nProvider>
|
||||
<HelpMenu />
|
||||
</I18nProvider>,
|
||||
domNode
|
||||
);
|
||||
return () => {
|
||||
unmountComponentAtNode(domNode);
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ReactNode } from 'react';
|
||||
import { SearchScope } from '../../model';
|
||||
|
||||
|
@ -15,17 +16,33 @@ export enum PathTypes {
|
|||
}
|
||||
|
||||
export const SearchScopeText = {
|
||||
[SearchScope.DEFAULT]: 'Search Everything',
|
||||
[SearchScope.REPOSITORY]: 'Search Repositories',
|
||||
[SearchScope.SYMBOL]: 'Search Symbols',
|
||||
[SearchScope.FILE]: 'Search Files',
|
||||
[SearchScope.DEFAULT]: i18n.translate('xpack.code.searchScope.defaultDropDownOptionLabel', {
|
||||
defaultMessage: 'Search Everything',
|
||||
}),
|
||||
[SearchScope.REPOSITORY]: i18n.translate('xpack.code.searchScope.repositoryDropDownOptionLabel', {
|
||||
defaultMessage: 'Search Repositories',
|
||||
}),
|
||||
[SearchScope.SYMBOL]: i18n.translate('xpack.code.searchScope.symbolDropDownOptionLabel', {
|
||||
defaultMessage: 'Search Symbols',
|
||||
}),
|
||||
[SearchScope.FILE]: i18n.translate('xpack.code.searchScope.fileDropDownOptionLabel', {
|
||||
defaultMessage: 'Search Files',
|
||||
}),
|
||||
};
|
||||
|
||||
export const SearchScopePlaceholderText = {
|
||||
[SearchScope.DEFAULT]: 'Type to find anything',
|
||||
[SearchScope.REPOSITORY]: 'Type to find repositories',
|
||||
[SearchScope.SYMBOL]: 'Type to find symbols',
|
||||
[SearchScope.FILE]: 'Type to find files',
|
||||
[SearchScope.DEFAULT]: i18n.translate('xpack.code.searchScope.defaultPlaceholder', {
|
||||
defaultMessage: 'Type to find anything',
|
||||
}),
|
||||
[SearchScope.REPOSITORY]: i18n.translate('xpack.code.searchScope.repositoryPlaceholder', {
|
||||
defaultMessage: 'Type to find repositories',
|
||||
}),
|
||||
[SearchScope.SYMBOL]: i18n.translate('xpack.code.searchScope.symbolPlaceholder', {
|
||||
defaultMessage: 'Type to find symbols',
|
||||
}),
|
||||
[SearchScope.FILE]: i18n.translate('xpack.code.searchScope.filePlaceholder', {
|
||||
defaultMessage: 'Type to find files',
|
||||
}),
|
||||
};
|
||||
|
||||
export interface MainRouteParams {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { parse as parseQuery } from 'querystring';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
@ -19,9 +20,8 @@ import { LanguageSeverTab } from './language_server_tab';
|
|||
import { ProjectTab } from './project_tab';
|
||||
|
||||
enum AdminTabs {
|
||||
projects = 'Repos',
|
||||
roles = 'Roles',
|
||||
languageServers = 'LanguageServers',
|
||||
projects = '0',
|
||||
languageServers = '1',
|
||||
}
|
||||
|
||||
interface Props extends RouteComponentProps {
|
||||
|
@ -56,12 +56,14 @@ class AdminPage extends React.PureComponent<Props, State> {
|
|||
public tabs = [
|
||||
{
|
||||
id: AdminTabs.projects,
|
||||
name: AdminTabs.projects,
|
||||
name: i18n.translate('xpack.code.adminPage.repoTabLabel', { defaultMessage: 'Repositories' }),
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
id: AdminTabs.languageServers,
|
||||
name: 'Language servers',
|
||||
name: i18n.translate('xpack.code.adminPage.langserverTabLabel', {
|
||||
defaultMessage: 'Language servers',
|
||||
}),
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
|
|
@ -8,6 +8,7 @@ import React from 'react';
|
|||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { EuiButton, EuiFlexGroup, EuiSpacer, EuiText } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { capabilities } from 'ui/capabilities';
|
||||
|
||||
import { ImportProject } from './import_project';
|
||||
|
@ -19,15 +20,34 @@ export const EmptyProject = () => {
|
|||
<EuiSpacer size="xl" />
|
||||
<div className="codeTab__projects--emptyHeader">
|
||||
<EuiText>
|
||||
<h1>You don't have any repos yet</h1>
|
||||
<h1>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.repoTab.emptyRepo.noRepositoryText"
|
||||
defaultMessage="You don't have any repos yet"
|
||||
/>
|
||||
</h1>
|
||||
</EuiText>
|
||||
<EuiText color="subdued">
|
||||
{isAdmin && (
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.repoTab.emptyRepo.importFirstRepositoryText"
|
||||
defaultMessage="Let's import your first one"
|
||||
/>
|
||||
</p>
|
||||
)}
|
||||
</EuiText>
|
||||
<EuiText color="subdued">{isAdmin && <p>Let's import your first one</p>}</EuiText>
|
||||
</div>
|
||||
{isAdmin && <ImportProject />}
|
||||
<EuiSpacer />
|
||||
<EuiFlexGroup justifyContent="center">
|
||||
<Link to="/setup-guide">
|
||||
<EuiButton>View the Setup Guide</EuiButton>
|
||||
<EuiButton>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.repoTab.emptyRepo.viewSetupGuideButtonLabel"
|
||||
defaultMessage="View the Setup Guide"
|
||||
/>
|
||||
</EuiButton>
|
||||
</Link>
|
||||
</EuiFlexGroup>
|
||||
</div>
|
||||
|
|
|
@ -13,6 +13,9 @@ import {
|
|||
EuiGlobalToastList,
|
||||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import React, { ChangeEvent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { closeToast, importRepo } from '../../actions';
|
||||
|
@ -71,11 +74,15 @@ class CodeImportProject extends React.PureComponent<
|
|||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiFormRow
|
||||
label="Repository URL"
|
||||
label={i18n.translate('xpack.code.adminPage.repoTab.repositoryUrlTitle', {
|
||||
defaultMessage: 'Repository URL',
|
||||
})}
|
||||
helpText="e.g. https://github.com/Microsoft/TypeScript-Node-Starter"
|
||||
fullWidth
|
||||
isInvalid={this.state.isInvalid}
|
||||
error="The URL shouldn't be empty."
|
||||
error={i18n.translate('xpack.code.adminPage.repoTab.repositoryUrlEmptyText', {
|
||||
defaultMessage: "The URL shouldn't be empty.",
|
||||
})}
|
||||
>
|
||||
<EuiFieldText
|
||||
value={this.state.value}
|
||||
|
@ -97,7 +104,10 @@ class CodeImportProject extends React.PureComponent<
|
|||
onClick={this.submitImportProject}
|
||||
data-test-subj="importRepositoryButton"
|
||||
>
|
||||
Import
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.repoTab.importButtonLabel"
|
||||
defaultMessage="Import"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
EuiTabbedContent,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { InstallationType } from '../../../common/installation';
|
||||
|
@ -51,24 +52,40 @@ const LanguageServerLi = (props: {
|
|||
let button = null;
|
||||
let state = null;
|
||||
if (status === LanguageServerStatus.RUNNING) {
|
||||
state = <EuiText size="xs">Running ...</EuiText>;
|
||||
state = (
|
||||
<EuiText size="xs">
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.langserverTab.runningText"
|
||||
defaultMessage="Running ..."
|
||||
/>
|
||||
</EuiText>
|
||||
);
|
||||
} else if (status === LanguageServerStatus.NOT_INSTALLED) {
|
||||
state = (
|
||||
<EuiText size="xs" color={'subdued'}>
|
||||
Not Installed
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.langserverTab.notInstalledText"
|
||||
defaultMessage="Not Installed"
|
||||
/>
|
||||
</EuiText>
|
||||
);
|
||||
} else if (status === LanguageServerStatus.READY) {
|
||||
state = (
|
||||
<EuiText size="xs" color={'subdued'}>
|
||||
Installed
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.langserverTab.installedText"
|
||||
defaultMessage="Installed"
|
||||
/>
|
||||
</EuiText>
|
||||
);
|
||||
}
|
||||
if (props.languageServer.installationType === InstallationType.Plugin) {
|
||||
button = (
|
||||
<EuiButton size="s" color="secondary" onClick={onInstallClick}>
|
||||
Setup
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.langserverTab.setupButtonLabel"
|
||||
defaultMessage="Setup"
|
||||
/>
|
||||
</EuiButton>
|
||||
);
|
||||
}
|
||||
|
@ -139,12 +156,13 @@ class AdminLanguageSever extends React.PureComponent<Props, State> {
|
|||
<EuiSpacer />
|
||||
<EuiText>
|
||||
<h3>
|
||||
{this.props.languageServers.length}
|
||||
{this.props.languageServers.length > 1 ? (
|
||||
<span> Language servers</span>
|
||||
) : (
|
||||
<span> Language server</span>
|
||||
)}
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.langserverTab.languageServersDescription"
|
||||
defaultMessage="{serverCount} {serverCount, plural, one {Language server} other {Language servers}}"
|
||||
values={{ serverCount: this.props.languageServers.length }}
|
||||
/>
|
||||
</span>
|
||||
</h3>
|
||||
</EuiText>
|
||||
<EuiSpacer />
|
||||
|
@ -186,16 +204,48 @@ const LanguageServerInstruction = (props: {
|
|||
<div>
|
||||
<EuiSpacer />
|
||||
<EuiText grow={false}>
|
||||
<h3>Install</h3>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.langserverTab.setup.installTitle"
|
||||
defaultMessage="Install"
|
||||
/>
|
||||
</h3>
|
||||
<ol>
|
||||
<li>Stop your kibana Code node.</li>
|
||||
<li>Use the following command to install the {props.name} language server.</li>
|
||||
<li>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.langserverTab.setup.stopKibanaDescription"
|
||||
defaultMessage="Stop your kibana Code node."
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.langserverTab.setup.useFollowingCommandToInstallDescription"
|
||||
defaultMessage="Use the following command to install the {name} language server."
|
||||
values={{ name: props.name }}
|
||||
/>
|
||||
</li>
|
||||
</ol>
|
||||
<EuiCodeBlock language="shell">{installCode}</EuiCodeBlock>
|
||||
<h3>Uninstall</h3>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.langserverTab.setup.uninstallTitle"
|
||||
defaultMessage="Uninstall"
|
||||
/>
|
||||
</h3>
|
||||
<ol>
|
||||
<li>Stop your kibana Code node.</li>
|
||||
<li>Use the following command to remove the {props.name} language server.</li>
|
||||
<li>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.langserverTab.setup.stopKibanaDescription"
|
||||
defaultMessage="Stop your kibana Code node."
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.langserverTab.setup.useFollowingCommandToRemoveDescription"
|
||||
defaultMessage="Use the following command to remove the {name} language server."
|
||||
values={{ name: props.name }}
|
||||
/>
|
||||
</li>
|
||||
</ol>
|
||||
<EuiCodeBlock language="shell">
|
||||
bin/kibana-plugin remove {props.pluginName}
|
||||
|
@ -213,14 +263,22 @@ const LanguageServerInstruction = (props: {
|
|||
<EuiOverlayMask>
|
||||
<EuiModal onClose={props.close} maxWidth={false}>
|
||||
<EuiModalHeader>
|
||||
<EuiModalHeaderTitle>Installation Instructions</EuiModalHeaderTitle>
|
||||
<EuiModalHeaderTitle>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.langserverTab.setup.installationInstructionTitle"
|
||||
defaultMessage="Installation Instructions"
|
||||
/>
|
||||
</EuiModalHeaderTitle>
|
||||
</EuiModalHeader>
|
||||
<EuiModalBody>
|
||||
<EuiTabbedContent tabs={tabs} initialSelectedTab={tabs[1]} size={'m'} />
|
||||
</EuiModalBody>
|
||||
<EuiModalFooter>
|
||||
<EuiButton onClick={props.close} fill>
|
||||
Close
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.langserverTab.setup.closeButtonLabel"
|
||||
defaultMessage="Close"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiModalFooter>
|
||||
</EuiModal>
|
||||
|
|
|
@ -18,10 +18,12 @@ import {
|
|||
EuiOverlayMask,
|
||||
EUI_MODAL_CONFIRM_BUTTON,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import moment from 'moment';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Repository, WorkerReservedProgress } from '../../../model';
|
||||
import { deleteRepo, indexRepo, initRepoCommand } from '../../actions';
|
||||
import { RepoState, RepoStatus } from '../../actions/status';
|
||||
|
@ -88,33 +90,70 @@ class CodeProjectItem extends React.PureComponent<
|
|||
let disableRepoLink = false;
|
||||
let hasError = false;
|
||||
if (!status) {
|
||||
footer = <div className="codeFooter">INIT...</div>;
|
||||
footer = (
|
||||
<div className="codeFooter">
|
||||
<FormattedMessage id="xpack.code.repoItem.initText" defaultMessage="INIT..." />
|
||||
</div>
|
||||
);
|
||||
} else if (status.state === RepoState.READY) {
|
||||
footer = (
|
||||
<div className="codeFooter" data-test-subj="repositoryIndexDone">
|
||||
LAST UPDATED: {moment(status.timestamp).fromNow()}
|
||||
<FormattedMessage
|
||||
id="xpack.code.repoItem.lastUpdatedText"
|
||||
defaultMessage="LAST UPDATED"
|
||||
/>
|
||||
:{' '}
|
||||
{moment(status.timestamp)
|
||||
.locale(i18n.getLocale())
|
||||
.fromNow()}
|
||||
</div>
|
||||
);
|
||||
} else if (status.state === RepoState.DELETING) {
|
||||
footer = <div className="codeFooter">DELETING...</div>;
|
||||
footer = (
|
||||
<div className="codeFooter">
|
||||
<FormattedMessage id="xpack.code.repoItem.deletingText" defaultMessage="DELETING..." />
|
||||
</div>
|
||||
);
|
||||
} else if (status.state === RepoState.INDEXING) {
|
||||
footer = (
|
||||
<div className="codeFooter" data-test-subj="repositoryIndexOngoing">
|
||||
INDEXING...
|
||||
<FormattedMessage id="xpack.code.repoItem.indexingText" defaultMessage="INDEXING..." />
|
||||
</div>
|
||||
);
|
||||
} else if (status.state === RepoState.CLONING) {
|
||||
footer = <div className="codeFooter">CLONING...</div>;
|
||||
footer = (
|
||||
<div className="codeFooter">
|
||||
<FormattedMessage id="xpack.code.repoItem.cloningText" defaultMessage="CLONING..." />
|
||||
</div>
|
||||
);
|
||||
} else if (status.state === RepoState.DELETE_ERROR) {
|
||||
footer = <div className="codeFooter codeFooter--error">ERROR DELETE REPO</div>;
|
||||
footer = (
|
||||
<div className="codeFooter codeFooter--error">
|
||||
<FormattedMessage
|
||||
id="xpack.code.repoItem.deleteErrorText"
|
||||
defaultMessage="ERROR DELETE REPO"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
hasError = true;
|
||||
} else if (status.state === RepoState.INDEX_ERROR) {
|
||||
footer = <div className="codeFooter codeFooter--error">ERROR INDEX REPO</div>;
|
||||
footer = (
|
||||
<div className="codeFooter codeFooter--error">
|
||||
<FormattedMessage
|
||||
id="xpack.code.repoItem.indexErrorText"
|
||||
defaultMessage="ERROR INDEX REPO"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
hasError = true;
|
||||
} else if (status.state === RepoState.CLONE_ERROR) {
|
||||
footer = (
|
||||
<div className="codeFooter codeFooter--error">
|
||||
ERROR CLONING REPO
|
||||
<FormattedMessage
|
||||
id="xpack.code.repoItem.cloneErrorText"
|
||||
defaultMessage="ERROR CLONING REPO"
|
||||
/>
|
||||
|
||||
<EuiToolTip position="top" content={status.errorMessage}>
|
||||
<EuiIcon type="iInCircle" />
|
||||
</EuiToolTip>
|
||||
|
@ -161,7 +200,10 @@ class CodeProjectItem extends React.PureComponent<
|
|||
>
|
||||
<EuiIcon type="gear" />
|
||||
<EuiText size="xs" color="subdued">
|
||||
Settings
|
||||
<FormattedMessage
|
||||
id="xpack.code.repoItem.settingsButtonLabel"
|
||||
defaultMessage="Settings"
|
||||
/>
|
||||
</EuiText>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
|
@ -177,7 +219,10 @@ class CodeProjectItem extends React.PureComponent<
|
|||
>
|
||||
<EuiIcon type="indexSettings" />
|
||||
<EuiText size="xs" color="subdued">
|
||||
Reindex
|
||||
<FormattedMessage
|
||||
id="xpack.code.repoItem.reindexButtonLabel"
|
||||
defaultMessage="Reindex"
|
||||
/>
|
||||
</EuiText>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
|
@ -193,7 +238,10 @@ class CodeProjectItem extends React.PureComponent<
|
|||
>
|
||||
<EuiIcon type="trash" color="danger" />
|
||||
<EuiText size="xs" color="subdued">
|
||||
Delete
|
||||
<FormattedMessage
|
||||
id="xpack.code.repoItem.deleteButtonLabel"
|
||||
defaultMessage="Delete"
|
||||
/>
|
||||
</EuiText>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
|
@ -244,11 +292,17 @@ class CodeProjectItem extends React.PureComponent<
|
|||
return (
|
||||
<EuiOverlayMask>
|
||||
<EuiConfirmModal
|
||||
title="Reindex this repository?"
|
||||
title={i18n.translate('xpack.code.repoItem.reindexConfirmTitle', {
|
||||
defaultMessage: 'Reindex this repository?',
|
||||
})}
|
||||
onCancel={this.closeReindexModal}
|
||||
onConfirm={this.confirmReindex}
|
||||
cancelButtonText="No, don't do it"
|
||||
confirmButtonText="Yes, do it"
|
||||
cancelButtonText={i18n.translate('xpack.code.repoItem.cancelButtonText', {
|
||||
defaultMessage: "No, don't do it",
|
||||
})}
|
||||
confirmButtonText={i18n.translate('xpack.code.repoItem.confirmButtonText', {
|
||||
defaultMessage: 'Yes, do it',
|
||||
})}
|
||||
defaultFocusedButton={EUI_MODAL_CONFIRM_BUTTON}
|
||||
/>
|
||||
</EuiOverlayMask>
|
||||
|
@ -259,11 +313,17 @@ class CodeProjectItem extends React.PureComponent<
|
|||
return (
|
||||
<EuiOverlayMask>
|
||||
<EuiConfirmModal
|
||||
title="Delete this repository?"
|
||||
title={i18n.translate('xpack.code.repoItem.deleteConfirmTitle', {
|
||||
defaultMessage: 'Delete this repository?',
|
||||
})}
|
||||
onCancel={this.closeDeleteModal}
|
||||
onConfirm={this.confirmDelete}
|
||||
cancelButtonText="No, don't do it"
|
||||
confirmButtonText="Yes, do it"
|
||||
cancelButtonText={i18n.translate('xpack.code.repoItem.cancelButtonText', {
|
||||
defaultMessage: "No, don't do it",
|
||||
})}
|
||||
confirmButtonText={i18n.translate('xpack.code.repoItem.confirmButtonText', {
|
||||
defaultMessage: 'Yes, do it',
|
||||
})}
|
||||
buttonColor="danger"
|
||||
defaultFocusedButton={EUI_MODAL_CONFIRM_BUTTON}
|
||||
/>
|
||||
|
|
|
@ -24,6 +24,8 @@ import {
|
|||
EuiText,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import moment from 'moment';
|
||||
import React, { ChangeEvent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
@ -62,10 +64,36 @@ const sortFunctionsFactory = (status: { [key: string]: RepoStatus }) => {
|
|||
};
|
||||
|
||||
const sortOptions = [
|
||||
{ value: SortOptionsValue.AlphabeticalAsc, inputDisplay: 'A to Z' },
|
||||
{ value: SortOptionsValue.AlphabeticalDesc, inputDisplay: 'Z to A' },
|
||||
{ value: SortOptionsValue.UpdatedAsc, inputDisplay: 'Last Updated ASC' },
|
||||
{ value: SortOptionsValue.UpdatedDesc, inputDisplay: 'Last Updated DESC' },
|
||||
{
|
||||
value: SortOptionsValue.AlphabeticalAsc,
|
||||
inputDisplay: i18n.translate('xpack.code.adminPage.repoTab.sort.aToZDropDownOptionLabel', {
|
||||
defaultMessage: 'A to Z',
|
||||
}),
|
||||
},
|
||||
{
|
||||
value: SortOptionsValue.AlphabeticalDesc,
|
||||
inputDisplay: i18n.translate('xpack.code.adminPage.repoTab.sort.zToADropDownOptionLabel', {
|
||||
defaultMessage: 'Z to A',
|
||||
}),
|
||||
},
|
||||
{
|
||||
value: SortOptionsValue.UpdatedAsc,
|
||||
inputDisplay: i18n.translate(
|
||||
'xpack.code.adminPage.repoTab.sort.updatedAscDropDownOptionLabel',
|
||||
{
|
||||
defaultMessage: 'Last Updated ASC',
|
||||
}
|
||||
),
|
||||
},
|
||||
{
|
||||
value: SortOptionsValue.UpdatedDesc,
|
||||
inputDisplay: i18n.translate(
|
||||
'xpack.code.adminPage.repoTab.sort.updatedDescDropDownOptionLabel',
|
||||
{
|
||||
defaultMessage: 'Last Updated DESC',
|
||||
}
|
||||
),
|
||||
},
|
||||
// { value: SortOptionsValue.recently_added, inputDisplay: 'Recently Added' },
|
||||
];
|
||||
|
||||
|
@ -148,14 +176,29 @@ class CodeProjectTab extends React.PureComponent<Props, State> {
|
|||
<EuiOverlayMask>
|
||||
<EuiModal onClose={this.closeModal}>
|
||||
<EuiModalHeader>
|
||||
<EuiModalHeaderTitle>Import a new repo</EuiModalHeaderTitle>
|
||||
<EuiModalHeaderTitle>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.repoTab.importRepoTitle"
|
||||
defaultMessage="Import a new repo"
|
||||
/>
|
||||
</EuiModalHeaderTitle>
|
||||
</EuiModalHeader>
|
||||
<EuiModalBody>
|
||||
<EuiTitle size="xs">
|
||||
<h3>Repository URL</h3>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.repoTab.repositoryUrlFormLabel"
|
||||
defaultMessage="Repository URL"
|
||||
/>
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
<EuiForm>
|
||||
<EuiFormRow isInvalid={this.state.isInvalid} error="The URL shouldn't be empty.">
|
||||
<EuiFormRow
|
||||
isInvalid={this.state.isInvalid}
|
||||
error={i18n.translate('xpack.code.adminPage.repoTab.repositoryUrlEmptyText', {
|
||||
defaultMessage: "The URL shouldn't be empty.",
|
||||
})}
|
||||
>
|
||||
<EuiFieldText
|
||||
value={this.state.repoURL}
|
||||
onChange={this.onChange}
|
||||
|
@ -172,9 +215,17 @@ class CodeProjectTab extends React.PureComponent<Props, State> {
|
|||
</EuiForm>
|
||||
</EuiModalBody>
|
||||
<EuiModalFooter>
|
||||
<EuiButtonEmpty onClick={this.closeModal}>Cancel</EuiButtonEmpty>
|
||||
<EuiButtonEmpty onClick={this.closeModal}>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.repoTab.cancelButtonLabel"
|
||||
defaultMessage="Cancel"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
<EuiButton fill onClick={this.submitImportProject} disabled={this.props.importLoading}>
|
||||
Import project
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.repoTab.importButtonLabel"
|
||||
defaultMessage="Import"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiModalFooter>
|
||||
</EuiModal>
|
||||
|
@ -226,7 +277,11 @@ class CodeProjectTab extends React.PureComponent<Props, State> {
|
|||
<EuiSpacer />
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiFormRow label="Sort By">
|
||||
<EuiFormRow
|
||||
label={i18n.translate('xpack.code.adminPage.repoTab.sort.sortByFormLabel', {
|
||||
defaultMessage: 'Sort By',
|
||||
})}
|
||||
>
|
||||
<EuiSuperSelect
|
||||
options={sortOptions}
|
||||
valueOfSelected={this.state.sortOption}
|
||||
|
@ -244,7 +299,10 @@ class CodeProjectTab extends React.PureComponent<Props, State> {
|
|||
onClick={this.openModal}
|
||||
data-test-subj="newProjectButton"
|
||||
>
|
||||
Import a new repo
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.repoTab.importRepoButtonLabel"
|
||||
defaultMessage="Import a new repo"
|
||||
/>
|
||||
</EuiButton>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
|
@ -252,8 +310,11 @@ class CodeProjectTab extends React.PureComponent<Props, State> {
|
|||
<EuiSpacer />
|
||||
<EuiText>
|
||||
<h3>
|
||||
{projectsCount}
|
||||
{projectsCount === 1 ? <span> Repo</span> : <span> Repos</span>}
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.repoTab.repoDescription"
|
||||
defaultMessage="{projectsCount} {projectsCount, plural, one {Repo} other {Repos}}"
|
||||
values={{ projectsCount }}
|
||||
/>
|
||||
</h3>
|
||||
</EuiText>
|
||||
<EuiSpacer />
|
||||
|
|
|
@ -15,6 +15,8 @@ import {
|
|||
EuiTitle,
|
||||
EuiLink,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
@ -23,80 +25,149 @@ import { RootState } from '../../reducers';
|
|||
|
||||
const steps = [
|
||||
{
|
||||
title: 'Check if multiple Kibana instances are used as a cluster',
|
||||
title: i18n.translate('xpack.code.adminPage.setupGuide.checkMultiInstanceTitle', {
|
||||
defaultMessage: 'Check if multiple Kibana instances are used as a clusterURL',
|
||||
}),
|
||||
children: (
|
||||
<EuiText>
|
||||
<p>If you are using single Kibana instance, you can skip this step.</p>
|
||||
<p>
|
||||
If you are using multiple Kibana instances, you need to assign one Kibana instance as
|
||||
`Code node`. To do this, add the following line of code into your kibana.yml file of every
|
||||
Kibana instance and restart the instances:
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.checkMultiInstanceDescription1"
|
||||
defaultMessage="If you are using single Kibana instance, you can skip this step."
|
||||
/>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.checkMultiInstanceDescription2"
|
||||
defaultMessage="If you are using multiple Kibana instances, you need to assign one Kibana instance as `Code node`.
|
||||
To do this, add the following line of code into your kibana.yml file of every
|
||||
Kibana instance and restart the instances:"
|
||||
/>
|
||||
</p>
|
||||
<pre>
|
||||
<code>xpack.code.codeNodeUrl: 'http://$YourCodeNodeAddress'</code>
|
||||
</pre>
|
||||
<p>
|
||||
Where `$YourCodeNoteAddress` is the URL of your assigned Code node accessible by other
|
||||
Kibana instances.
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.checkMultiInstanceDescription3"
|
||||
defaultMessage="Where `$YourCodeNoteAddress` is the URL of your assigned Code node accessible by other Kibana instances."
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Install extra language support optionally',
|
||||
title: i18n.translate('xpack.code.adminPage.setupGuide.installExtraLangSupportTitle', {
|
||||
defaultMessage: 'Install extra language support optionally',
|
||||
}),
|
||||
children: (
|
||||
<EuiText>
|
||||
<p>
|
||||
Look{' '}
|
||||
<EuiLink href={documentationLinks.codeInstallLangServer} target="_blank">
|
||||
here
|
||||
</EuiLink>{' '}
|
||||
to learn more about supported languages and language server installation.
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.installExtraLangSupportDescription1"
|
||||
defaultMessage="Look {link} to learn more about supported languages and language server installation."
|
||||
values={{
|
||||
link: (
|
||||
<EuiLink href={documentationLinks.codeInstallLangServer} target="_blank">
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.installExtraLangSupportHereLinkText"
|
||||
defaultMessage="here"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
If you need Java language support, you can manage language server installation{' '}
|
||||
<Link to="/admin?tab=LanguageServers">here</Link>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.installExtraLangSupportDescription2"
|
||||
defaultMessage="If you need Java language support, you can manage language server installation {link}."
|
||||
values={{
|
||||
link: (
|
||||
<Link to="/admin?tab=LanguageServers">
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.installExtraLangSupportHereLinkText"
|
||||
defaultMessage="here"
|
||||
/>
|
||||
</Link>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Add a repository to Code',
|
||||
title: i18n.translate('xpack.code.adminPage.setupGuide.addRepositoryTitle', {
|
||||
defaultMessage: 'Add a repository to Code',
|
||||
}),
|
||||
children: (
|
||||
<EuiText>
|
||||
<p>
|
||||
Import{' '}
|
||||
<EuiLink href={documentationLinks.codeGettingStarted} target="_blank">
|
||||
{' '}
|
||||
a sample repo
|
||||
</EuiLink>{' '}
|
||||
or{' '}
|
||||
<EuiLink href={documentationLinks.codeRepoManagement} target="_blank">
|
||||
your own repo
|
||||
</EuiLink>
|
||||
. It is as easy as copy and paste git clone URLs to Code.
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.addRepositoryDescription"
|
||||
defaultMessage="Import {sampleRepoLink} or {ownRepoLink}. It is as easy as copy and paste git clone URLs to Code."
|
||||
values={{
|
||||
sampleRepoLink: (
|
||||
<EuiLink href={documentationLinks.codeGettingStarted} target="_blank">
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.addRepositorySampleRepoLinkText"
|
||||
defaultMessage="a sample repo"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
ownRepoLink: (
|
||||
<EuiLink href={documentationLinks.codeRepoManagement} target="_blank">
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.addRepositoryOwnRepoLinkText"
|
||||
defaultMessage="your own repo"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Verify the repo is successfully imported',
|
||||
title: i18n.translate('xpack.code.adminPage.setupGuide.verifyImportTitle', {
|
||||
defaultMessage: 'Verify the repo is successfully imported',
|
||||
}),
|
||||
children: (
|
||||
<EuiText>
|
||||
<p>
|
||||
You can verify your repo is successfully imported by{' '}
|
||||
<EuiLink href={documentationLinks.codeSearch} target="_blank">
|
||||
searching
|
||||
</EuiLink>{' '}
|
||||
and{' '}
|
||||
<EuiLink href={documentationLinks.codeOtherFeatures} target="_blank">
|
||||
navigating
|
||||
</EuiLink>{' '}
|
||||
the repo. If language support is available to the repo, make sure{' '}
|
||||
<EuiLink href={documentationLinks.semanticNavigation} target="_blank">
|
||||
semantic navigation
|
||||
</EuiLink>{' '}
|
||||
is available as well.
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.verifyImportDescription"
|
||||
defaultMessage="You can verify your repo is successfully imported by {searchingLink} and {navigatingLink} the repo. If language support is available to the repo, make sure {semanticNavigationLink} is available as well."
|
||||
values={{
|
||||
searchingLink: (
|
||||
<EuiLink href={documentationLinks.codeSearch} target="_blank">
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.verifyImportSearchingLinkText"
|
||||
defaultMessage="searching"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
navigatingLink: (
|
||||
<EuiLink href={documentationLinks.codeOtherFeatures} target="_blank">
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.verifyImportNavigatingLinkText"
|
||||
defaultMessage="navigating"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
semanticNavigationLink: (
|
||||
<EuiLink href={documentationLinks.semanticNavigation} target="_blank">
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.verifyImportSemanticNavigatingLinkText"
|
||||
defaultMessage="semantic navigation"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
),
|
||||
|
@ -106,11 +177,16 @@ const steps = [
|
|||
const toastMessage = (
|
||||
<div>
|
||||
<p>
|
||||
We’ve made some changes to roles and permissions in Kibana. Read more about how these changes
|
||||
affect your Code implementation below.{' '}
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.permissionChangesDescription"
|
||||
defaultMessage="We’ve made some changes to roles and permissions in Kibana. Read more about how these changes affect your Code implementation below."
|
||||
/>
|
||||
</p>
|
||||
<EuiButton size="s" href={documentationLinks.kibanaRoleManagement}>
|
||||
Learn more
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.learnMoreButtonLabel"
|
||||
defaultMessage="Learn more"
|
||||
/>
|
||||
</EuiButton>
|
||||
</div>
|
||||
);
|
||||
|
@ -133,7 +209,9 @@ class SetupGuidePage extends React.PureComponent<{ setupOk?: boolean }, { hideTo
|
|||
<EuiGlobalToastList
|
||||
toasts={[
|
||||
{
|
||||
title: 'Permission Changes',
|
||||
title: i18n.translate('xpack.code.adminPage.setupGuide.permissionChangesTitle', {
|
||||
defaultMessage: 'Permission Changes',
|
||||
}),
|
||||
color: 'primary',
|
||||
iconType: 'iInCircle',
|
||||
text: toastMessage,
|
||||
|
@ -158,15 +236,25 @@ class SetupGuidePage extends React.PureComponent<{ setupOk?: boolean }, { hideTo
|
|||
{this.props.setupOk === true && (
|
||||
<React.Fragment>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiButton iconType="sortLeft">
|
||||
<Link to="/admin">Back To project dashboard</Link>
|
||||
</EuiButton>
|
||||
<Link to="/admin">
|
||||
<EuiButton iconType="sortLeft">
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.backToDashboardButtonLabel"
|
||||
defaultMessage="Back To repository dashboard"
|
||||
/>
|
||||
</EuiButton>
|
||||
</Link>
|
||||
<EuiSpacer size="s" />
|
||||
</React.Fragment>
|
||||
)}
|
||||
<EuiPanel>
|
||||
<EuiTitle>
|
||||
<h3>Getting started in Elastic Code</h3>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.code.adminPage.setupGuide.getStartedTitle"
|
||||
defaultMessage="Getting started in Elastic Code"
|
||||
/>
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
<EuiSpacer />
|
||||
<EuiSteps steps={steps} />
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import React from 'react';
|
||||
import chrome from 'ui/chrome';
|
||||
import { EuiButton, EuiHorizontalRule, EuiText, EuiSpacer } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { documentationLinks } from '../../lib/documentation_links';
|
||||
|
||||
export class HelpMenu extends React.PureComponent {
|
||||
|
@ -16,15 +17,26 @@ export class HelpMenu extends React.PureComponent {
|
|||
<EuiHorizontalRule margin="none" />
|
||||
<EuiSpacer />
|
||||
<EuiText size="s">
|
||||
<p>For Code specific information</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.code.helpMenu.helpDescription"
|
||||
defaultMessage="For Code specific information"
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer />
|
||||
<EuiButton fill iconType="popout" href={chrome.addBasePath('/app/code#/setup-guide')}>
|
||||
Setup Guide
|
||||
<FormattedMessage
|
||||
id="xpack.code.helpMenu.setupGuideButtonLabel"
|
||||
defaultMessage="Setup Guide"
|
||||
/>
|
||||
</EuiButton>
|
||||
<EuiSpacer />
|
||||
<EuiButton fill iconType="popout" href={documentationLinks.code} target="_blank">
|
||||
Code documentation
|
||||
<FormattedMessage
|
||||
id="xpack.code.helpMenu.codeDocumentationButtonLabel"
|
||||
defaultMessage="Code documentation"
|
||||
/>
|
||||
</EuiButton>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
*/
|
||||
|
||||
import { EuiButton, EuiFlexGroup } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import React from 'react';
|
||||
import { HoverState } from './hover_widget';
|
||||
|
||||
|
@ -25,7 +27,10 @@ export class HoverButtons extends React.PureComponent<HoverButtonProps> {
|
|||
onClick={this.props.gotoDefinition}
|
||||
data-test-subj="codeGoToDefinitionButton"
|
||||
>
|
||||
Goto Definition
|
||||
<FormattedMessage
|
||||
id="xpack.code.monaco.hover.gotoDefinitionButtonLabel"
|
||||
defaultMessage="Goto Definition"
|
||||
/>
|
||||
</EuiButton>
|
||||
<EuiButton
|
||||
size="s"
|
||||
|
@ -33,7 +38,10 @@ export class HoverButtons extends React.PureComponent<HoverButtonProps> {
|
|||
onClick={this.props.findReferences}
|
||||
data-test-subj="codeFindReferenceButton"
|
||||
>
|
||||
Find Reference
|
||||
<FormattedMessage
|
||||
id="xpack.code.monaco.hover.findReferenceButtonLabel"
|
||||
defaultMessage="Find Reference"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexGroup>
|
||||
</React.Fragment>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EuiText, EuiLink } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
import { MarkedString } from 'vscode-languageserver-types';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
|
@ -98,9 +99,19 @@ export class HoverWidget extends React.PureComponent<HoverWidgetProps> {
|
|||
{/*
|
||||
// @ts-ignore */}
|
||||
<EuiText textAlign="center">
|
||||
<h4>Language Server is initializing…</h4>
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.code.monaco.hover.languageServerInitializingTitle"
|
||||
defaultMessage="Language Server is initializing…"
|
||||
/>
|
||||
</h4>
|
||||
<EuiText size="xs" color="subdued">
|
||||
<p>Depending on the size of your repo, this could take a few minutes.</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.code.monaco.hover.languageServerInitializingDescription"
|
||||
defaultMessage="Depending on the size of your repo, this could take a few minutes."
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiText>
|
||||
</div>
|
||||
|
|
|
@ -5,8 +5,11 @@
|
|||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiProgress, EuiSpacer, EuiText } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import theme from '@elastic/eui/dist/eui_theme_light.json';
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { CloneProgress } from '../../../model';
|
||||
|
||||
interface Props {
|
||||
|
@ -17,20 +20,38 @@ interface Props {
|
|||
|
||||
export const CloneStatus = (props: Props) => {
|
||||
const { progress: progressRate, cloneProgress, repoName } = props;
|
||||
let progress = `Receiving objects: ${progressRate.toFixed(2)}%`;
|
||||
let progress = i18n.translate(
|
||||
'xpack.code.mainPage.content.cloneStatus.progress.receivingRateOnlyText',
|
||||
{
|
||||
defaultMessage: 'Receiving objects: {progressRate}%',
|
||||
values: { progressRate: progressRate.toFixed(2) },
|
||||
}
|
||||
);
|
||||
if (progressRate < 0) {
|
||||
progress = 'Clone Failed';
|
||||
progress = i18n.translate('xpack.code.mainPage.content.cloneStatus.progress.cloneFailedText', {
|
||||
defaultMessage: 'Clone Failed',
|
||||
});
|
||||
} else if (cloneProgress) {
|
||||
const { receivedObjects, totalObjects, indexedObjects } = cloneProgress;
|
||||
|
||||
if (receivedObjects === totalObjects) {
|
||||
progress = `Indexing objects: ${((indexedObjects * 100) / totalObjects).toFixed(
|
||||
2
|
||||
)}% (${indexedObjects}/${totalObjects})`;
|
||||
progress = i18n.translate('xpack.code.mainPage.content.cloneStatus.progress.indexingText', {
|
||||
defaultMessage: 'Indexing objects: {progressRate}% {indexedObjects}/{totalObjects}',
|
||||
values: {
|
||||
progressRate: ((indexedObjects * 100) / totalObjects).toFixed(2),
|
||||
indexedObjects,
|
||||
totalObjects,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
progress = `Receiving objects: ${((receivedObjects * 100) / totalObjects).toFixed(
|
||||
2
|
||||
)}% (${receivedObjects}/${totalObjects})`;
|
||||
progress = i18n.translate('xpack.code.mainPage.content.cloneStatus.progress.receivingText', {
|
||||
defaultMessage: 'Receiving objects: {progressRate}% {receivedObjects}/{totalObjects}',
|
||||
values: {
|
||||
progressRate: ((receivedObjects * 100) / totalObjects).toFixed(2),
|
||||
receivedObjects,
|
||||
totalObjects,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
return (
|
||||
|
@ -39,13 +60,20 @@ export const CloneStatus = (props: Props) => {
|
|||
<EuiSpacer size="xxl" />
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText style={{ fontSize: theme.euiSizeXXL, color: '#1A1A1A' }}>
|
||||
{repoName} is cloning
|
||||
{repoName}{' '}
|
||||
<FormattedMessage
|
||||
id="xpack.code.mainPage.content.cloneStatus.isCloningText"
|
||||
defaultMessage="is cloning"
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText style={{ fontSize: theme.euiSizeM, color: '#69707D' }}>
|
||||
Your project will be available when this process is complete
|
||||
<FormattedMessage
|
||||
id="xpack.code.mainPage.content.cloneStatus.yourProjectWillBeAvailableText"
|
||||
defaultMessage="Your project will be available when this process is complete"
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiSpacer size="xl" />
|
||||
|
|
|
@ -13,10 +13,13 @@ import {
|
|||
EuiText,
|
||||
EuiTextColor,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { CommitInfo } from '../../../model/commit';
|
||||
import { CommitLink } from '../diff_page/commit_link';
|
||||
import { RootState } from '../../reducers';
|
||||
|
@ -64,7 +67,14 @@ const CommitGroup = (props: { commits: CommitInfo[]; date: string; repoUri: stri
|
|||
<EuiFlexItem>
|
||||
<EuiText>
|
||||
<h4>
|
||||
<EuiTextColor color="subdued">Commits on {props.date}</EuiTextColor>
|
||||
<EuiTextColor color="subdued">
|
||||
<FormattedMessage
|
||||
id="xpack.code.mainPage.history.commitsOnTitle"
|
||||
defaultMessage="Commits on {date}"
|
||||
values={{ date: props.date }}
|
||||
/>{' '}
|
||||
{}
|
||||
</EuiTextColor>
|
||||
</h4>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
|
@ -94,12 +104,17 @@ export const PageButtons = (props: {
|
|||
isDisabled={props.disabled}
|
||||
size="s"
|
||||
>
|
||||
More
|
||||
<FormattedMessage id="xpack.code.mainPage.history.moreButtonLabel" defaultMessage="More" />
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
||||
const commitDateFormatMap: { [key: string]: string } = {
|
||||
en: 'MMMM Do, YYYY',
|
||||
'zh-cn': 'YYYY年MoDo',
|
||||
};
|
||||
|
||||
export const CommitHistoryComponent = (props: {
|
||||
commits: CommitInfo[];
|
||||
repoUri: string;
|
||||
|
@ -111,10 +126,13 @@ export const CommitHistoryComponent = (props: {
|
|||
}) => {
|
||||
const commits = _.groupBy(props.commits, commit => moment(commit.updated).format('YYYYMMDD'));
|
||||
const commitDates = Object.keys(commits).sort((a, b) => b.localeCompare(a)); // sort desc
|
||||
const locale = i18n.getLocale();
|
||||
const commitDateFormat =
|
||||
locale in commitDateFormatMap ? commitDateFormatMap[locale] : commitDateFormatMap.en;
|
||||
const commitList = commitDates.map(cd => (
|
||||
<CommitGroup
|
||||
commits={commits[cd]}
|
||||
date={moment(cd).format('MMMM Do, YYYY')}
|
||||
date={moment(cd).format(commitDateFormat)}
|
||||
key={cd}
|
||||
repoUri={props.repoUri}
|
||||
/>
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
*/
|
||||
|
||||
import { EuiButton, EuiButtonGroup, EuiFlexGroup, EuiTitle, EuiLink } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import 'github-markdown-css/github-markdown.css';
|
||||
import React from 'react';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
|
@ -69,13 +72,6 @@ enum ButtonOption {
|
|||
Folder = 'Directory',
|
||||
}
|
||||
|
||||
enum ButtonLabel {
|
||||
Code = 'Code',
|
||||
Content = 'Content',
|
||||
Download = 'Download',
|
||||
Raw = 'Raw',
|
||||
}
|
||||
|
||||
class CodeContent extends React.PureComponent<Props> {
|
||||
public findNode = (pathSegments: string[], node: FileTree): FileTree | undefined => {
|
||||
if (!node) {
|
||||
|
@ -161,20 +157,40 @@ class CodeContent extends React.PureComponent<Props> {
|
|||
const buttonOptions = [
|
||||
{
|
||||
id: ButtonOption.Code,
|
||||
label: isText && !isMarkdown ? ButtonLabel.Code : ButtonLabel.Content,
|
||||
label:
|
||||
isText && !isMarkdown
|
||||
? i18n.translate('xpack.code.mainPage.content.buttons.codeButtonLabel', {
|
||||
defaultMessage: 'Code',
|
||||
})
|
||||
: i18n.translate('xpack.code.mainPage.content.buttons.contentButtonLabel', {
|
||||
defaultMessage: 'content',
|
||||
}),
|
||||
},
|
||||
{
|
||||
id: ButtonOption.Blame,
|
||||
label: ButtonOption.Blame,
|
||||
label: i18n.translate('xpack.code.mainPage.content.buttons.blameButtonLabel', {
|
||||
defaultMessage: 'Blame',
|
||||
}),
|
||||
isDisabled: isUnsupported || isImage || isOversize,
|
||||
},
|
||||
{
|
||||
id: ButtonOption.History,
|
||||
label: ButtonOption.History,
|
||||
label: i18n.translate('xpack.code.mainPage.content.buttons.historyButtonLabel', {
|
||||
defaultMessage: 'History',
|
||||
}),
|
||||
},
|
||||
];
|
||||
const rawButtonOptions = [
|
||||
{ id: 'Raw', label: isText ? ButtonLabel.Raw : ButtonLabel.Download },
|
||||
{
|
||||
id: 'Raw',
|
||||
label: isText
|
||||
? i18n.translate('xpack.code.mainPage.content.buttons.rawButtonLabel', {
|
||||
defaultMessage: 'Raw',
|
||||
})
|
||||
: i18n.translate('xpack.code.mainPage.content.buttons.downloadButtonLabel', {
|
||||
defaultMessage: 'Download',
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
|
@ -210,11 +226,15 @@ class CodeContent extends React.PureComponent<Props> {
|
|||
options={[
|
||||
{
|
||||
id: ButtonOption.Folder,
|
||||
label: ButtonOption.Folder,
|
||||
label: i18n.translate('xpack.code.mainPage.content.buttons.folderButtonLabel', {
|
||||
defaultMessage: 'Directory',
|
||||
}),
|
||||
},
|
||||
{
|
||||
id: ButtonOption.History,
|
||||
label: ButtonOption.History,
|
||||
label: i18n.translate('xpack.code.mainPage.content.buttons.historyButtonLabel', {
|
||||
defaultMessage: 'History',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
type="single"
|
||||
|
@ -296,7 +316,12 @@ class CodeContent extends React.PureComponent<Props> {
|
|||
header={
|
||||
<React.Fragment>
|
||||
<EuiTitle size="s" className="codeMargin__title">
|
||||
<h3>Recent Commits</h3>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.code.mainPage.directory.recentCommitsTitle"
|
||||
defaultMessage="Recent Commits"
|
||||
/>
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
<EuiButton
|
||||
size="s"
|
||||
|
@ -304,7 +329,10 @@ class CodeContent extends React.PureComponent<Props> {
|
|||
revision
|
||||
)}/${path || ''}`}
|
||||
>
|
||||
View All
|
||||
<FormattedMessage
|
||||
id="xpack.code.mainPage.directory.viewAllCommitsButtonLabel"
|
||||
defaultMessage="View All"
|
||||
/>
|
||||
</EuiButton>
|
||||
</React.Fragment>
|
||||
}
|
||||
|
@ -383,7 +411,12 @@ class CodeContent extends React.PureComponent<Props> {
|
|||
repoUri={repoUri}
|
||||
header={
|
||||
<EuiTitle className="codeMargin__title">
|
||||
<h3>Commit History</h3>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.code.mainPage.history.commitHistoryTitle"
|
||||
defaultMessage="Commit History"
|
||||
/>
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
}
|
||||
showPagination={true}
|
||||
|
|
|
@ -14,6 +14,8 @@ import {
|
|||
EuiLoadingSpinner,
|
||||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import React from 'react';
|
||||
import { Link, RouteComponentProps, withRouter } from 'react-router-dom';
|
||||
import { FileTree, FileTreeItemType } from '../../../model';
|
||||
|
@ -84,9 +86,23 @@ export const Directory = withRouter((props: Props) => {
|
|||
const { resource, org, repo, revision } = props.match.params;
|
||||
const getUrl = (pathType: PathTypes) => (path: string) =>
|
||||
`/${resource}/${org}/${repo}/${pathType}/${encodeRevisionString(revision)}/${path}`;
|
||||
const fileList = <DirectoryNodes nodes={files} title="Files" getUrl={getUrl(PathTypes.blob)} />;
|
||||
const fileList = (
|
||||
<DirectoryNodes
|
||||
nodes={files}
|
||||
title={i18n.translate('xpack.code.mainPage.content.directory.filesTitle', {
|
||||
defaultMessage: 'Files',
|
||||
})}
|
||||
getUrl={getUrl(PathTypes.blob)}
|
||||
/>
|
||||
);
|
||||
const folderList = (
|
||||
<DirectoryNodes nodes={folders} title="Directories" getUrl={getUrl(PathTypes.tree)} />
|
||||
<DirectoryNodes
|
||||
nodes={folders}
|
||||
title={i18n.translate('xpack.code.mainPage.content.directory.directoriesTitle', {
|
||||
defaultMessage: 'Directories',
|
||||
})}
|
||||
getUrl={getUrl(PathTypes.tree)}
|
||||
/>
|
||||
);
|
||||
const children = props.loading ? (
|
||||
<div>
|
||||
|
|
|
@ -9,6 +9,7 @@ import { parse as parseQuery } from 'querystring';
|
|||
import React from 'react';
|
||||
import { RouteComponentProps, withRouter } from 'react-router-dom';
|
||||
import { QueryString } from 'ui/utils/query_string';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { MainRouteParams } from '../../common/types';
|
||||
import { FileTree } from '../file_tree/file_tree';
|
||||
import { Shortcut } from '../shortcuts';
|
||||
|
@ -56,28 +57,44 @@ class CodeSideTabs extends React.PureComponent<Props> {
|
|||
public get tabs() {
|
||||
const { languageServerInitializing, loadingFileTree, loadingStructureTree } = this.props;
|
||||
const fileTabContent = loadingFileTree ? (
|
||||
this.renderLoadingSpinner('Loading file tree')
|
||||
this.renderLoadingSpinner(
|
||||
i18n.translate('xpack.code.mainPage.sideTab.loadingFileTreeText', {
|
||||
defaultMessage: 'Loading file tree',
|
||||
})
|
||||
)
|
||||
) : (
|
||||
<div className="codeFileTree__container">{<FileTree />}</div>
|
||||
);
|
||||
let structureTabContent: React.ReactNode;
|
||||
if (languageServerInitializing) {
|
||||
structureTabContent = this.renderLoadingSpinner('Language server is initializing');
|
||||
structureTabContent = this.renderLoadingSpinner(
|
||||
i18n.translate('xpack.code.mainPage.sideTab.languageServerInitializingText', {
|
||||
defaultMessage: 'Language server is initializing',
|
||||
})
|
||||
);
|
||||
} else if (loadingStructureTree) {
|
||||
structureTabContent = this.renderLoadingSpinner('Loading structure tree');
|
||||
structureTabContent = this.renderLoadingSpinner(
|
||||
i18n.translate('xpack.code.mainPage.sideTab.loadingStructureTreeText', {
|
||||
defaultMessage: 'Loading structure tree',
|
||||
})
|
||||
);
|
||||
} else {
|
||||
structureTabContent = <SymbolTree />;
|
||||
}
|
||||
return [
|
||||
{
|
||||
id: Tabs.file,
|
||||
name: 'File',
|
||||
name: i18n.translate('xpack.code.mainPage.sideTab.fileTabLabel', {
|
||||
defaultMessage: 'Files',
|
||||
}),
|
||||
content: fileTabContent,
|
||||
'data-test-subj': `codeFileTreeTab${this.sideTab === Tabs.file ? 'Active' : ''}`,
|
||||
},
|
||||
{
|
||||
id: Tabs.structure,
|
||||
name: 'Structure',
|
||||
name: i18n.translate('xpack.code.mainPage.sideTab.structureTabLabel', {
|
||||
defaultMessage: 'Structure',
|
||||
}),
|
||||
content: structureTabContent,
|
||||
disabled:
|
||||
!(this.props.currentTree && this.props.currentTree.type === FileTreeItemType.File) ||
|
||||
|
|
|
@ -623,7 +623,19 @@ exports[`render correctly with empty query string 1`] = `
|
|||
<span
|
||||
className="euiTextColor euiTextColor--secondary"
|
||||
>
|
||||
Search Filters
|
||||
<FormattedMessage
|
||||
defaultMessage=" {filterCount, plural, one {Search Filter} other {Search Filters}} "
|
||||
id="xpack.code.searchBar.searchFilterTitle"
|
||||
values={
|
||||
Object {
|
||||
"filterCount": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
<span>
|
||||
Search Filters
|
||||
</span>
|
||||
</FormattedMessage>
|
||||
</span>
|
||||
</EuiTextColor>
|
||||
</span>
|
||||
|
@ -1332,7 +1344,19 @@ exports[`render correctly with input query string changed 1`] = `
|
|||
<span
|
||||
className="euiTextColor euiTextColor--secondary"
|
||||
>
|
||||
Search Filters
|
||||
<FormattedMessage
|
||||
defaultMessage=" {filterCount, plural, one {Search Filter} other {Search Filters}} "
|
||||
id="xpack.code.searchBar.searchFilterTitle"
|
||||
values={
|
||||
Object {
|
||||
"filterCount": 0,
|
||||
}
|
||||
}
|
||||
>
|
||||
<span>
|
||||
Search Filters
|
||||
</span>
|
||||
</FormattedMessage>
|
||||
</span>
|
||||
</EuiTextColor>
|
||||
</span>
|
||||
|
|
|
@ -20,6 +20,8 @@ import {
|
|||
EuiNotificationBadge,
|
||||
} from '@elastic/eui';
|
||||
import { EuiIcon } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { unique } from 'lodash';
|
||||
import React, { Component } from 'react';
|
||||
import { SearchOptions as ISearchOptions, Repository } from '../../../../model';
|
||||
|
@ -114,6 +116,14 @@ export class SearchOptions extends Component<Props, State> {
|
|||
);
|
||||
});
|
||||
|
||||
const repoCandidates = this.state.query
|
||||
? this.props.repoSearchResults.map(repo => ({
|
||||
label: repo.name,
|
||||
}))
|
||||
: this.props.defaultRepoOptions.map(repo => ({
|
||||
label: repo.name,
|
||||
}));
|
||||
|
||||
optionsFlyout = (
|
||||
<EuiFlyout
|
||||
onClose={this.closeOptionsFlyout}
|
||||
|
@ -128,30 +138,38 @@ export class SearchOptions extends Component<Props, State> {
|
|||
{repoScope.length}
|
||||
</EuiNotificationBadge>
|
||||
<EuiTextColor color="secondary" className="code-flyout-title">
|
||||
{' '}
|
||||
Search Filters{' '}
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchBar.searchFilterTitle"
|
||||
defaultMessage=" {filterCount, plural, one {Search Filter} other {Search Filters}} "
|
||||
values={{ filterCount: repoScope.length }}
|
||||
/>
|
||||
</EuiTextColor>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiFlyoutHeader>
|
||||
<EuiFlyoutBody>
|
||||
<EuiTitle size="xs">
|
||||
<h3>Repo Scope</h3>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchBar.searchScopeTitle"
|
||||
defaultMessage="Search Scope"
|
||||
/>
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
<EuiText size="xs">Add indexed repos to your search scope</EuiText>
|
||||
<EuiText size="xs">
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchBar.addToScopeDescription"
|
||||
defaultMessage="Add indexed repos to your search scope"
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiComboBox
|
||||
placeholder="Search to add repos"
|
||||
noSuggestions={repoCandidates.length === 0}
|
||||
placeholder={i18n.translate('xpack.code.searchBar.addRepoPlaceholder', {
|
||||
defaultMessage: 'Search to add repos',
|
||||
})}
|
||||
async={true}
|
||||
options={
|
||||
this.state.query
|
||||
? this.props.repoSearchResults.map(repo => ({
|
||||
label: repo.name,
|
||||
}))
|
||||
: this.props.defaultRepoOptions.map(repo => ({
|
||||
label: repo.name,
|
||||
}))
|
||||
}
|
||||
options={repoCandidates}
|
||||
selectedOptions={[]}
|
||||
isLoading={this.props.searchLoading}
|
||||
onChange={this.onRepoChange}
|
||||
|
@ -163,7 +181,10 @@ export class SearchOptions extends Component<Props, State> {
|
|||
<EuiSpacer size="s" />
|
||||
<EuiFlexGroup justifyContent="flexEnd" gutterSize="none">
|
||||
<EuiButton onClick={this.applyAndClose} fill={true} iconSide="right">
|
||||
Apply and Close
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchBar.applyAndCloseButtonLabel"
|
||||
defaultMessage="Apply and Close"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlyoutBody>
|
||||
|
@ -178,7 +199,13 @@ export class SearchOptions extends Component<Props, State> {
|
|||
<EuiNotificationBadge size="m" className="code-notification-badge">
|
||||
{repoScope.length}
|
||||
</EuiNotificationBadge>
|
||||
<EuiTextColor color="secondary"> Search Filters </EuiTextColor>
|
||||
<EuiTextColor color="secondary">
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchBar.searchFilterTitle"
|
||||
defaultMessage=" {filterCount, plural, one {Search Filter} other {Search Filters}} "
|
||||
values={{ filterCount: repoScope.length }}
|
||||
/>
|
||||
</EuiTextColor>
|
||||
</EuiButtonEmpty>
|
||||
</div>
|
||||
{optionsFlyout}
|
||||
|
|
|
@ -195,8 +195,19 @@ exports[`render full suggestions component 1`] = `
|
|||
<div
|
||||
className="codeSearch-suggestion__group-result"
|
||||
>
|
||||
1
|
||||
Result
|
||||
<FormattedMessage
|
||||
defaultMessage="{total} {total, plural, one {Result} other {Results}}"
|
||||
id="xpack.code.searchBar.resultCountText"
|
||||
values={
|
||||
Object {
|
||||
"total": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
<span>
|
||||
1 Result
|
||||
</span>
|
||||
</FormattedMessage>
|
||||
</div>
|
||||
</div>
|
||||
</EuiFlexGroup>
|
||||
|
@ -347,8 +358,19 @@ exports[`render full suggestions component 1`] = `
|
|||
<div
|
||||
className="codeSearch-suggestion__group-result"
|
||||
>
|
||||
1
|
||||
Result
|
||||
<FormattedMessage
|
||||
defaultMessage="{total} {total, plural, one {Result} other {Results}}"
|
||||
id="xpack.code.searchBar.resultCountText"
|
||||
values={
|
||||
Object {
|
||||
"total": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
<span>
|
||||
1 Result
|
||||
</span>
|
||||
</FormattedMessage>
|
||||
</div>
|
||||
</div>
|
||||
</EuiFlexGroup>
|
||||
|
@ -463,9 +485,19 @@ exports[`render full suggestions component 1`] = `
|
|||
<div
|
||||
className="codeSearch-suggestion__group-result"
|
||||
>
|
||||
2
|
||||
Result
|
||||
s
|
||||
<FormattedMessage
|
||||
defaultMessage="{total} {total, plural, one {Result} other {Results}}"
|
||||
id="xpack.code.searchBar.resultCountText"
|
||||
values={
|
||||
Object {
|
||||
"total": 2,
|
||||
}
|
||||
}
|
||||
>
|
||||
<span>
|
||||
2 Results
|
||||
</span>
|
||||
</FormattedMessage>
|
||||
</div>
|
||||
</div>
|
||||
</EuiFlexGroup>
|
||||
|
@ -568,7 +600,16 @@ exports[`render full suggestions component 1`] = `
|
|||
href="/search?q=string"
|
||||
onClick={[Function]}
|
||||
>
|
||||
View More
|
||||
|
||||
<FormattedMessage
|
||||
defaultMessage="View More"
|
||||
id="xpack.code.searchBar.viewMoreLinkText"
|
||||
values={Object {}}
|
||||
>
|
||||
<span>
|
||||
View More
|
||||
</span>
|
||||
</FormattedMessage>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
|
@ -584,7 +625,15 @@ exports[`render full suggestions component 1`] = `
|
|||
<div
|
||||
className="codeSearch__full-text-button"
|
||||
>
|
||||
Press ⮐ Return for Full Text Search
|
||||
<FormattedMessage
|
||||
defaultMessage="Press ⮐ Return for Full Text Search"
|
||||
id="xpack.code.searchBar.viewFullSearchLinkText"
|
||||
values={Object {}}
|
||||
>
|
||||
<span>
|
||||
Press ⮐ Return for Full Text Search
|
||||
</span>
|
||||
</FormattedMessage>
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiText, EuiToken, IconType } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { isEmpty } from 'lodash';
|
||||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
@ -53,7 +56,10 @@ export class SuggestionsComponent extends Component<Props> {
|
|||
{this.renderSuggestionGroups()}
|
||||
<Link to={this.viewMoreUrl()}>
|
||||
<div className="codeSearch__full-text-button">
|
||||
Press ⮐ Return for Full Text Search
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchBar.viewFullSearchLinkText"
|
||||
defaultMessage="Press ⮐ Return for Full Text Search"
|
||||
/>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
|
@ -109,15 +115,24 @@ export class SuggestionsComponent extends Component<Props> {
|
|||
</EuiText>
|
||||
</EuiFlexGroup>
|
||||
<div className="codeSearch-suggestion__group-result">
|
||||
{total} Result
|
||||
{total === 1 ? '' : 's'}
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchBar.resultCountText"
|
||||
defaultMessage="{total} {total, plural, one {Result} other {Results}}"
|
||||
values={{ total }}
|
||||
/>
|
||||
</div>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
||||
const viewMore = (
|
||||
<div className="codeSearch-suggestion__link">
|
||||
<Link to={this.viewMoreUrl()}>View More</Link>
|
||||
<Link to={this.viewMoreUrl()}>
|
||||
{' '}
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchBar.viewMoreLinkText"
|
||||
defaultMessage="View More"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
@ -153,11 +168,17 @@ export class SuggestionsComponent extends Component<Props> {
|
|||
private getGroupTitle(type: AutocompleteSuggestionType): string {
|
||||
switch (type) {
|
||||
case AutocompleteSuggestionType.FILE:
|
||||
return 'Files';
|
||||
return i18n.translate('xpack.code.searchBar.fileGroupTitle', {
|
||||
defaultMessage: 'Files',
|
||||
});
|
||||
case AutocompleteSuggestionType.REPOSITORY:
|
||||
return 'Repos';
|
||||
return i18n.translate('xpack.code.searchBar.repositorylGroupTitle', {
|
||||
defaultMessage: 'Repos',
|
||||
});
|
||||
case AutocompleteSuggestionType.SYMBOL:
|
||||
return 'Symbols';
|
||||
return i18n.translate('xpack.code.searchBar.symbolGroupTitle', {
|
||||
defaultMessage: 'Symbols',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { IPosition } from 'monaco-editor';
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
@ -63,7 +64,10 @@ export class CodeResult extends React.PureComponent<Props> {
|
|||
<EuiBadge color="default">{hits}</EuiBadge>
|
||||
</EuiFlexItem>
|
||||
<EuiText size="s">
|
||||
hits from
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchPage.hitsCountText"
|
||||
defaultMessage=" hits from "
|
||||
/>
|
||||
<Link to={fileLinkUrl} data-test-subj="codeSearchResultFileItem">
|
||||
{filePath}
|
||||
</Link>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EuiButton, EuiSpacer, EuiText } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
|
||||
export const EmptyPlaceholder = (props: any) => {
|
||||
|
@ -25,11 +26,17 @@ export const EmptyPlaceholder = (props: any) => {
|
|||
</EuiText>
|
||||
<EuiSpacer size="xl" />
|
||||
<EuiText textAlign="center" style={{ fontSize: '28px', color: '#1A1A1A' }}>
|
||||
Hmmm... we looked for that, but couldn’t find anything.
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchPage.emptyTitle"
|
||||
defaultMessage="Hmmm... we looked for that, but couldn’t find anything."
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiSpacer size="xl" />
|
||||
<EuiText textAlign="center" color="subdued">
|
||||
You can search for something else or modify your search settings.
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchPage.emptyText"
|
||||
defaultMessage="You can search for something else or modify your search settings."
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiSpacer size="l" />
|
||||
<EuiText textAlign="center">
|
||||
|
@ -41,7 +48,10 @@ export const EmptyPlaceholder = (props: any) => {
|
|||
}
|
||||
}}
|
||||
>
|
||||
Modify your search settings
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchPage.modifySearchSettingButtonLabel"
|
||||
defaultMessage="Modify your search settings"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiText>
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EuiTab, EuiTabs } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import querystring from 'querystring';
|
||||
import React from 'react';
|
||||
import url from 'url';
|
||||
|
@ -44,14 +45,20 @@ export class ScopeTabs extends React.PureComponent<Props> {
|
|||
isSelected={this.props.scope !== SearchScope.REPOSITORY}
|
||||
onClick={this.onTabClicked(SearchScope.DEFAULT)}
|
||||
>
|
||||
Code
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchPage.scopeTabs.codeTabLabel"
|
||||
defaultMessage="Code"
|
||||
/>
|
||||
</EuiTab>
|
||||
<EuiTab
|
||||
className="codeUtility__width--half"
|
||||
isSelected={this.props.scope === SearchScope.REPOSITORY}
|
||||
onClick={this.onTabClicked(SearchScope.REPOSITORY)}
|
||||
>
|
||||
Repository
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchPage.scopeTabs.repositoryTabLabel"
|
||||
defaultMessage="Repository"
|
||||
/>
|
||||
</EuiTab>
|
||||
</EuiTabs>
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EuiFlexItem, EuiLoadingSpinner, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import querystring from 'querystring';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
@ -166,7 +167,11 @@ class SearchPage extends React.PureComponent<Props, State> {
|
|||
const statsComp = (
|
||||
<EuiTitle size="m">
|
||||
<h1>
|
||||
Showing {total > 0 ? from : 0} - {to} of {total} results.
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchPage.showingResultsTitle"
|
||||
defaultMessage="Showing {from} - {to} of {total} results."
|
||||
values={{ from, to, total }}
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
);
|
||||
|
@ -186,7 +191,11 @@ class SearchPage extends React.PureComponent<Props, State> {
|
|||
const statsComp = (
|
||||
<EuiTitle size="m">
|
||||
<h1>
|
||||
Showing {total > 0 ? from : 0} - {to} of {total} results.
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchPage.showingResultsTitle"
|
||||
defaultMessage="Showing {from} - {to} of {total} results."
|
||||
values={{ from, to, total }}
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
);
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
EuiTitle,
|
||||
EuiToken,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
|
||||
import { RepositoryUtils } from '../../../common/repository_utils';
|
||||
|
@ -116,7 +117,12 @@ export class SideBar extends React.PureComponent<Props> {
|
|||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="xxs">
|
||||
<h3>Repositories</h3>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchPage.sideBar.repositoriesTitle"
|
||||
defaultMessage="Repositories"
|
||||
/>
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
@ -136,7 +142,12 @@ export class SideBar extends React.PureComponent<Props> {
|
|||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="xxs">
|
||||
<h3>Languages</h3>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.code.searchPage.sideBar.languagesTitle"
|
||||
defaultMessage="Languages"
|
||||
/>
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
LangServerType,
|
||||
REPO_FILE_STATUS_SEVERITY,
|
||||
RepoFileStatus,
|
||||
RepoFileStatusText as StatusText,
|
||||
Severity,
|
||||
StatusReport,
|
||||
} from '../../../common/repo_file_status';
|
||||
|
@ -80,7 +81,7 @@ export class StatusIndicatorComponent extends React.Component<Props, State> {
|
|||
</p>
|
||||
);
|
||||
} else {
|
||||
children.push(<p key={`${error}_key`}>{error}</p>);
|
||||
children.push(<p key={`${error}_key`}>{StatusText[error]}</p>);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
import { editor as Editor, languages, Range as EditorRange } from 'monaco-editor';
|
||||
// @ts-ignore
|
||||
import { createCancelablePromise } from 'monaco-editor/esm/vs/base/common/async';
|
||||
|
@ -135,11 +136,20 @@ export class ContentHoverWidget extends ContentWidget {
|
|||
}
|
||||
|
||||
this.showAt(new monaco.Position(renderRange.startLineNumber, startColumn), this.shouldFocus);
|
||||
const element = React.createElement(HoverWidget, props, null);
|
||||
|
||||
const element = (
|
||||
<I18nProvider>
|
||||
<HoverWidget {...props} />
|
||||
</I18nProvider>
|
||||
);
|
||||
// @ts-ignore
|
||||
ReactDOM.render(element, fragment);
|
||||
const buttonFragment = document.createDocumentFragment();
|
||||
const buttons = React.createElement(HoverButtons, props, null);
|
||||
const buttons = (
|
||||
<I18nProvider>
|
||||
<HoverButtons {...props} />
|
||||
</I18nProvider>
|
||||
);
|
||||
// @ts-ignore
|
||||
ReactDOM.render(buttons, buttonFragment);
|
||||
this.updateContents(fragment, buttonFragment);
|
|
@ -6,6 +6,7 @@
|
|||
import produce from 'immer';
|
||||
import { Action, handleActions } from 'redux-actions';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Repository, RepoConfigs, RepositoryConfig } from '../../model';
|
||||
|
||||
import {
|
||||
|
@ -89,22 +90,35 @@ export const repositoryManagement = handleActions<
|
|||
draft.importLoading = true;
|
||||
}),
|
||||
[String(importRepoSuccess)]: (state, action: Action<Repository>) =>
|
||||
// TODO is it possible and how to deal with action.payload === undefined?
|
||||
produce<RepositoryManagementState>(state, draft => {
|
||||
draft.importLoading = false;
|
||||
draft.showToast = true;
|
||||
draft.toastType = ToastType.success;
|
||||
draft.toastMessage = `${action.payload!.name} has been successfully submitted!`;
|
||||
draft.toastMessage = i18n.translate(
|
||||
'xpack.code.repositoryManagement.repoSubmittedMessage',
|
||||
{
|
||||
defaultMessage: '{name} has been successfully submitted!',
|
||||
values: { name: action.payload!.name },
|
||||
}
|
||||
);
|
||||
draft.repositories = [...state.repositories, action.payload!];
|
||||
}),
|
||||
[String(importRepoFailed)]: (state, action: Action<any>) =>
|
||||
produce<RepositoryManagementState>(state, draft => {
|
||||
if (action.payload) {
|
||||
if (action.payload.res.status === 304) {
|
||||
draft.toastMessage = 'This Repository has already been imported!';
|
||||
draft.toastMessage = i18n.translate(
|
||||
'xpack.code.repositoryManagement.repoImportedMessage',
|
||||
{
|
||||
defaultMessage: 'This Repository has already been imported!',
|
||||
}
|
||||
);
|
||||
draft.showToast = true;
|
||||
draft.toastType = ToastType.warning;
|
||||
draft.importLoading = false;
|
||||
} else {
|
||||
// TODO add localication for those messages
|
||||
draft.toastMessage = action.payload.body.message;
|
||||
draft.showToast = true;
|
||||
draft.toastType = ToastType.danger;
|
||||
|
|
|
@ -4291,7 +4291,148 @@
|
|||
"xpack.canvas.functions.timefilterControl.args.columnHelpText": "附加筛选的列字段",
|
||||
"xpack.canvas.functions.timefilterControl.args.compactHelpText": "将时间筛选显示为触发弹出框的按钮",
|
||||
"xpack.canvas.sampleDataLinkLabel": "Canvas",
|
||||
"xpack.code.adminPage.langserverTab.installedText": "已安装",
|
||||
"xpack.code.adminPage.langserverTab.languageServersDescription": "{serverCount} {serverCount, plural, one {服务器} other {服务器}}",
|
||||
"xpack.code.adminPage.langserverTab.notInstalledText": "未安装",
|
||||
"xpack.code.adminPage.langserverTab.runningText": "运行中",
|
||||
"xpack.code.adminPage.langserverTab.setup.closeButtonLabel": "关闭",
|
||||
"xpack.code.adminPage.langserverTab.setup.installationInstructionTitle": "安装指南",
|
||||
"xpack.code.adminPage.langserverTab.setup.installTitle": "安装",
|
||||
"xpack.code.adminPage.langserverTab.setup.stopKibanaDescription": "停止您的 Kibana Code 服务器",
|
||||
"xpack.code.adminPage.langserverTab.setup.uninstallTitle": "卸载",
|
||||
"xpack.code.adminPage.langserverTab.setup.useFollowingCommandToInstallDescription": "使用以下命令来安装 {name} 语言服务器",
|
||||
"xpack.code.adminPage.langserverTab.setup.useFollowingCommandToRemoveDescription": "使用以下命令来移除 {name} 语言服务器",
|
||||
"xpack.code.adminPage.langserverTab.setupButtonLabel": "安装",
|
||||
"xpack.code.adminPage.langserverTabLabel": "语言服务器",
|
||||
"xpack.code.adminPage.repoTab.cancelButtonLabel": "导入",
|
||||
"xpack.code.adminPage.repoTab.emptyRepo.importFirstRepositoryText": "请导入第一个代码仓库",
|
||||
"xpack.code.adminPage.repoTab.emptyRepo.noRepositoryText": "您还没有导入任何代码仓库",
|
||||
"xpack.code.adminPage.repoTab.emptyRepo.viewSetupGuideButtonLabel": "查看配置指南",
|
||||
"xpack.code.adminPage.repoTab.importButtonLabel": "导入",
|
||||
"xpack.code.adminPage.repoTab.importRepoButtonLabel": "导入新仓库",
|
||||
"xpack.code.adminPage.repoTab.importRepoTitle": "导入新仓库",
|
||||
"xpack.code.adminPage.repoTab.repoDescription": "{projectsCount} 仓库",
|
||||
"xpack.code.adminPage.repoTab.repositoryUrlEmptyText": "URL 不能为空",
|
||||
"xpack.code.adminPage.repoTab.repositoryUrlFormLabel": "代码仓库 URL",
|
||||
"xpack.code.adminPage.repoTab.repositoryUrlTitle": "代码仓库 URL",
|
||||
"xpack.code.adminPage.repoTab.sort.aToZDropDownOptionLabel": "A 到 Z",
|
||||
"xpack.code.adminPage.repoTab.sort.sortByFormLabel": "排序依据",
|
||||
"xpack.code.adminPage.repoTab.sort.updatedAscDropDownOptionLabel": "最近更新升序",
|
||||
"xpack.code.adminPage.repoTab.sort.updatedDescDropDownOptionLabel": "最近更新降序",
|
||||
"xpack.code.adminPage.repoTab.sort.zToADropDownOptionLabel": "Z 到 A",
|
||||
"xpack.code.adminPage.repoTabLabel": "代码仓库",
|
||||
"xpack.code.adminPage.setupGuide.checkMultiInstanceTitle": "检查是否是多个 Kibana 实例组成的集群",
|
||||
"xpack.code.adminPage.setupGuide.checkMultiInstanceDescription1": "如果您使用的是单 Kibana 实例,可以跳过这一步。",
|
||||
"xpack.code.adminPage.setupGuide.checkMultiInstanceDescription2": "如果您使用多个 Kibana 实例,您需要制定其中一个实例为 `Code 节点`。您可以将以下配置添加到您每个 Kibana 实例的 kibana.yml 文件中,然后重启所有实例:",
|
||||
"xpack.code.adminPage.setupGuide.checkMultiInstanceDescription3": "其中 `$YourCodeNoteAddress` 是您 Code 节点的 URL。",
|
||||
"xpack.code.adminPage.setupGuide.installExtraLangSupportTitle": "安装额外的语言支持(可选)",
|
||||
"xpack.code.adminPage.setupGuide.installExtraLangSupportDescription1": "查看{link}了解我们支持的语言和语言服务器的安装。",
|
||||
"xpack.code.adminPage.setupGuide.installExtraLangSupportDescription2": "如果您需要 Java 支持,您可以在{link}管理语言服务器。",
|
||||
"xpack.code.adminPage.setupGuide.installExtraLangSupportHereLinkText": "此处",
|
||||
"xpack.code.adminPage.setupGuide.addRepositoryTitle": "添加代码仓库到 Code",
|
||||
"xpack.code.adminPage.setupGuide.addRepositoryDescription": "导入{sampleRepoLink}或者{ownRepoLink}。您可以很容易地复制粘贴 Git 的克隆 URL 到Code。",
|
||||
"xpack.code.adminPage.setupGuide.addRepositorySampleRepoLinkText": "示例仓库",
|
||||
"xpack.code.adminPage.setupGuide.addRepositoryOwnRepoLinkText": "您自己的仓库",
|
||||
"xpack.code.adminPage.setupGuide.verifyImportTitle": "验证代码仓库是否被成功导入",
|
||||
"xpack.code.adminPage.setupGuide.verifyImportDescription": "您可以尝试{searchingLink},{navigatingLink},以及{semanticNavigationLink}来验证仓库是否被成功导入并索引。",
|
||||
"xpack.code.adminPage.setupGuide.verifyImportSearchingLinkText": "搜索",
|
||||
"xpack.code.adminPage.setupGuide.verifyImportNavigatingLinkText": "导航",
|
||||
"xpack.code.adminPage.setupGuide.verifyImportSemanticNavigatingLinkText": "语义导航",
|
||||
"xpack.code.adminPage.setupGuide.backToDashboardButtonLabel": "返回到仪表板",
|
||||
"xpack.code.adminPage.setupGuide.getStartedTitle": "开始使用 Elastic Code",
|
||||
"xpack.code.adminPage.setupGuide.learnMoreButtonLabel": "了解更多",
|
||||
"xpack.code.adminPage.setupGuide.permissionChangesDescription": "Kibana 的角色和权限模型有新的改动,请了解这些改动对您 Code 部署的影响",
|
||||
"xpack.code.adminPage.setupGuide.permissionChangesTitle": "权限模型变动",
|
||||
"xpack.code.featureRegistry.codeFeatureName": "Code",
|
||||
"xpack.code.gitUrlUtil.urlNotWhitelistedMessage": "Git URL 主机地址没有在白名单中。",
|
||||
"xpack.code.gitUrlUtil.protocolNotWhitelistedMessage": "Git URL 的协议没有在白名单中。",
|
||||
"xpack.code.helpMenu.codeDocumentationButtonLabel": "Code 文档",
|
||||
"xpack.code.helpMenu.helpDescription": "Code 相关信息",
|
||||
"xpack.code.helpMenu.setupGuideButtonLabel": "配置指南",
|
||||
"xpack.code.mainPage.content.cloneStatus.isCloningText": "正在克隆",
|
||||
"xpack.code.mainPage.content.cloneStatus.yourProjectWillBeAvailableText": "当此过程完成后您的项目即可访问",
|
||||
"xpack.code.mainPage.content.cloneStatus.progress.receivingText": "正在接收对象 {progressRate}% {receivedObjects}/{totalObjects}",
|
||||
"xpack.code.mainPage.content.cloneStatus.progress.receivingRateOnlyText": "正在接收对象 {progressRate}%",
|
||||
"xpack.code.mainPage.content.cloneStatus.progress.indexingText": "正在索引对象 {progressRate}% {indexedObjects}/{totalObjects}",
|
||||
"xpack.code.mainPage.content.cloneStatus.progress.cloneFailedText": "克隆失败",
|
||||
"xpack.code.mainPage.content.buttons.blameButtonLabel": "注解",
|
||||
"xpack.code.mainPage.content.buttons.codeButtonLabel": "代码",
|
||||
"xpack.code.mainPage.content.buttons.contentButtonLabel": "内容",
|
||||
"xpack.code.mainPage.content.buttons.downloadButtonLabel": "下载",
|
||||
"xpack.code.mainPage.content.buttons.folderButtonLabel": "目录",
|
||||
"xpack.code.mainPage.content.buttons.historyButtonLabel": "历史",
|
||||
"xpack.code.mainPage.content.buttons.rawButtonLabel": "原件",
|
||||
"xpack.code.mainPage.content.directory.directoriesTitle": "目录",
|
||||
"xpack.code.mainPage.content.directory.filesTitle": "文件",
|
||||
"xpack.code.mainPage.directory.recentCommitsTitle": "近期提交",
|
||||
"xpack.code.mainPage.directory.viewAllCommitsButtonLabel": "查看全部",
|
||||
"xpack.code.mainPage.history.commitHistoryTitle": "提交记录",
|
||||
"xpack.code.mainPage.history.commitsOnTitle": "{date} 的提交",
|
||||
"xpack.code.mainPage.history.moreButtonLabel": "更多",
|
||||
"xpack.code.mainPage.sideTab.fileTabLabel": "文件",
|
||||
"xpack.code.mainPage.sideTab.languageServerInitializingText": "语言服务器初始化中",
|
||||
"xpack.code.mainPage.sideTab.loadingFileTreeText": "读取目录树",
|
||||
"xpack.code.mainPage.sideTab.loadingStructureTreeText": "读取结构树",
|
||||
"xpack.code.mainPage.sideTab.structureTabLabel": "结构",
|
||||
"xpack.code.monaco.hover.findReferenceButtonLabel": "查看引用",
|
||||
"xpack.code.monaco.hover.gotoDefinitionButtonLabel": "跳转到定义",
|
||||
"xpack.code.monaco.hover.languageServerInitializingDescription": "取决于代码仓库大小,初始化需要花费若干分钟",
|
||||
"xpack.code.monaco.hover.languageServerInitializingTitle": "语言服务器正在初始化…",
|
||||
"xpack.code.repoItem.cancelButtonText": "否,取消",
|
||||
"xpack.code.repoItem.cloneErrorText": "克隆错误",
|
||||
"xpack.code.repoItem.cloningText": "克隆中...",
|
||||
"xpack.code.repoItem.confirmButtonText": "是,继续",
|
||||
"xpack.code.repoItem.deleteButtonLabel": "删除",
|
||||
"xpack.code.repoItem.deleteConfirmTitle": "确认删除仓库?",
|
||||
"xpack.code.repoItem.deleteErrorText": "删除错误",
|
||||
"xpack.code.repoItem.deletingText": "删除中...",
|
||||
"xpack.code.repoItem.indexErrorText": "索引错误",
|
||||
"xpack.code.repoItem.indexingText": "索引中...",
|
||||
"xpack.code.repoItem.initText": "初始化中...",
|
||||
"xpack.code.repoItem.lastUpdatedText": "最后更新",
|
||||
"xpack.code.repoItem.reindexButtonLabel": "重新索引",
|
||||
"xpack.code.repoItem.reindexConfirmTitle": "确认重新索引仓库?",
|
||||
"xpack.code.repoItem.settingsButtonLabel": "设置",
|
||||
"xpack.code.repositoryManagement.repoImportedMessage": "此代码仓库已经被成功导入!",
|
||||
"xpack.code.repositoryManagement.repoSubmittedMessage": "{name} 已经被成功提交!",
|
||||
"xpack.code.repoFileStatus.langugageServerIsInitializitingMessage": "语言服务器正在初始化。",
|
||||
"xpack.code.repoFileStatus.languageServerInitializedMessage": "语言服务器已经初始化。",
|
||||
"xpack.code.repoFileStatus.IndexingInProgressMessage": "索引正在进行中。",
|
||||
"xpack.code.repoFileStatus.fileNotSupportedMessage": "当前文件的语言没有支持。",
|
||||
"xpack.code.repoFileStatus.revisionNotIndexedMessage": "当前版本还没有被索引。",
|
||||
"xpack.code.repoFileStatus.langServerNotInstalledMessage": "请安装其他语言服务器以支持当前文件。",
|
||||
"xpack.code.repoFileStatus.fileIsTooBigMessage": "当前文件过大。",
|
||||
"xpack.code.repoFileStatus.langserverType.noneMessage": "当前文件不被任何语言服务器支持。",
|
||||
"xpack.code.repoFileStatus.langserverType.genericMessage": "当前文件由通用语言服务器支持。",
|
||||
"xpack.code.repoFileStatus.langserverType.dedicatedMessage": "当前文件由专用语言服务器支持。",
|
||||
"xpack.code.searchBar.addRepoPlaceholder": "查找并添加仓库",
|
||||
"xpack.code.searchBar.addToScopeDescription": "添加已索引代码仓库到搜索范围",
|
||||
"xpack.code.searchBar.applyAndCloseButtonLabel": "应用并关闭",
|
||||
"xpack.code.searchBar.fileGroupTitle": "文件",
|
||||
"xpack.code.searchBar.repositorylGroupTitle": "仓库",
|
||||
"xpack.code.searchBar.resultCountText": "{total} {total, plural, one {结果} other {结果}}",
|
||||
"xpack.code.searchBar.searchFilterTitle": " {filterCount, plural, one {搜索筛选} other {搜索筛选}}",
|
||||
"xpack.code.searchBar.searchScopeTitle": "搜索范围",
|
||||
"xpack.code.searchBar.symbolGroupTitle": "符号",
|
||||
"xpack.code.searchBar.viewFullSearchLinkText": "按 ⮐ 以返回全文搜索结果",
|
||||
"xpack.code.searchBar.viewMoreLinkText": "查看更多",
|
||||
"xpack.code.searchPage.emptyText": "您可以输入其他查询或者修改搜索设置。",
|
||||
"xpack.code.searchPage.emptyTitle": "对不起,我们并没有找到任何结果。",
|
||||
"xpack.code.searchPage.hitsCountText": " 个匹配在 ",
|
||||
"xpack.code.searchPage.modifySearchSettingButtonLabel": "修改搜索设置",
|
||||
"xpack.code.searchPage.scopeTabs.codeTabLabel": "代码",
|
||||
"xpack.code.searchPage.scopeTabs.repositoryTabLabel": "仓库",
|
||||
"xpack.code.searchPage.showingResultsTitle": "以下是从 {from} 到 {to} 个结果,总共找到 {total} 个结果",
|
||||
"xpack.code.searchPage.sideBar.languagesTitle": "语言",
|
||||
"xpack.code.searchPage.sideBar.repositoriesTitle": "代码仓库",
|
||||
"xpack.code.searchScope.defaultDropDownOptionLabel": "搜索全部",
|
||||
"xpack.code.searchScope.defaultPlaceholder": "请输入任何查询",
|
||||
"xpack.code.searchScope.fileDropDownOptionLabel": "搜索文件",
|
||||
"xpack.code.searchScope.filePlaceholder": "请输入文件查询",
|
||||
"xpack.code.searchScope.repositoryDropDownOptionLabel": "搜索仓库",
|
||||
"xpack.code.searchScope.repositoryPlaceholder": "请输入仓库查询",
|
||||
"xpack.code.searchScope.symbolDropDownOptionLabel": "搜索符号",
|
||||
"xpack.code.searchScope.symbolPlaceholder": "请输入符号查询",
|
||||
"xpack.crossClusterReplication.addAutoFollowPatternButtonLabel": "创建自动跟随模式",
|
||||
"xpack.crossClusterReplication.addBreadcrumbTitle": "添加",
|
||||
"xpack.crossClusterReplication.addFollowerButtonLabel": "创建 Follower 索引",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue