mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
Merge pull request #119 from wavetermdev/dev-0.5.1
pull dev-0.5.1 branch to main
This commit is contained in:
+1
-1
@@ -33,7 +33,7 @@ WAVETERM_DEV=1 PCLOUD_ENDPOINT="https://ot2e112zx5.execute-api.us-west-2.amazona
|
||||
```bash
|
||||
# @scripthaus command typecheck
|
||||
# @scripthaus cd :playbook
|
||||
node_modules/.bin/tsc --jsx preserve --noEmit --esModuleInterop --target ES5 --experimentalDecorators --downlevelIteration src/index.ts src/types/custom.d.ts
|
||||
node_modules/.bin/tsc --noEmit
|
||||
```
|
||||
|
||||
```bash
|
||||
|
||||
+49
-23
@@ -49,6 +49,14 @@ textarea {
|
||||
}
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
font-family: @text-s1-font;
|
||||
color: @text-primary;
|
||||
}
|
||||
|
||||
.text-standard {
|
||||
font-size: 12.5px;
|
||||
font-weight: 300;
|
||||
@@ -80,6 +88,15 @@ textarea {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
body a {
|
||||
color: @wave-green;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
&:hover {
|
||||
color: @wave-green;
|
||||
}
|
||||
}
|
||||
|
||||
body code {
|
||||
font-family: @terminal-font;
|
||||
}
|
||||
@@ -148,10 +165,10 @@ svg.icon {
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
background-color: @button-background !important;
|
||||
color: @prompt-green;
|
||||
color: @wave-green;
|
||||
.hoverEffect;
|
||||
&:hover {
|
||||
color: @prompt-green;
|
||||
color: @wave-green;
|
||||
}
|
||||
&.disabled {
|
||||
color: fade(@disabled-color, 60%);
|
||||
@@ -176,12 +193,6 @@ svg.icon {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
a:hover {
|
||||
color: #485fc7;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -219,7 +230,8 @@ a.a-block {
|
||||
|
||||
.history-view,
|
||||
.bookmarks-view,
|
||||
.plugins-view {
|
||||
.plugins-view,
|
||||
.connections-view {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -465,85 +477,99 @@ a.a-block {
|
||||
}
|
||||
|
||||
.icon.color-red {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-red;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-green {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-green;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-orange {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-orange;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-blue {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-blue;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-yellow {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-yellow;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-pink {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-pink;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-mint {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-mint;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-cyan {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-cyan;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-violet {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-violet;
|
||||
}
|
||||
}
|
||||
|
||||
.icon.color-white {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @tab-white;
|
||||
}
|
||||
}
|
||||
|
||||
.status-icon.status-connected {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @status-connected;
|
||||
}
|
||||
}
|
||||
|
||||
.status-icon.status-connecting {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @status-connecting;
|
||||
}
|
||||
}
|
||||
|
||||
.status-icon.status-disconnected {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @status-disconnected;
|
||||
}
|
||||
}
|
||||
|
||||
.status-icon.status-error {
|
||||
path, circle {
|
||||
path,
|
||||
circle {
|
||||
fill: @status-error;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-24
@@ -15,22 +15,16 @@ import { WorkspaceView } from "./workspace/workspaceview";
|
||||
import { PluginsView } from "./pluginsview/pluginsview";
|
||||
import { BookmarksView } from "./bookmarks/bookmarks";
|
||||
import { HistoryView } from "./history/history";
|
||||
import { ConnectionsView } from "./connections/connections";
|
||||
import {
|
||||
ScreenSettingsModal,
|
||||
SessionSettingsModal,
|
||||
LineSettingsModal,
|
||||
ClientSettingsModal,
|
||||
} from "./common/modals/settings";
|
||||
import { RemotesModal } from "./connections/connections";
|
||||
import { TosModal } from "./common/modals/modals";
|
||||
import { MainSideBar } from "./sidebar/sidebar";
|
||||
import {
|
||||
DisconnectedModal,
|
||||
ClientStopModal,
|
||||
AlertModal,
|
||||
AboutModal,
|
||||
CreateRemoteConnModal,
|
||||
} from "./common/modals/modals";
|
||||
import { DisconnectedModal, ClientStopModal, ModalsProvider } from "./common/modals/modals";
|
||||
import { ErrorBoundary } from "./common/error/errorboundary";
|
||||
import "./app.less";
|
||||
|
||||
@@ -64,7 +58,7 @@ class App extends React.Component<{}, {}> {
|
||||
opts.showCut = true;
|
||||
}
|
||||
let sel = window.getSelection();
|
||||
if (!isBlank(sel.toString())) {
|
||||
if (!isBlank(sel?.toString())) {
|
||||
GlobalModel.contextEditMenu(e, opts);
|
||||
} else {
|
||||
if (isInNonTermInput) {
|
||||
@@ -85,14 +79,12 @@ class App extends React.Component<{}, {}> {
|
||||
let sessionSettingsModal = GlobalModel.sessionSettingsModal.get();
|
||||
let lineSettingsModal = GlobalModel.lineSettingsModal.get();
|
||||
let clientSettingsModal = GlobalModel.clientSettingsModal.get();
|
||||
let remotesModel = GlobalModel.remotesModalModel;
|
||||
let remotesModal = remotesModel.isOpen();
|
||||
let selectedRemoteId = remotesModel.selectedRemoteId.get();
|
||||
let remoteEdit = remotesModel.remoteEdit.get();
|
||||
let remotesModel = GlobalModel.remotesModel;
|
||||
let disconnected = !GlobalModel.ws.open.get() || !GlobalModel.waveSrvRunning.get();
|
||||
let hasClientStop = GlobalModel.getHasClientStop();
|
||||
let dcWait = this.dcWait.get();
|
||||
let platform = GlobalModel.getPlatform();
|
||||
|
||||
if (disconnected || hasClientStop) {
|
||||
if (!dcWait) {
|
||||
setTimeout(() => this.updateDcWait(true), 1500);
|
||||
@@ -117,7 +109,6 @@ class App extends React.Component<{}, {}> {
|
||||
if (dcWait) {
|
||||
setTimeout(() => this.updateDcWait(false), 0);
|
||||
}
|
||||
//console.log(`GlobalModel.activeMainView.get() = ${GlobalModel.activeMainView.get()}`); // @mike - if I remove this, I cant see plugins
|
||||
return (
|
||||
<div id="main" className={"platform-" + platform} onContextMenu={this.handleContextMenu}>
|
||||
<div className="main-content">
|
||||
@@ -127,18 +118,13 @@ class App extends React.Component<{}, {}> {
|
||||
<WorkspaceView />
|
||||
<HistoryView />
|
||||
<BookmarksView />
|
||||
<ConnectionsView model={remotesModel} />
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
<AlertModal />
|
||||
<If condition={GlobalModel.needsTos()}>
|
||||
<TosModal />
|
||||
</If>
|
||||
<If condition={GlobalModel.aboutModalOpen.get()}>
|
||||
<AboutModal />
|
||||
</If>
|
||||
<If condition={remoteEdit !== null && !remoteEdit.old}>
|
||||
<CreateRemoteConnModal model={remotesModel} remoteEdit={remoteEdit} />
|
||||
</If>
|
||||
<ModalsProvider />
|
||||
<If condition={screenSettingsModal != null}>
|
||||
<ScreenSettingsModal
|
||||
key={screenSettingsModal.sessionId + ":" + screenSettingsModal.screenId}
|
||||
@@ -155,9 +141,6 @@ class App extends React.Component<{}, {}> {
|
||||
<If condition={clientSettingsModal}>
|
||||
<ClientSettingsModal />
|
||||
</If>
|
||||
<If condition={remotesModal}>
|
||||
<RemotesModal model={GlobalModel.remotesModalModel} />
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export const ABOUT = "about";
|
||||
export const CREATE_REMOTE = "createRemote";
|
||||
export const VIEW_REMOTE = "viewRemote";
|
||||
export const EDIT_REMOTE = "editRemote";
|
||||
export const ALERT = "alert";
|
||||
+236
-29
@@ -247,7 +247,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.button.is-prompt-green {
|
||||
.button.is-wave-green {
|
||||
background-color: #222;
|
||||
color: @term-white;
|
||||
|
||||
@@ -257,33 +257,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.wave-button {
|
||||
display: flex;
|
||||
padding: 6px 16px !important;
|
||||
color: @term-white !important;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
border-radius: 6px !important;
|
||||
height: auto !important;
|
||||
|
||||
&:hover {
|
||||
color: @term-white !important;
|
||||
}
|
||||
}
|
||||
|
||||
.wave-button.is-wave-green {
|
||||
color: @term-bright-white !important;
|
||||
background: @term-green !important;
|
||||
|
||||
&:hover {
|
||||
background-color: @term-green;
|
||||
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.8) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.6) inset;
|
||||
color: @term-bright-white !important;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.button.is-plain,
|
||||
.button.is-prompt-cancel {
|
||||
background-color: #222;
|
||||
@@ -637,7 +610,8 @@
|
||||
position: relative;
|
||||
background-color: transparent;
|
||||
height: 44px;
|
||||
width: 412px;
|
||||
min-width: 412px;
|
||||
width: 100%;
|
||||
border: 1px solid var(--element-separator, rgba(241, 246, 243, 0.15));
|
||||
border-radius: 6px;
|
||||
background: var(--element-hover-2, rgba(255, 255, 255, 0.06));
|
||||
@@ -801,10 +775,18 @@
|
||||
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.5) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset;
|
||||
|
||||
&:hover {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
&.focused {
|
||||
border-color: @term-green;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
&.error {
|
||||
border-color: @term-red;
|
||||
}
|
||||
@@ -931,3 +913,228 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wave-button {
|
||||
background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
outline: inherit;
|
||||
|
||||
display: flex;
|
||||
padding: 6px 16px;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
border-radius: 6px;
|
||||
height: auto;
|
||||
|
||||
&:hover {
|
||||
color: @term-white;
|
||||
}
|
||||
|
||||
i {
|
||||
fill: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
&.primary {
|
||||
color: @term-green;
|
||||
background: none;
|
||||
|
||||
i {
|
||||
fill: @term-green;
|
||||
}
|
||||
|
||||
&.solid {
|
||||
color: @term-bright-white;
|
||||
background: @term-green;
|
||||
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.8) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.6) inset;
|
||||
|
||||
i {
|
||||
fill: @term-white;
|
||||
}
|
||||
}
|
||||
|
||||
&.outlined {
|
||||
border: 1px solid @term-green;
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
// Styles for .ghost are already defined above
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: @term-bright-white;
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
color: @term-white;
|
||||
background: none;
|
||||
|
||||
&.solid {
|
||||
background: rgba(255, 255, 255, 0.09);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&.outlined {
|
||||
border: 1px solid rgba(255, 255, 255, 0.09);
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
padding: 6px 10px;
|
||||
|
||||
i {
|
||||
fill: @term-green;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.color-yellow {
|
||||
&.solid {
|
||||
border-color: @warning-yellow;
|
||||
background-color: mix(@warning-yellow, @term-white, 50%);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&.outlined {
|
||||
color: @warning-yellow;
|
||||
border-color: @warning-yellow;
|
||||
&:hover {
|
||||
color: @term-white;
|
||||
border-color: @term-white;
|
||||
}
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
}
|
||||
}
|
||||
|
||||
&.color-red {
|
||||
&.solid {
|
||||
border-color: @term-red;
|
||||
background-color: mix(@term-red, @term-white, 50%);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&.outlined {
|
||||
color: @term-red;
|
||||
border-color: @term-red;
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&.link-button {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.wave-status-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.dot {
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.dot.green {
|
||||
background-color: @status-connected;
|
||||
}
|
||||
|
||||
.dot.red {
|
||||
background-color: @status-error;
|
||||
}
|
||||
|
||||
.dot.gray {
|
||||
background-color: @status-disconnected;
|
||||
}
|
||||
|
||||
.dot.yellow {
|
||||
background-color: @status-connecting;
|
||||
}
|
||||
}
|
||||
|
||||
.wave-modal-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 500;
|
||||
|
||||
.wave-modal-backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(21, 23, 21, 0.7);
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.wave-modal {
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
border-radius: 10px;
|
||||
background: #151715;
|
||||
box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.35), 0px 10px 24px 0px rgba(0, 0, 0, 0.45),
|
||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.5) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset;
|
||||
|
||||
.wave-modal-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
.wave-modal-header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 14px 12px 20px;
|
||||
justify-content: space-between;
|
||||
line-height: 20px;
|
||||
border-bottom: 1px solid rgba(250, 250, 250, 0.1);
|
||||
|
||||
button {
|
||||
i {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wave-modal-body {
|
||||
width: 100%;
|
||||
padding: 0px 20px;
|
||||
}
|
||||
|
||||
.wave-modal-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
padding: 0 20px 20px;
|
||||
|
||||
button:first-child {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+209
-5
@@ -99,7 +99,7 @@ class Toggle extends React.Component<{ checked: boolean; onChange: (value: boole
|
||||
}
|
||||
|
||||
class Checkbox extends React.Component<
|
||||
{ checked: boolean; onChange: (value: boolean) => void; label: string; id: string },
|
||||
{ checked: boolean; onChange: (value: boolean) => void; label: React.ReactNode; id: string },
|
||||
{}
|
||||
> {
|
||||
render() {
|
||||
@@ -217,6 +217,115 @@ class Tooltip extends React.Component<TooltipProps, TooltipState> {
|
||||
}
|
||||
}
|
||||
|
||||
type ButtonVariantType = "outlined" | "solid" | "ghost";
|
||||
type ButtonThemeType = "primary" | "secondary";
|
||||
|
||||
interface ButtonProps {
|
||||
theme?: ButtonThemeType;
|
||||
children: React.ReactNode;
|
||||
onClick?: () => void;
|
||||
disabled?: boolean;
|
||||
variant?: ButtonVariantType;
|
||||
leftIcon?: React.ReactNode;
|
||||
rightIcon?: React.ReactNode;
|
||||
color?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
class Button extends React.Component<ButtonProps> {
|
||||
static defaultProps = {
|
||||
theme: "primary",
|
||||
variant: "solid",
|
||||
color: "",
|
||||
style: {},
|
||||
};
|
||||
|
||||
@boundMethod
|
||||
handleClick() {
|
||||
if (this.props.onClick && !this.props.disabled) {
|
||||
this.props.onClick();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { leftIcon, rightIcon, theme, children, disabled, variant, color, style } = this.props;
|
||||
|
||||
return (
|
||||
<button
|
||||
className={cn("wave-button", theme, variant, color, { disabled: disabled })}
|
||||
onClick={this.handleClick}
|
||||
disabled={disabled}
|
||||
style={style}
|
||||
>
|
||||
{leftIcon && <span className="icon-left">{leftIcon}</span>}
|
||||
{children}
|
||||
{rightIcon && <span className="icon-right">{rightIcon}</span>}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class IconButton extends Button {
|
||||
render() {
|
||||
const { children, theme, variant = "solid", ...rest } = this.props;
|
||||
const className = `wave-button icon-button ${theme} ${variant}`;
|
||||
|
||||
return (
|
||||
<button {...rest} className={className}>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default IconButton;
|
||||
|
||||
interface LinkButtonProps extends ButtonProps {
|
||||
href: string;
|
||||
target?: string;
|
||||
}
|
||||
|
||||
class LinkButton extends IconButton {
|
||||
render() {
|
||||
// @ts-ignore
|
||||
const { href, target, leftIcon, rightIcon, children, theme, variant }: LinkButtonProps = this.props;
|
||||
|
||||
return (
|
||||
<a href={href} target={target} className={`wave-button link-button`}>
|
||||
<button {...this.props} className={`icon-button ${theme} ${variant}`}>
|
||||
{leftIcon && <span className="icon-left">{leftIcon}</span>}
|
||||
{children}
|
||||
{rightIcon && <span className="icon-right">{rightIcon}</span>}
|
||||
</button>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
}
|
||||
interface StatusProps {
|
||||
status: "green" | "red" | "gray" | "yellow";
|
||||
text: string;
|
||||
}
|
||||
|
||||
class Status extends React.Component<StatusProps> {
|
||||
@boundMethod
|
||||
renderDot() {
|
||||
const { status } = this.props;
|
||||
|
||||
return <div className={`dot ${status}`} />;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { text } = this.props;
|
||||
|
||||
return (
|
||||
<div className="wave-status-container">
|
||||
{this.renderDot()}
|
||||
<span>{text}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
interface TextFieldDecorationProps {
|
||||
startDecoration?: React.ReactNode;
|
||||
endDecoration?: React.ReactNode;
|
||||
@@ -232,6 +341,7 @@ interface TextFieldProps {
|
||||
required?: boolean;
|
||||
maxLength?: number;
|
||||
autoFocus?: boolean;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
interface TextFieldState {
|
||||
@@ -242,7 +352,6 @@ interface TextFieldState {
|
||||
hasContent: boolean;
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class TextField extends React.Component<TextFieldProps, TextFieldState> {
|
||||
inputRef: React.RefObject<HTMLInputElement>;
|
||||
state: TextFieldState;
|
||||
@@ -267,6 +376,22 @@ class TextField extends React.Component<TextFieldProps, TextFieldState> {
|
||||
}
|
||||
}
|
||||
|
||||
// Method to handle focus at the component level
|
||||
@boundMethod
|
||||
handleComponentFocus() {
|
||||
if (this.inputRef.current && !this.inputRef.current.contains(document.activeElement)) {
|
||||
this.inputRef.current.focus();
|
||||
}
|
||||
}
|
||||
|
||||
// Method to handle blur at the component level
|
||||
@boundMethod
|
||||
handleComponentBlur() {
|
||||
if (this.inputRef.current && this.inputRef.current.contains(document.activeElement)) {
|
||||
this.inputRef.current.blur();
|
||||
}
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleFocus() {
|
||||
this.setState({ focused: true });
|
||||
@@ -311,14 +436,23 @@ class TextField extends React.Component<TextFieldProps, TextFieldState> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { label, value, placeholder, decoration, className, maxLength, autoFocus } = this.props;
|
||||
const { label, value, placeholder, decoration, className, maxLength, autoFocus, disabled } = this.props;
|
||||
const { focused, internalValue, error } = this.state;
|
||||
|
||||
// Decide if the input should behave as controlled or uncontrolled
|
||||
const inputValue = value !== undefined ? value : internalValue;
|
||||
|
||||
return (
|
||||
<div className={cn(`wave-textfield ${className || ""}`, { focused: focused, error: error })}>
|
||||
<div
|
||||
className={cn(`wave-textfield ${className || ""}`, {
|
||||
focused: focused,
|
||||
error: error,
|
||||
disabled: disabled,
|
||||
})}
|
||||
onFocus={this.handleComponentFocus}
|
||||
onBlur={this.handleComponentBlur}
|
||||
tabIndex={-1}
|
||||
>
|
||||
{decoration?.startDecoration && <>{decoration.startDecoration}</>}
|
||||
<div className="wave-textfield-inner">
|
||||
<label
|
||||
@@ -341,6 +475,7 @@ class TextField extends React.Component<TextFieldProps, TextFieldState> {
|
||||
placeholder={placeholder}
|
||||
maxLength={maxLength}
|
||||
autoFocus={autoFocus}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
{decoration?.endDecoration && <>{decoration.endDecoration}</>}
|
||||
@@ -617,7 +752,7 @@ class InlineSettingsTextEdit extends React.Component<
|
||||
<div
|
||||
onClick={this.confirmChange}
|
||||
title="Confirm (Enter)"
|
||||
className="button is-prompt-green is-outlined is-small"
|
||||
className="button is-wave-green is-outlined is-small"
|
||||
>
|
||||
<span className="icon is-small">
|
||||
<i className="fa-sharp fa-solid fa-check" />
|
||||
@@ -964,6 +1099,70 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
}
|
||||
}
|
||||
|
||||
interface ModalHeaderProps {
|
||||
onClose: () => void;
|
||||
title: string;
|
||||
}
|
||||
|
||||
const ModalHeader: React.FC<ModalHeaderProps> = ({ onClose, title }) => (
|
||||
<div className="wave-modal-header">
|
||||
{<div>{title}</div>}
|
||||
<IconButton theme="secondary" variant="ghost" onClick={onClose}>
|
||||
<i className="fa-sharp fa-solid fa-xmark"></i>
|
||||
</IconButton>
|
||||
</div>
|
||||
);
|
||||
|
||||
interface ModalFooterProps {
|
||||
onCancel?: () => void;
|
||||
onOk?: () => void;
|
||||
cancelLabel?: string;
|
||||
okLabel?: string;
|
||||
}
|
||||
|
||||
const ModalFooter: React.FC<ModalFooterProps> = ({ onCancel, onOk, cancelLabel = "Cancel", okLabel = "Ok" }) => (
|
||||
<div className="wave-modal-footer">
|
||||
{onCancel && (
|
||||
<Button theme="secondary" onClick={onCancel}>
|
||||
{cancelLabel}
|
||||
</Button>
|
||||
)}
|
||||
{onOk && <Button onClick={onOk}>{okLabel}</Button>}
|
||||
</div>
|
||||
);
|
||||
|
||||
interface ModalProps {
|
||||
className?: string;
|
||||
children?: React.ReactNode;
|
||||
onClickBackdrop?: () => void;
|
||||
}
|
||||
|
||||
class Modal extends React.Component<ModalProps> {
|
||||
static Header = ModalHeader;
|
||||
static Footer = ModalFooter;
|
||||
|
||||
renderBackdrop(onClick: (() => void) | undefined) {
|
||||
return <div className="wave-modal-backdrop" onClick={onClick}></div>;
|
||||
}
|
||||
|
||||
renderModal() {
|
||||
const { className, children } = this.props;
|
||||
|
||||
return (
|
||||
<div className="wave-modal-container">
|
||||
{this.renderBackdrop(this.props.onClickBackdrop)}
|
||||
<div className={`wave-modal ${className}`}>
|
||||
<div className="wave-modal-content">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return ReactDOM.createPortal(this.renderModal(), document.getElementById("app") as HTMLElement);
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
CmdStrCode,
|
||||
Toggle,
|
||||
@@ -980,4 +1179,9 @@ export {
|
||||
NumberField,
|
||||
PasswordField,
|
||||
Tooltip,
|
||||
Button,
|
||||
IconButton,
|
||||
LinkButton,
|
||||
Status,
|
||||
Modal,
|
||||
};
|
||||
|
||||
+218
-125
@@ -59,22 +59,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.modal.alert-modal {
|
||||
z-index: 205;
|
||||
|
||||
footer {
|
||||
justify-content: center;
|
||||
|
||||
.button {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.button:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal.settings-modal {
|
||||
footer {
|
||||
justify-content: center;
|
||||
@@ -181,59 +165,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.modal.wave-modal {
|
||||
.wave-modal-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
border-radius: 10px;
|
||||
background: var(--olive-dark-1, #151715);
|
||||
box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.35), 0px 10px 24px 0px rgba(0, 0, 0, 0.45),
|
||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.5) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset;
|
||||
|
||||
.wave-modal-content-inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
width: 100%;
|
||||
|
||||
.wave-modal-header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 20px;
|
||||
justify-content: space-between;
|
||||
line-height: 20px;
|
||||
border-bottom: 1px solid rgba(250, 250, 250, 0.1);
|
||||
|
||||
.wave-modal-title {
|
||||
color: @term-bright-white;
|
||||
font-style: normal;
|
||||
line-height: 20px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.wave-modal-close {
|
||||
display: flex;
|
||||
padding: 4px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.wave-modal-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 24px;
|
||||
width: 87%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal.tos-modal {
|
||||
.modal-content.wave-modal-content {
|
||||
padding: 32px 48px;
|
||||
@@ -323,14 +254,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
.modal.about-modal {
|
||||
.about-wave-modal-content {
|
||||
width: 401px;
|
||||
.about-modal {
|
||||
width: 382px;
|
||||
|
||||
.about-wave-modal-body {
|
||||
.wave-modal-content {
|
||||
gap: 24px;
|
||||
|
||||
.wave-modal-body {
|
||||
margin-bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 24px;
|
||||
|
||||
.about-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
align-self: stretch;
|
||||
width: 100%;
|
||||
|
||||
.wave-modal-section {
|
||||
.logo-wrapper {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
@@ -403,7 +346,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.wave-modal-section:nth-child(3) {
|
||||
.about-section:nth-child(3) {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
@@ -418,7 +361,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.wave-modal-section:last-child {
|
||||
.about-section:last-child {
|
||||
margin-bottom: 24px;
|
||||
color: @term-white;
|
||||
}
|
||||
@@ -426,71 +369,220 @@
|
||||
}
|
||||
}
|
||||
|
||||
.wave-modal.crconn-modal {
|
||||
.wave-modal-content.crconn-wave-modal-content {
|
||||
width: 452px;
|
||||
min-height: 411px;
|
||||
overflow: visible;
|
||||
.crconn-modal {
|
||||
width: 452px;
|
||||
min-height: 411px;
|
||||
|
||||
.wave-modal-content-inner.crconn-wave-modal-content-inner {
|
||||
.wave-modal-content {
|
||||
gap: 24px;
|
||||
|
||||
.wave-modal-body {
|
||||
display: flex;
|
||||
padding-bottom: 0px;
|
||||
padding: 0px 20px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
flex-shrink: 0;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
align-self: stretch;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.crconn-wave-modal-body {
|
||||
.screen-settings-modal {
|
||||
width: 640px;
|
||||
min-height: 329px;
|
||||
|
||||
.wave-modal-content {
|
||||
gap: 24px;
|
||||
|
||||
.wave-modal-body {
|
||||
display: flex;
|
||||
padding: 0px 20px;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 4px;
|
||||
align-self: stretch;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.erconn-modal {
|
||||
width: 502px;
|
||||
min-height: 411px;
|
||||
|
||||
.wave-modal-content {
|
||||
gap: 20px;
|
||||
|
||||
.wave-modal-body {
|
||||
display: flex;
|
||||
padding: 0px 20px;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
align-self: stretch;
|
||||
width: 100%;
|
||||
|
||||
> div {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.name-actions-section {
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
padding: 0px 20px;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
align-self: stretch;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.crconn-wave-modal-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
padding: 0 20px 20px;
|
||||
.name {
|
||||
color: @term-bright-white;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
.header-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-start;
|
||||
|
||||
div.button {
|
||||
margin-right: 8px;
|
||||
.wave-button {
|
||||
padding: 4px 15px;
|
||||
font-size: 11px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wave-button {
|
||||
display: flex;
|
||||
padding: 6px 16px;
|
||||
align-items: center;
|
||||
gap: var(--sizing-2-xs, 4px);
|
||||
border-radius: 6px;
|
||||
height: auto;
|
||||
.alert-modal {
|
||||
.wave-modal-content {
|
||||
.wave-modal-body {
|
||||
padding: 40px 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wave-button.color-green {
|
||||
color: @term-bright-white;
|
||||
background: @term-green !important; // !important is needed to override the default button color
|
||||
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.8) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.6) inset;
|
||||
.rconndetail-modal {
|
||||
width: 631px;
|
||||
min-height: 565px;
|
||||
|
||||
&:hover {
|
||||
color: @term-bright-white;
|
||||
.wave-modal-content {
|
||||
display: flex;
|
||||
padding-bottom: 0px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
flex-shrink: 0;
|
||||
|
||||
.wave-modal-body {
|
||||
display: flex;
|
||||
padding: 0px 20px;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
align-self: stretch;
|
||||
|
||||
.name-header-actions-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
|
||||
.rconndetail-name {
|
||||
color: @term-bright-white;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-start;
|
||||
|
||||
.wave-button {
|
||||
padding: 4px 15px;
|
||||
font-size: 11px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remote-detail {
|
||||
.settings-field {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.settings-label {
|
||||
font-weight: bold;
|
||||
width: 12em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.settings-input {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
color: @term-white;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-field:not(:first-child) {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.status {
|
||||
display: flex;
|
||||
height: 30px;
|
||||
padding: 3px 8px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
align-self: stretch;
|
||||
border-radius: 6px;
|
||||
background: rgba(241, 246, 243, 0.08);
|
||||
}
|
||||
|
||||
.terminal-wrapper {
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
|
||||
.terminal-connectelem {
|
||||
height: 163px !important; // Needed to override plugin height
|
||||
|
||||
.xterm-viewport {
|
||||
display: flex;
|
||||
padding: 6px 10px;
|
||||
gap: 8px;
|
||||
align-items: flex-start;
|
||||
align-self: stretch;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--element-separator, rgba(241, 246, 243, 0.15));
|
||||
background: #080a08;
|
||||
height: 163px !important; // Needed to override plugin height
|
||||
}
|
||||
|
||||
.xterm-screen {
|
||||
padding: 10px;
|
||||
width: 541px !important; // Needed to override plugin width
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wave-button.color-standard {
|
||||
color: @term-white;
|
||||
background: var(--overlays-white-6, rgba(255, 255, 255, 0.12));
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
|
||||
&:hover {
|
||||
color: @term-white;
|
||||
@@ -659,31 +751,32 @@
|
||||
fill: @tab-pink;
|
||||
}
|
||||
|
||||
.tab-colors {
|
||||
.tab-colors,
|
||||
.tab-icons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.tab-color-sep {
|
||||
.tab-color-sep,
|
||||
.tab-icon-sep {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tab-color-cur {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.tab-color-icon {
|
||||
.tab-color-icon,
|
||||
.tab-icon-icon {
|
||||
width: 1.1em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.tab-color-name {
|
||||
.tab-color-name,
|
||||
.tab-icon-name {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.tab-color-select {
|
||||
.tab-color-select,
|
||||
.tab-icon-select {
|
||||
cursor: pointer;
|
||||
margin: 5px;
|
||||
&:hover {
|
||||
|
||||
+976
-322
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import {
|
||||
AboutModal,
|
||||
CreateRemoteConnModal,
|
||||
ViewRemoteConnDetailModal,
|
||||
EditRemoteConnModal,
|
||||
AlertModal,
|
||||
} from "./modals";
|
||||
import * as constants from "../../appconst";
|
||||
|
||||
const modalsRegistry: { [key: string]: () => React.ReactElement } = {
|
||||
[constants.ABOUT]: () => <AboutModal />,
|
||||
[constants.CREATE_REMOTE]: () => <CreateRemoteConnModal />,
|
||||
[constants.VIEW_REMOTE]: () => <ViewRemoteConnDetailModal />,
|
||||
[constants.EDIT_REMOTE]: () => <EditRemoteConnModal />,
|
||||
[constants.ALERT]: () => <AlertModal />,
|
||||
};
|
||||
|
||||
export { modalsRegistry };
|
||||
+139
-100
@@ -7,10 +7,18 @@ import * as mobx from "mobx";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import { If, For } from "tsx-control-statements/components";
|
||||
import cn from "classnames";
|
||||
import { GlobalModel, GlobalCommandRunner, TabColors } from "../../../model/model";
|
||||
import { Toggle, InlineSettingsTextEdit, SettingsError, InfoMessage } from "../common";
|
||||
import {
|
||||
GlobalModel,
|
||||
GlobalCommandRunner,
|
||||
TabColors,
|
||||
MinFontSize,
|
||||
MaxFontSize,
|
||||
TabIcons,
|
||||
Screen,
|
||||
} from "../../../model/model";
|
||||
import { Toggle, InlineSettingsTextEdit, SettingsError, InfoMessage, Modal } from "../common";
|
||||
import { LineType, RendererPluginType, ClientDataType, CommandRtnType } from "../../../types/types";
|
||||
import { ConnectionDropdown } from "../../connections/connections";
|
||||
import { ConnectionDropdown } from "../../connections_deprecated/connections";
|
||||
import { PluginModel } from "../../../plugins/plugins";
|
||||
import * as util from "../../../util/util";
|
||||
import { commandRtnHandler } from "../../../util/util";
|
||||
@@ -50,15 +58,16 @@ Are you sure you want to stop web-sharing this tab?
|
||||
`.trim();
|
||||
|
||||
@mobxReact.observer
|
||||
class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId: string; }, {}> {
|
||||
class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId: string }, {}> {
|
||||
shareCopied: OV<boolean> = mobx.observable.box(false, { name: "ScreenSettings-shareCopied" });
|
||||
errorMessage: OV<string> = mobx.observable.box(null, { name: "ScreenSettings-errorMessage" });
|
||||
screen: Screen;
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
let { sessionId, screenId } = props;
|
||||
let screen = GlobalModel.getScreenById(sessionId, screenId);
|
||||
if (screen == null) {
|
||||
this.screen = GlobalModel.getScreenById(sessionId, screenId);
|
||||
if (this.screen == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -84,6 +93,15 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId:
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
selectTabIcon(icon: string): void {
|
||||
if (this.screen.getTabIcon() == icon) {
|
||||
return;
|
||||
}
|
||||
let prtn = GlobalCommandRunner.screenSetSettings(this.screen.screenId, { tabicon: icon }, false);
|
||||
util.commandRtnHandler(prtn, this.errorMessage);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleChangeArchived(val: boolean): void {
|
||||
let { sessionId, screenId } = this.props;
|
||||
@@ -203,105 +221,123 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId:
|
||||
render() {
|
||||
let { sessionId, screenId } = this.props;
|
||||
let inline = false;
|
||||
let screen = GlobalModel.getScreenById(sessionId, screenId);
|
||||
let screen = this.screen;
|
||||
if (screen == null) {
|
||||
return null;
|
||||
}
|
||||
console.log("screen.getTabIcon()", screen.getTabIcon());
|
||||
let color: string = null;
|
||||
let icon: string = null;
|
||||
let curRemote = GlobalModel.getRemote(GlobalModel.getActiveScreen().getCurRemoteInstance().remoteid);
|
||||
return (
|
||||
<div className={cn("modal screen-settings-modal settings-modal prompt-modal is-active")}>
|
||||
<div className="modal-background"/>
|
||||
<div className="modal-content">
|
||||
{this.shareCopied.get() && <div className="copied-indicator" />}
|
||||
<header>
|
||||
<div className="modal-title">tab settings ({screen.name.get()})</div>
|
||||
<div className="close-icon hoverEffect" title="Close (Escape)" onClick={this.closeModal}>
|
||||
<XmarkIcon />
|
||||
</div>
|
||||
</header>
|
||||
<div className="inner-content">
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Tab Id</div>
|
||||
<div className="settings-input">{screen.screenId}</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Name</div>
|
||||
<div className="settings-input">
|
||||
<InlineSettingsTextEdit
|
||||
placeholder="name"
|
||||
text={screen.name.get() ?? "(none)"}
|
||||
value={screen.name.get() ?? ""}
|
||||
onChange={this.inlineUpdateName}
|
||||
maxLength={50}
|
||||
showIcon={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Connection</div>
|
||||
<div className="settings-input">
|
||||
<ConnectionDropdown curRemote={curRemote} onSelectRemote={this.selectRemote} allowNewConn={false}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Tab Color</div>
|
||||
<div className="settings-input">
|
||||
<div className="tab-colors">
|
||||
<div className="tab-color-cur">
|
||||
<SquareIcon className={cn("tab-color-icon", "color-" + screen.getTabColor())} />
|
||||
<span className="tab-color-name">{screen.getTabColor()}</span>
|
||||
</div>
|
||||
<div className="tab-color-sep">|</div>
|
||||
<For each="color" of={TabColors}>
|
||||
<div
|
||||
key={color}
|
||||
className="tab-color-select"
|
||||
onClick={() => this.selectTabColor(color)}
|
||||
>
|
||||
<SquareIcon className={cn("tab-color-icon", "color-" + color)} />
|
||||
</div>
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">
|
||||
<div>Archived</div>
|
||||
<InfoMessage width={400}>
|
||||
Archive will hide the tab. Commands and output will be retained in
|
||||
history.
|
||||
</InfoMessage>
|
||||
</div>
|
||||
<div className="settings-input">
|
||||
<Toggle checked={screen.archived.get()} onChange={this.handleChangeArchived} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">
|
||||
<div>Actions</div>
|
||||
<InfoMessage width={400}>
|
||||
Delete will remove the tab, removing all commands and output from history.
|
||||
</InfoMessage>
|
||||
</div>
|
||||
<div className="settings-input">
|
||||
<div
|
||||
onClick={this.handleDeleteScreen}
|
||||
className="button is-prompt-danger is-outlined is-small"
|
||||
>
|
||||
Delete Tab
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<SettingsError errorMessage={this.errorMessage} />
|
||||
<Modal className="screen-settings-modal">
|
||||
<Modal.Header onClose={this.closeModal} title={`tab settings (${screen.name.get()})`} />
|
||||
<div className="wave-modal-body">
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Tab Id</div>
|
||||
<div className="settings-input">{screen.screenId}</div>
|
||||
</div>
|
||||
<footer>
|
||||
<div onClick={this.closeModal} className="button is-prompt-green is-outlined is-small">
|
||||
Close
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Name</div>
|
||||
<div className="settings-input">
|
||||
<InlineSettingsTextEdit
|
||||
placeholder="name"
|
||||
text={screen.name.get() ?? "(none)"}
|
||||
value={screen.name.get() ?? ""}
|
||||
onChange={this.inlineUpdateName}
|
||||
maxLength={50}
|
||||
showIcon={true}
|
||||
/>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Connection</div>
|
||||
<div className="settings-input">
|
||||
<ConnectionDropdown
|
||||
curRemote={curRemote}
|
||||
onSelectRemote={this.selectRemote}
|
||||
allowNewConn={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Tab Color</div>
|
||||
<div className="settings-input">
|
||||
<div className="tab-colors">
|
||||
<div className="tab-color-cur">
|
||||
<SquareIcon className={cn("tab-color-icon", "color-" + screen.getTabColor())} />
|
||||
<span className="tab-color-name">{screen.getTabColor()}</span>
|
||||
</div>
|
||||
<div className="tab-color-sep">|</div>
|
||||
<For each="color" of={TabColors}>
|
||||
<div
|
||||
key={color}
|
||||
className="tab-color-select"
|
||||
onClick={() => this.selectTabColor(color)}
|
||||
>
|
||||
<SquareIcon className={cn("tab-color-icon", "color-" + color)} />
|
||||
</div>
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">Tab Icon</div>
|
||||
<div className="settings-input">
|
||||
<div className="tab-icons">
|
||||
<div className="tab-icon-cur">
|
||||
<If condition={screen.getTabIcon() == "default"}>
|
||||
<SquareIcon className={cn("tab-color-icon", "color-white")} />
|
||||
</If>
|
||||
<If condition={screen.getTabIcon() != "default"}>
|
||||
<i className={`fa-sharp fa-solid fa-${screen.getTabIcon()}`}></i>
|
||||
</If>
|
||||
<span className="tab-icon-name">{screen.getTabIcon()}</span>
|
||||
</div>
|
||||
<div className="tab-icon-sep">|</div>
|
||||
<For each="icon" of={TabIcons}>
|
||||
<div
|
||||
key={color}
|
||||
className="tab-icon-select"
|
||||
onClick={() => this.selectTabIcon(icon)}
|
||||
>
|
||||
<i className={`fa-sharp fa-solid fa-${icon}`}></i>
|
||||
</div>
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">
|
||||
<div>Archived</div>
|
||||
<InfoMessage width={400}>
|
||||
Archive will hide the tab. Commands and output will be retained in history.
|
||||
</InfoMessage>
|
||||
</div>
|
||||
<div className="settings-input">
|
||||
<Toggle checked={screen.archived.get()} onChange={this.handleChangeArchived} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">
|
||||
<div>Actions</div>
|
||||
<InfoMessage width={400}>
|
||||
Delete will remove the tab, removing all commands and output from history.
|
||||
</InfoMessage>
|
||||
</div>
|
||||
<div className="settings-input">
|
||||
<div
|
||||
onClick={this.handleDeleteScreen}
|
||||
className="button is-prompt-danger is-outlined is-small"
|
||||
>
|
||||
Delete Tab
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<SettingsError errorMessage={this.errorMessage} />
|
||||
</div>
|
||||
</div>
|
||||
<Modal.Footer cancelLabel="Close" onCancel={this.closeModal} />
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -436,7 +472,7 @@ class SessionSettingsModal extends React.Component<{ sessionId: string }, {}> {
|
||||
<SettingsError errorMessage={this.errorMessage} />
|
||||
</div>
|
||||
<footer>
|
||||
<div onClick={this.closeModal} className="button is-prompt-green is-outlined is-small">
|
||||
<div onClick={this.closeModal} className="button is-wave-green is-outlined is-small">
|
||||
Close
|
||||
</div>
|
||||
</footer>
|
||||
@@ -572,7 +608,7 @@ class LineSettingsModal extends React.Component<{ linenum: number }, {}> {
|
||||
<div style={{ height: 50 }} />
|
||||
</div>
|
||||
<footer>
|
||||
<div onClick={this.closeModal} className="button is-prompt-green is-outlined is-small">
|
||||
<div onClick={this.closeModal} className="button is-wave-green is-outlined is-small">
|
||||
Close
|
||||
</div>
|
||||
</footer>
|
||||
@@ -630,7 +666,10 @@ class ClientSettingsModal extends React.Component<{}, {}> {
|
||||
}
|
||||
|
||||
renderFontSizeDropdown(): any {
|
||||
let availableFontSizes = [8, 9, 10, 11, 12, 13, 14, 15];
|
||||
let availableFontSizes = [];
|
||||
for (let s = MinFontSize; s <= MaxFontSize; s++) {
|
||||
availableFontSizes.push(s);
|
||||
}
|
||||
let fsize: number = 0;
|
||||
let curSize = GlobalModel.termFontSize.get();
|
||||
return (
|
||||
@@ -767,7 +806,7 @@ class ClientSettingsModal extends React.Component<{}, {}> {
|
||||
<SettingsError errorMessage={this.errorMessage} />
|
||||
</div>
|
||||
<footer>
|
||||
<div onClick={this.closeModal} className="button is-prompt-green is-outlined is-small">
|
||||
<div onClick={this.closeModal} className="button is-wave-green is-outlined is-small">
|
||||
Close
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
vertical-align: middle;
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
fill: @prompt-green;
|
||||
fill: @wave-green;
|
||||
}
|
||||
|
||||
.term-prompt-branch {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
@background-session: rgba(13, 13, 13, 0.85);
|
||||
@background-session-components: rgba(48, 49, 48, 0.6);
|
||||
@background-session-components-solid: rgb(33, 34, 33);
|
||||
@prompt-green: rgb(88, 193, 66);
|
||||
@wave-green: rgb(88, 193, 66);
|
||||
@disabled-background: rgba(76, 81, 75, 1);
|
||||
@disabled-color: #adadad;
|
||||
@scrollbar-background: rgba(21, 23, 21, 1);
|
||||
|
||||
@@ -1,408 +1,107 @@
|
||||
@import "../../app/common/themes/themes.less";
|
||||
|
||||
.modal.prompt-modal.remotes-modal {
|
||||
.modal-content {
|
||||
min-width: 850px;
|
||||
}
|
||||
.icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
fill: @base-color;
|
||||
margin: 0;
|
||||
}
|
||||
.button {
|
||||
svg {
|
||||
float: right;
|
||||
margin-top: 0.3em;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
.dropdown,
|
||||
.button {
|
||||
display: inline-flex;
|
||||
}
|
||||
.dropdown .button {
|
||||
border: none !important;
|
||||
}
|
||||
.inner-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
padding: 0;
|
||||
min-height: 45em;
|
||||
max-height: 45em;
|
||||
|
||||
.remotes-menu {
|
||||
flex: 0 0 200px;
|
||||
border-right: 1px solid @disabled-color;
|
||||
overflow-y: auto;
|
||||
|
||||
.remote-menu-item {
|
||||
border-top: 1px solid @disabled-color;
|
||||
padding: 0.5em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
cursor: pointer;
|
||||
|
||||
&.add-remote {
|
||||
padding: 10px 5px 10px 5px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
&.is-selected {
|
||||
background-color: @active-menu-color;
|
||||
|
||||
.remote-name .remote-name-secondary {
|
||||
color: @term-white;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.remote-status-light {
|
||||
width: 2em;
|
||||
margin-top: 0.7em;
|
||||
margin-right: 0.7em;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.remote-name {
|
||||
flex-grow: 1;
|
||||
|
||||
.remote-name-primary {
|
||||
font-weight: bold;
|
||||
max-width: 10em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.remote-name-secondary {
|
||||
color: @disabled-color;
|
||||
max-width: 14em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remote-detail {
|
||||
padding: 10px;
|
||||
flex-grow: 1;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.settings-field {
|
||||
margin-top: 0.75em;
|
||||
}
|
||||
|
||||
* {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.detail-subtitle {
|
||||
margin-bottom: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: @term-white;
|
||||
padding: 0.75em 0;
|
||||
margin-bottom: 0;
|
||||
border-bottom: 1px solid #777;
|
||||
}
|
||||
|
||||
.terminal-wrapper {
|
||||
margin-left: 0;
|
||||
margin-bottom: 0;
|
||||
&.has-message {
|
||||
margin-top: 0;
|
||||
}
|
||||
box-shadow: none;
|
||||
border: 1px solid #777;
|
||||
border-radius: 0 0 5px 5px;
|
||||
.xterm-rows {
|
||||
padding-top: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.remote-message {
|
||||
margin-top: 5px;
|
||||
padding: 8px;
|
||||
border-radius: 5px 5px 0 0;
|
||||
background-color: #333;
|
||||
border: 1px solid #777;
|
||||
border-bottom: none;
|
||||
|
||||
.message-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
svg {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
}
|
||||
|
||||
.remote-status {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
.button {
|
||||
height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-field {
|
||||
.update-auth-button {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.update-auth-button {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.hide-hover {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.auth-editing,
|
||||
&.create-remote {
|
||||
.settings-field.align-top {
|
||||
align-items: flex-start;
|
||||
|
||||
.settings-label {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.settings-input {
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-label {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: 12em !important;
|
||||
}
|
||||
|
||||
.settings-field .settings-input .undo-icon {
|
||||
cursor: pointer;
|
||||
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.editremote-dropdown .dropdown-trigger button {
|
||||
width: 120px;
|
||||
justify-content: flex-start;
|
||||
color: @base-color;
|
||||
border: none;
|
||||
&:hover {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-field .raw-input {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.settings-input input {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
width: 250px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.dropdown .dropdown-item {
|
||||
padding: 5px 5px 5px 12px;
|
||||
}
|
||||
|
||||
.dropdown .dropdown-content {
|
||||
max-width: 10.6em;
|
||||
}
|
||||
|
||||
.settings-input {
|
||||
.info-message {
|
||||
margin-left: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-label {
|
||||
.info-message {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.terminal-wrapper {
|
||||
position: relative;
|
||||
padding: 2px 10px 5px 4px;
|
||||
margin: 5px 5px 10px 5px;
|
||||
box-shadow: 0 0 1px 1px rgba(255, 255, 255, 0.3);
|
||||
&.focus {
|
||||
box-shadow: 0 0 3px 3px rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.term-tag {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background-color: @term-red;
|
||||
color: @term-white;
|
||||
z-index: 110;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown.conn-dropdown {
|
||||
padding-left: 0;
|
||||
.connections-view {
|
||||
background-color: @background-session;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
margin-bottom: 10px;
|
||||
margin-right: 10px;
|
||||
border-radius: 8px;
|
||||
background-color: rgba(241, 246, 243, 0.08);
|
||||
border: 1px solid rgba(241, 246, 243, 0.08);
|
||||
background: var(--element-window, rgba(13, 13, 13, 0.85));
|
||||
|
||||
.conn-dd-trigger {
|
||||
.header {
|
||||
margin: 24px 18px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 413px;
|
||||
padding: 6px 8px 6px 12px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 42px;
|
||||
|
||||
.lefticon {
|
||||
margin-right: 8px;
|
||||
margin-top: 4px;
|
||||
position: relative;
|
||||
|
||||
.status-icon {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
stroke-width: 2px;
|
||||
stroke: @status-outline;
|
||||
position: absolute;
|
||||
bottom: 3px;
|
||||
right: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
.dd-control {
|
||||
display: flex;
|
||||
padding: 4px;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.globe-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.conntext {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
flex: 1 0 0;
|
||||
|
||||
.conntext-solo {
|
||||
color: @text-primary;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.conntext-1 {
|
||||
color: @text-primary;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.conntext-2 {
|
||||
color: @text-secondary;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.connections-title {
|
||||
}
|
||||
}
|
||||
|
||||
.conn-dd-menu {
|
||||
.no-items {
|
||||
display: flex;
|
||||
width: 413px;
|
||||
padding: 6px;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
border-radius: 8px;
|
||||
background-color: @dropdown-menu;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
padding: 30px 0 30px 0;
|
||||
border: 1px solid white;
|
||||
border-radius: 3px;
|
||||
margin: 20px 50px 20px 20px;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
display: flex;
|
||||
padding: 5px 12px 5px 8px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
align-self: stretch;
|
||||
border-radius: 6px;
|
||||
.connections-table {
|
||||
margin: 0px 10px 10px 10px;
|
||||
table-layout: fixed;
|
||||
max-width: 970px;
|
||||
|
||||
.status-div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 3px;
|
||||
|
||||
svg.status-icon {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
colgroup {
|
||||
.first-col {
|
||||
max-width: 650px;
|
||||
}
|
||||
|
||||
.add-div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
svg.add-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
path {
|
||||
fill: @text-primary;
|
||||
}
|
||||
}
|
||||
.second-col {
|
||||
max-width: 150px;
|
||||
}
|
||||
.third-col {
|
||||
max-width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
.text-standard {
|
||||
thead {
|
||||
border-radius: var(--sizing-2-xs, 4px);
|
||||
border-top: 1px solid rgba(250, 250, 250, 0.1);
|
||||
border-bottom: 1px solid rgba(241, 246, 243, 0.15);
|
||||
background: var(--opacity-zinc-502, rgba(250, 250, 250, 0.02));
|
||||
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.5) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset;
|
||||
|
||||
th {
|
||||
height: 32px;
|
||||
padding: 5px 15px 5px 10px;
|
||||
color: @text-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
.text-caption {
|
||||
color: @text-caption;
|
||||
}
|
||||
|
||||
.ellipsis {
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
tr.connections-item {
|
||||
border-bottom: 1px solid rgba(241, 246, 243, 0.15);
|
||||
color: @text-secondary;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(241, 246, 243, 0.08);
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
|
||||
td.bookmark i {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
height: 40px;
|
||||
padding: 5px 15px 5px 10px;
|
||||
vertical-align: middle;
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
&.hovered {
|
||||
.action-buttons {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.help-entry {
|
||||
margin: 1em 2em;
|
||||
}
|
||||
}
|
||||
|
||||
+115
-1231
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,408 @@
|
||||
@import "../../app/common/themes/themes.less";
|
||||
|
||||
.modal.prompt-modal.remotes-modal {
|
||||
.modal-content {
|
||||
min-width: 850px;
|
||||
}
|
||||
.icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
fill: @base-color;
|
||||
margin: 0;
|
||||
}
|
||||
.button {
|
||||
svg {
|
||||
float: right;
|
||||
margin-top: 0.3em;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
.dropdown,
|
||||
.button {
|
||||
display: inline-flex;
|
||||
}
|
||||
.dropdown .button {
|
||||
border: none !important;
|
||||
}
|
||||
.inner-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
padding: 0;
|
||||
min-height: 45em;
|
||||
max-height: 45em;
|
||||
|
||||
.remotes-menu {
|
||||
flex: 0 0 200px;
|
||||
border-right: 1px solid @disabled-color;
|
||||
overflow-y: auto;
|
||||
|
||||
.remote-menu-item {
|
||||
border-top: 1px solid @disabled-color;
|
||||
padding: 0.5em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
cursor: pointer;
|
||||
|
||||
&.add-remote {
|
||||
padding: 10px 5px 10px 5px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
&.is-selected {
|
||||
background-color: @active-menu-color;
|
||||
|
||||
.remote-name .remote-name-secondary {
|
||||
color: @term-white;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.remote-status-light {
|
||||
width: 2em;
|
||||
margin-top: 0.7em;
|
||||
margin-right: 0.7em;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.remote-name {
|
||||
flex-grow: 1;
|
||||
|
||||
.remote-name-primary {
|
||||
font-weight: bold;
|
||||
max-width: 10em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.remote-name-secondary {
|
||||
color: @disabled-color;
|
||||
max-width: 14em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remote-detail {
|
||||
padding: 10px;
|
||||
flex-grow: 1;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.settings-field {
|
||||
margin-top: 0.75em;
|
||||
}
|
||||
|
||||
* {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.detail-subtitle {
|
||||
margin-bottom: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: @term-white;
|
||||
padding: 0.75em 0;
|
||||
margin-bottom: 0;
|
||||
border-bottom: 1px solid #777;
|
||||
}
|
||||
|
||||
.terminal-wrapper {
|
||||
margin-left: 0;
|
||||
margin-bottom: 0;
|
||||
&.has-message {
|
||||
margin-top: 0;
|
||||
}
|
||||
box-shadow: none;
|
||||
border: 1px solid #777;
|
||||
border-radius: 0 0 5px 5px;
|
||||
.xterm-rows {
|
||||
padding-top: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.remote-message {
|
||||
margin-top: 5px;
|
||||
padding: 8px;
|
||||
border-radius: 5px 5px 0 0;
|
||||
background-color: #333;
|
||||
border: 1px solid #777;
|
||||
border-bottom: none;
|
||||
|
||||
.message-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
svg {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
}
|
||||
|
||||
.remote-status {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
.button {
|
||||
height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-field {
|
||||
.update-auth-button {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.update-auth-button {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.hide-hover {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.auth-editing,
|
||||
&.create-remote {
|
||||
.settings-field.align-top {
|
||||
align-items: flex-start;
|
||||
|
||||
.settings-label {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.settings-input {
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-label {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: 12em !important;
|
||||
}
|
||||
|
||||
.settings-field .settings-input .undo-icon {
|
||||
cursor: pointer;
|
||||
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.editremote-dropdown .dropdown-trigger button {
|
||||
width: 120px;
|
||||
justify-content: flex-start;
|
||||
color: @base-color;
|
||||
border: none;
|
||||
&:hover {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-field .raw-input {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.settings-input input {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
width: 250px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.dropdown .dropdown-item {
|
||||
padding: 5px 5px 5px 12px;
|
||||
}
|
||||
|
||||
.dropdown .dropdown-content {
|
||||
max-width: 10.6em;
|
||||
}
|
||||
|
||||
.settings-input {
|
||||
.info-message {
|
||||
margin-left: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-label {
|
||||
.info-message {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.terminal-wrapper {
|
||||
position: relative;
|
||||
padding: 2px 10px 5px 4px;
|
||||
margin: 5px 5px 10px 5px;
|
||||
box-shadow: 0 0 1px 1px rgba(255, 255, 255, 0.3);
|
||||
&.focus {
|
||||
box-shadow: 0 0 3px 3px rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.term-tag {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background-color: @term-red;
|
||||
color: @term-white;
|
||||
z-index: 110;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown.conn-dropdown {
|
||||
padding-left: 0;
|
||||
border-radius: 8px;
|
||||
background-color: rgba(241, 246, 243, 0.08);
|
||||
|
||||
.conn-dd-trigger {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 413px;
|
||||
padding: 6px 8px 6px 12px;
|
||||
align-items: center;
|
||||
height: 42px;
|
||||
|
||||
.lefticon {
|
||||
margin-right: 8px;
|
||||
margin-top: 4px;
|
||||
position: relative;
|
||||
|
||||
.status-icon {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
stroke-width: 2px;
|
||||
stroke: @status-outline;
|
||||
position: absolute;
|
||||
bottom: 3px;
|
||||
right: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
.dd-control {
|
||||
display: flex;
|
||||
padding: 4px;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.globe-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.conntext {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
flex: 1 0 0;
|
||||
|
||||
.conntext-solo {
|
||||
color: @text-primary;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.conntext-1 {
|
||||
color: @text-primary;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.conntext-2 {
|
||||
color: @text-secondary;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.conn-dd-menu {
|
||||
display: flex;
|
||||
width: 413px;
|
||||
padding: 6px;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
border-radius: 8px;
|
||||
background-color: @dropdown-menu;
|
||||
|
||||
.dropdown-item {
|
||||
display: flex;
|
||||
padding: 5px 12px 5px 8px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
align-self: stretch;
|
||||
border-radius: 6px;
|
||||
|
||||
.status-div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 3px;
|
||||
|
||||
svg.status-icon {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.add-div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
svg.add-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
path {
|
||||
fill: @text-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-standard {
|
||||
color: @text-secondary;
|
||||
}
|
||||
|
||||
.text-caption {
|
||||
color: @text-caption;
|
||||
}
|
||||
|
||||
.ellipsis {
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(241, 246, 243, 0.08);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -188,7 +188,7 @@
|
||||
}
|
||||
|
||||
&.active {
|
||||
border: 1px solid rgba(@prompt-green, 0.8) !important;
|
||||
border: 1px solid rgba(@wave-green, 0.8) !important;
|
||||
box-shadow: 0px 0px 0.5px 0px rgba(255, 255, 255, 0.5) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset;
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
}
|
||||
|
||||
.success {
|
||||
fill: @prompt-green;
|
||||
fill: @wave-green;
|
||||
}
|
||||
|
||||
.fail {
|
||||
|
||||
@@ -68,7 +68,7 @@ class LinesView extends React.Component<
|
||||
});
|
||||
this.visibleMap = new Map();
|
||||
this.collapsedMap = new Map();
|
||||
this.computeVisibleMap_debounced = debounce(1000, this.computeVisibleMap.bind(this));
|
||||
this.computeVisibleMap_debounced = debounce(100, this.computeVisibleMap.bind(this));
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
margin-bottom: 1em;
|
||||
border: 1px solid transparent;
|
||||
&.selected {
|
||||
border-color: @prompt-green;
|
||||
border-color: @wave-green;
|
||||
}
|
||||
.plugin-summary-header {
|
||||
display: flex;
|
||||
|
||||
@@ -110,6 +110,15 @@ class MainSideBar extends React.Component<{}, {}> {
|
||||
GlobalCommandRunner.bookmarksView();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleConnectionsClick(): void {
|
||||
if (GlobalModel.activeMainView.get() == "connections") {
|
||||
GlobalModel.showSessionView();
|
||||
return;
|
||||
}
|
||||
GlobalCommandRunner.connectionsView();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleWebSharingClick(): void {
|
||||
if (GlobalModel.activeMainView.get() == "webshare") {
|
||||
@@ -126,11 +135,6 @@ class MainSideBar extends React.Component<{}, {}> {
|
||||
})();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleConnectionsClick(): void {
|
||||
GlobalModel.remotesModalModel.openModal();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
openSessionSettings(e: any, session: Session): void {
|
||||
e.preventDefault();
|
||||
@@ -199,14 +203,14 @@ class MainSideBar extends React.Component<{}, {}> {
|
||||
<div className="logo">
|
||||
<If condition={isCollapsed}>
|
||||
<div className="logo-container" onClick={this.toggleCollapsed}>
|
||||
<img src="public/logos/wave-logo.png"/>
|
||||
<img src="public/logos/wave-logo.png" />
|
||||
</div>
|
||||
</If>
|
||||
<If condition={!isCollapsed}>
|
||||
<div className="logo-container">
|
||||
<img src="public/logos/wave-dark.png"/>
|
||||
<img src="public/logos/wave-dark.png" />
|
||||
</div>
|
||||
<div className="spacer"/>
|
||||
<div className="spacer" />
|
||||
<div className="collapse-button" onClick={this.toggleCollapsed}>
|
||||
<LeftChevronIcon className="icon" />
|
||||
</div>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user