mirror of
https://github.com/wavetermdev/backup.git
synced 2026-04-22 15:26:58 -07:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3a8e08433d | |||
| 630e46d4ba | |||
| f41ac1d5e3 | |||
| 0024f0f3e8 | |||
| 8a3d9628ba | |||
| 7c2265f3e3 | |||
| 4f6c2ee39b | |||
| a1e4e807cc | |||
| 5c85b2b786 | |||
| 4879e90e91 | |||
| a61310afc3 | |||
| 80c781bf4c | |||
| 33400e65ff | |||
| 7b58949027 | |||
| 3be96c949d | |||
| 052645e0df |
+6423
-6447
File diff suppressed because one or more lines are too long
+8
-6
@@ -32,15 +32,16 @@
|
||||
"electron-updater": "^6.1.8",
|
||||
"framer-motion": "^10.16.16",
|
||||
"mobx": "6.12",
|
||||
"mobx-react": "^7.5.0",
|
||||
"mobx-preact": "^7.5.0",
|
||||
"monaco-editor": "^0.44.0",
|
||||
"mustache": "^4.2.0",
|
||||
"node-fetch": "^3.2.10",
|
||||
"overlayscrollbars": "^2.6.1",
|
||||
"overlayscrollbars-react": "^0.5.5",
|
||||
"papaparse": "^5.4.1",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"preact": "^10.20.1",
|
||||
"react": "npm:@preact/compat",
|
||||
"react-dom": "npm:@preact/compat",
|
||||
"react-markdown": "^9.0.0",
|
||||
"remark": "^15.0.1",
|
||||
"remark-gfm": "^4.0.0",
|
||||
@@ -49,8 +50,10 @@
|
||||
"tsx-control-statements": "^5.1.1",
|
||||
"uuid": "^9.0.0",
|
||||
"winston": "^3.8.2",
|
||||
"xterm": "^5.0.0",
|
||||
"xterm-addon-web-links": "^0.9.0"
|
||||
"xterm": "^5.3.0",
|
||||
"xterm-addon-serialize": "^0.11.0",
|
||||
"xterm-addon-web-links": "^0.9.0",
|
||||
"xterm-addon-webgl": "^0.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.17.10",
|
||||
@@ -69,7 +72,6 @@
|
||||
"@types/electron": "^1.6.10",
|
||||
"@types/node": "^20.11.0",
|
||||
"@types/papaparse": "^5.3.10",
|
||||
"@types/react": "^18.0.12",
|
||||
"@types/semver": "^7.5.6",
|
||||
"@types/sprintf-js": "^1.1.3",
|
||||
"@types/throttle-debounce": "^5.0.1",
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
--form-element-border-color: rgba(241, 246, 243, 0.15);
|
||||
--form-element-bg-color: var(--app-bg-color);
|
||||
--form-element-text-color: var(--app-text-primary-color);
|
||||
--form-element-primary-text-color: var(--form-element-text-color);
|
||||
--form-element-primary-text-color: var(--app-text-primary-color);
|
||||
--form-element-label-color: var(--app-text-secondary-color);
|
||||
--form-element-primary-color: var(--app-accent-color);
|
||||
--form-element-secondary-color: rgba(255, 255, 255, 0.2);
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
/* form colors */
|
||||
--form-element-border-color: rgba(0, 0, 0, 0.3);
|
||||
--form-element-bg-color: var(--app-bg-color);
|
||||
--form-element-text-color: var(--app-text-color);
|
||||
--form-element-primary-text-color: var(--app-bg-color);
|
||||
--form-element-text-color: var(--app-text-primary-color);
|
||||
--form-element-primary-text-color: var(--app-text-primary-color);
|
||||
--form-element-label-color: rgba(0, 0, 0, 0.6);
|
||||
--form-element-secondary-color: rgba(0, 0, 0, 0.09);
|
||||
--form-element-icon-color: rgb(0, 0, 0, 0.6);
|
||||
|
||||
+5
-4
@@ -1,8 +1,9 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import React, { PureComponent } from "preact/compat";
|
||||
import { createRef, RefObject } from "preact";
|
||||
import * as mobxReact from "mobx-preact";
|
||||
import * as mobx from "mobx";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import { If } from "tsx-control-statements/components";
|
||||
@@ -28,9 +29,9 @@ import "./app.less";
|
||||
dayjs.extend(localizedFormat);
|
||||
|
||||
@mobxReact.observer
|
||||
class App extends React.Component<{}, {}> {
|
||||
class App extends PureComponent<{}, {}> {
|
||||
dcWait: OV<boolean> = mobx.observable.box(false, { name: "dcWait" });
|
||||
mainContentRef: React.RefObject<HTMLDivElement> = React.createRef();
|
||||
mainContentRef: RefObject<HTMLDivElement> = createRef();
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import React, { PureComponent } from "preact/compat";
|
||||
import * as mobxReact from "mobx-preact";
|
||||
import * as mobx from "mobx";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import { If, For } from "tsx-control-statements/components";
|
||||
@@ -22,7 +22,7 @@ type BookmarkProps = {
|
||||
bookmark: BookmarkType;
|
||||
};
|
||||
|
||||
class BookmarkKeybindings extends React.Component<{}, {}> {
|
||||
class BookmarkKeybindings extends PureComponent<{}, {}> {
|
||||
@boundMethod
|
||||
componentDidMount(): void {
|
||||
let keybindManager = GlobalModel.keybindManager;
|
||||
@@ -76,7 +76,7 @@ class BookmarkKeybindings extends React.Component<{}, {}> {
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class Bookmark extends React.Component<BookmarkProps, {}> {
|
||||
class Bookmark extends PureComponent<BookmarkProps, {}> {
|
||||
@boundMethod
|
||||
handleDeleteClick(): void {
|
||||
let { bookmark } = this.props;
|
||||
@@ -232,7 +232,7 @@ class Bookmark extends React.Component<BookmarkProps, {}> {
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class BookmarksView extends React.Component<{}, {}> {
|
||||
class BookmarksView extends PureComponent<{}, {}> {
|
||||
@boundMethod
|
||||
handleClose() {
|
||||
GlobalModel.bookmarksModel.closeView();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import React, { PureComponent } from "preact/compat";
|
||||
import * as mobxReact from "mobx-preact";
|
||||
import * as mobx from "mobx";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import { If } from "tsx-control-statements/components";
|
||||
@@ -14,7 +14,7 @@ import * as appconst from "@/app/appconst";
|
||||
import "./clientsettings.less";
|
||||
import { MainView } from "../common/elements/mainview";
|
||||
|
||||
class ClientSettingsKeybindings extends React.Component<{}, {}> {
|
||||
class ClientSettingsKeybindings extends PureComponent<{}, {}> {
|
||||
componentDidMount() {
|
||||
let clientSettingsViewModel = GlobalModel.clientSettingsViewModel;
|
||||
let keybindManager = GlobalModel.keybindManager;
|
||||
@@ -34,7 +34,7 @@ class ClientSettingsKeybindings extends React.Component<{}, {}> {
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> {
|
||||
class ClientSettingsView extends PureComponent<{ model: RemotesModel }, { hoveredItemId: string }> {
|
||||
errorMessage: OV<string> = mobx.observable.box(null, { name: "ClientSettings-errorMessage" });
|
||||
|
||||
@boundMethod
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.danger {
|
||||
background: var(--app-error-color);
|
||||
}
|
||||
|
||||
&.primary.outlined {
|
||||
background: none;
|
||||
border: 1px solid var(--form-element-primary-color);
|
||||
@@ -36,6 +40,37 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.greyoutlined {
|
||||
background: none;
|
||||
border: 1px solid var(--app-text-secondary-color);
|
||||
|
||||
i {
|
||||
fill: var(--app-text-secondary-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.outlined,
|
||||
&.primary.greyoutlined {
|
||||
&.hover-danger:hover {
|
||||
color: var(--form-element-primary-text-color);
|
||||
border: 1px solid var(--app-error-color);
|
||||
background: var(--app-error-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.outlined.danger {
|
||||
background: none;
|
||||
border: 1px solid var(--app-error-color);
|
||||
|
||||
i {
|
||||
fill: var(--app-error-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.greytext {
|
||||
color: var(--app-text-secondary-color);
|
||||
}
|
||||
|
||||
&.primary.ghost {
|
||||
background: none;
|
||||
i {
|
||||
@@ -43,6 +78,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.primary.ghost.danger {
|
||||
background: none;
|
||||
i {
|
||||
fill: var(--app-error-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
color: var(--form-element-text-color);
|
||||
background: var(--form-element-secondary-color);
|
||||
@@ -56,6 +98,11 @@
|
||||
border: 1px solid var(--form-element-text-color);
|
||||
}
|
||||
|
||||
&.secondary.outlined.danger {
|
||||
background: none;
|
||||
border: 1px solid var(--app-error-color);
|
||||
}
|
||||
|
||||
&.secondary.ghost {
|
||||
background: none;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import * as React from "react";
|
||||
import React, { PureComponent, ReactNode, CSSProperties } from "preact/compat";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import cn from "classnames";
|
||||
|
||||
import "./button.less";
|
||||
|
||||
interface ButtonProps {
|
||||
children: React.ReactNode;
|
||||
children: ReactNode;
|
||||
onClick?: () => void;
|
||||
disabled?: boolean;
|
||||
leftIcon?: React.ReactNode;
|
||||
rightIcon?: React.ReactNode;
|
||||
style?: React.CSSProperties;
|
||||
leftIcon?: ReactNode;
|
||||
rightIcon?: ReactNode;
|
||||
style?: CSSProperties;
|
||||
autoFocus?: boolean;
|
||||
className?: string;
|
||||
termInline?: boolean;
|
||||
}
|
||||
|
||||
class Button extends React.Component<ButtonProps> {
|
||||
class Button extends PureComponent<ButtonProps> {
|
||||
static defaultProps = {
|
||||
style: {},
|
||||
className: "primary",
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import * as mobx from "mobx";
|
||||
import { PureComponent, ReactNode } from "preact/compat";
|
||||
import cn from "classnames";
|
||||
|
||||
import "./checkbox.less";
|
||||
|
||||
class Checkbox extends React.Component<
|
||||
class Checkbox extends PureComponent<
|
||||
{
|
||||
checked?: boolean;
|
||||
defaultChecked?: boolean;
|
||||
onChange: (value: boolean) => void;
|
||||
label: React.ReactNode;
|
||||
label: ReactNode;
|
||||
className?: string;
|
||||
id?: string;
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import React, { PureComponent } from "preact/compat";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import cn from "classnames";
|
||||
import { If } from "tsx-control-statements/components";
|
||||
@@ -11,7 +11,7 @@ import { ReactComponent as CopyIcon } from "@/assets/icons/history/copy.svg";
|
||||
|
||||
import "./cmdstrcode.less";
|
||||
|
||||
class CmdStrCode extends React.Component<
|
||||
class CmdStrCode extends PureComponent<
|
||||
{
|
||||
cmdstr: string;
|
||||
onUse: () => void;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import React, { PureComponent } from "preact/compat";
|
||||
|
||||
function renderCmdText(text: string): any {
|
||||
return <span>⌘{text}</span>;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { useState, useEffect, useRef, createRef } from "react";
|
||||
import { RefObject, FunctionComponent, createRef, Fragment } from "preact";
|
||||
import { useState, useEffect, useRef, CSSProperties } from "preact/compat";
|
||||
import * as mobx from "mobx";
|
||||
import ReactDOM from "react-dom";
|
||||
import dayjs from "dayjs";
|
||||
@@ -11,7 +12,7 @@ import { v4 as uuidv4 } from "uuid";
|
||||
import "./datepicker.less";
|
||||
|
||||
interface YearRefs {
|
||||
[key: number]: React.RefObject<HTMLDivElement>;
|
||||
[key: number]: RefObject<HTMLDivElement>;
|
||||
}
|
||||
|
||||
type DatePickerProps = {
|
||||
@@ -20,12 +21,11 @@ type DatePickerProps = {
|
||||
format?: string;
|
||||
};
|
||||
|
||||
const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/YYYY", onSelectDate }) => {
|
||||
const DatePicker: FunctionComponent<DatePickerProps> = ({ selectedDate, format = "MM/DD/YYYY", onSelectDate }) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [selDate, setSelDate] = useState(dayjs(selectedDate)); // Initialize with dayjs object
|
||||
const [showYearAccordion, setShowYearAccordion] = useState(false);
|
||||
const [expandedYear, setExpandedYear] = useState<number | null>(selDate.year());
|
||||
const [selectionTimeoutId, setSelectionTimeoutId] = useState<string | number | NodeJS.Timeout | null>(null);
|
||||
const yearRefs = useRef<YearRefs>({});
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
const modalRef = useRef<HTMLDivElement>(null);
|
||||
@@ -200,7 +200,7 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
return days;
|
||||
};
|
||||
|
||||
const calculatePosition = (): React.CSSProperties => {
|
||||
const calculatePosition = (): CSSProperties => {
|
||||
if (wrapperRef.current) {
|
||||
const rect = wrapperRef.current.getBoundingClientRect();
|
||||
return {
|
||||
@@ -220,7 +220,7 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
|
||||
for (let year = startYear; year <= endYear; year++) {
|
||||
yearsRange.push(year);
|
||||
yearRefs.current[year] = React.createRef();
|
||||
yearRefs.current[year] = createRef();
|
||||
}
|
||||
|
||||
return yearsRange;
|
||||
@@ -302,51 +302,24 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
: null;
|
||||
|
||||
const handleDatePartChange = (part: string, value: string) => {
|
||||
console.log("Date part changed: ", part, value);
|
||||
const newDateParts = { ...dateParts, [part]: value };
|
||||
console.log("New date parts: ", newDateParts);
|
||||
setDateParts(newDateParts);
|
||||
|
||||
// Construct a new date from the updated parts
|
||||
const newDate = dayjs(`${newDateParts.YYYY}-${newDateParts.MM}-${newDateParts.DD}`);
|
||||
if (newDate.isValid()) {
|
||||
setSelDate(newDate); // Update selDate with the new dayjs object
|
||||
} else {
|
||||
console.log("Invalid date");
|
||||
setSelDate(dayjs(new Date()));
|
||||
onSelectDate(newDate.toDate()); // Call onSelectDate with the new date
|
||||
}
|
||||
onSelectDate(selDate.toDate()); // Call onSelectDate with the new date
|
||||
};
|
||||
|
||||
const handleArrowNavigation = (key: string, currentPart: string) => {
|
||||
console.log("Arrow key pressed: ", key);
|
||||
const currentIndex = formatParts.indexOf(currentPart);
|
||||
let targetInput;
|
||||
|
||||
const incrementInput = (part: string, increment: number) => {
|
||||
let newValue = parseInt(dateParts[part]) + increment;
|
||||
switch (part) {
|
||||
case "MM":
|
||||
newValue = newValue > 12 ? 1 : newValue < 1 ? 12 : newValue;
|
||||
break;
|
||||
case "DD":
|
||||
const daysInMonth = dayjs(selDate).daysInMonth();
|
||||
console.log("Days in month: ", daysInMonth);
|
||||
newValue = newValue > daysInMonth ? 1 : newValue < 1 ? daysInMonth : newValue;
|
||||
break;
|
||||
case "YYYY":
|
||||
// No bounds for year
|
||||
break;
|
||||
}
|
||||
handleDatePartChange(part, newValue.toString());
|
||||
};
|
||||
|
||||
if (key == "ArrowLeft" && currentIndex > 0) {
|
||||
targetInput = inputRefs.current[formatParts[currentIndex - 1]].current;
|
||||
} else if (key == "ArrowRight" && currentIndex < formatParts.length - 1) {
|
||||
targetInput = inputRefs.current[formatParts[currentIndex + 1]].current;
|
||||
} else if (key == "ArrowUp") {
|
||||
incrementInput(currentPart, 1);
|
||||
} else if (key == "ArrowDown") {
|
||||
incrementInput(currentPart, -1);
|
||||
}
|
||||
|
||||
if (targetInput) {
|
||||
@@ -378,14 +351,6 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
handleArrowNavigation("ArrowRight", part);
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:selectAbove", (_) => {
|
||||
handleArrowNavigation("ArrowUp", part);
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:selectBelow", (_) => {
|
||||
handleArrowNavigation("ArrowDown", part);
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:space", (_) => {
|
||||
toggleModal();
|
||||
return true;
|
||||
@@ -404,10 +369,10 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
});
|
||||
for (let numpadKey = 0; numpadKey <= 9; numpadKey++) {
|
||||
keybindManager.registerKeybinding("control", domain, "generic:numpad-" + numpadKey.toString(), (_) => {
|
||||
console.log("Numpad key pressed: ", numpadKey);
|
||||
const currentPart = part;
|
||||
const maxLength = currentPart === "YYYY" ? 4 : 2;
|
||||
const newValue = event.target.value.length < maxLength ? event.target.value + numpadKey : numpadKey;
|
||||
let selectionTimeoutId = null;
|
||||
handleDatePartChange(currentPart, newValue);
|
||||
|
||||
// Clear any existing timeout
|
||||
@@ -416,12 +381,10 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
}
|
||||
|
||||
// Re-focus and select the input after state update
|
||||
setSelectionTimeoutId(
|
||||
setTimeout(() => {
|
||||
event.target.focus();
|
||||
event.target.select();
|
||||
}, 0)
|
||||
);
|
||||
selectionTimeoutId = setTimeout(() => {
|
||||
event.target.focus();
|
||||
event.target.select();
|
||||
}, 0);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -488,14 +451,14 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
const inputRef = inputRefs.current[part];
|
||||
|
||||
return (
|
||||
<React.Fragment key={part}>
|
||||
<Fragment key={part}>
|
||||
{index > 0 && <span>{delimiter}</span>}
|
||||
<input
|
||||
readOnly
|
||||
ref={inputRef}
|
||||
type="text"
|
||||
value={dateParts[part]}
|
||||
onChange={(e) => handleDatePartChange(part, e.target.value)}
|
||||
onChange={(e) => handleDatePartChange(part, (e.target as HTMLInputElement).value)}
|
||||
onKeyDown={(e) => handleKeyDown(e, part)}
|
||||
onMouseDown={(e) => handleMouseDown(e, part)}
|
||||
onFocus={(e) => handleFocus(e, part)}
|
||||
@@ -504,7 +467,7 @@ const DatePicker: React.FC<DatePickerProps> = ({ selectedDate, format = "MM/DD/Y
|
||||
className="date-input"
|
||||
placeholder={part}
|
||||
/>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
<i
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import { RefObject, createRef } from "preact";
|
||||
import React, { PureComponent, ReactNode, TargetedEvent, CSSProperties } from "preact/compat";
|
||||
import * as mobxReact from "mobx-preact";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import cn from "classnames";
|
||||
import { If } from "tsx-control-statements/components";
|
||||
@@ -13,8 +14,8 @@ import { GlobalModel } from "@/models";
|
||||
import "./dropdown.less";
|
||||
|
||||
interface DropdownDecorationProps {
|
||||
startDecoration?: React.ReactNode;
|
||||
endDecoration?: React.ReactNode;
|
||||
startDecoration?: ReactNode;
|
||||
endDecoration?: ReactNode;
|
||||
}
|
||||
|
||||
interface DropdownProps {
|
||||
@@ -37,9 +38,9 @@ interface DropdownState {
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
wrapperRef: React.RefObject<HTMLDivElement>;
|
||||
menuRef: React.RefObject<HTMLDivElement>;
|
||||
class Dropdown extends PureComponent<DropdownProps, DropdownState> {
|
||||
wrapperRef: RefObject<HTMLDivElement>;
|
||||
menuRef: RefObject<HTMLDivElement>;
|
||||
timeoutId: any;
|
||||
curUuid: string;
|
||||
|
||||
@@ -51,9 +52,9 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
highlightedIndex: -1,
|
||||
isTouched: false,
|
||||
};
|
||||
this.wrapperRef = React.createRef();
|
||||
this.menuRef = React.createRef();
|
||||
this.curUuid == uuidv4();
|
||||
this.wrapperRef = createRef();
|
||||
this.menuRef = createRef();
|
||||
this.curUuid = uuidv4();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -100,6 +101,9 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
|
||||
@boundMethod
|
||||
handleClick() {
|
||||
if (!this.state.isOpen || !this.state.isTouched) {
|
||||
this.registerKeybindings();
|
||||
}
|
||||
this.toggleDropdown();
|
||||
}
|
||||
|
||||
@@ -109,6 +113,7 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
this.registerKeybindings();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
registerKeybindings() {
|
||||
let keybindManager = GlobalModel.keybindManager;
|
||||
let domain = "dropdown-" + this.curUuid;
|
||||
@@ -122,6 +127,7 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:cancel", (waveEvent) => {
|
||||
this.setState({ isOpen: false });
|
||||
this.unregisterKeybindings();
|
||||
return true;
|
||||
});
|
||||
keybindManager.registerKeybinding("control", domain, "generic:selectAbove", (waveEvent) => {
|
||||
@@ -165,20 +171,22 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
}
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleBlur() {
|
||||
this.unregisterKeybindings();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
unregisterKeybindings() {
|
||||
let domain = "dropdown-" + this.curUuid;
|
||||
GlobalModel.keybindManager.unregisterDomain(domain);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleKeyDown(event: React.KeyboardEvent) {}
|
||||
handleKeyDown(event) {}
|
||||
|
||||
@boundMethod
|
||||
handleSelect(value: string, event?: React.MouseEvent | React.KeyboardEvent) {
|
||||
handleSelect(value: string, event?: TargetedEvent) {
|
||||
const { onChange } = this.props;
|
||||
if (event) {
|
||||
event.stopPropagation(); // This stops the event from bubbling up to the wrapper
|
||||
@@ -189,6 +197,7 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
}
|
||||
onChange(value);
|
||||
this.setState({ isOpen: false, isTouched: true });
|
||||
this.unregisterKeybindings();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
@@ -197,7 +206,7 @@ class Dropdown extends React.Component<DropdownProps, DropdownState> {
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
calculatePosition(): React.CSSProperties {
|
||||
calculatePosition(): CSSProperties {
|
||||
if (this.wrapperRef.current) {
|
||||
const rect = this.wrapperRef.current.getBoundingClientRect();
|
||||
return {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import { createRef, RefObject } from "preact";
|
||||
import React, { PureComponent } from "preact/compat";
|
||||
import * as mobxReact from "mobx-preact";
|
||||
import * as mobx from "mobx";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import cn from "classnames";
|
||||
@@ -14,7 +15,7 @@ import { v4 as uuidv4 } from "uuid";
|
||||
import "./inlinesettingstextedit.less";
|
||||
|
||||
@mobxReact.observer
|
||||
class InlineSettingsTextEdit extends React.Component<
|
||||
class InlineSettingsTextEdit extends PureComponent<
|
||||
{
|
||||
text: string;
|
||||
value: string;
|
||||
@@ -28,7 +29,7 @@ class InlineSettingsTextEdit extends React.Component<
|
||||
isEditing: OV<boolean> = mobx.observable.box(false, { name: "inlineedit-isEditing" });
|
||||
tempText: OV<string>;
|
||||
shouldFocus: boolean = false;
|
||||
inputRef: React.RefObject<any> = React.createRef();
|
||||
inputRef: RefObject<any> = createRef();
|
||||
curId: string;
|
||||
|
||||
componentDidMount(): void {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import { PureComponent, ReactNode } from "preact/compat";
|
||||
import * as mobxReact from "mobx-preact";
|
||||
import cn from "classnames";
|
||||
|
||||
import "./inputdecoration.less";
|
||||
|
||||
interface InputDecorationProps {
|
||||
position?: "start" | "end";
|
||||
children: React.ReactNode;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class InputDecoration extends React.Component<InputDecorationProps, {}> {
|
||||
class InputDecoration extends PureComponent<InputDecorationProps, {}> {
|
||||
render() {
|
||||
const { children, position = "end" } = this.props;
|
||||
return (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import React, { PureComponent } from "preact/compat";
|
||||
import cn from "classnames";
|
||||
import { ButtonProps } from "./button";
|
||||
|
||||
@@ -11,7 +11,7 @@ interface LinkButtonProps extends ButtonProps {
|
||||
target?: string;
|
||||
}
|
||||
|
||||
class LinkButton extends React.Component<LinkButtonProps> {
|
||||
class LinkButton extends PureComponent<LinkButtonProps> {
|
||||
render() {
|
||||
const { leftIcon, rightIcon, children, className, ...rest } = this.props;
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import { PureComponent, ReactNode } from "preact/compat";
|
||||
import * as mobxReact from "mobx-preact";
|
||||
import cn from "classnames";
|
||||
import { GlobalModel } from "@/models";
|
||||
|
||||
import "./mainview.less";
|
||||
|
||||
@mobxReact.observer
|
||||
class MainView extends React.Component<{
|
||||
class MainView extends PureComponent<{
|
||||
title: string;
|
||||
onClose: () => void;
|
||||
children: React.ReactNode;
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
}> {
|
||||
render() {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import { createRef, RefObject, JSX } from "preact";
|
||||
import { PureComponent, ReactNode } from "preact/compat";
|
||||
import * as mobxReact from "mobx-preact";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import cn from "classnames";
|
||||
@@ -28,20 +29,20 @@ function CodeRenderer(props: any): any {
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class CodeBlockMarkdown extends React.Component<{ children: React.ReactNode; codeSelectSelectedIndex?: number }, {}> {
|
||||
class CodeBlockMarkdown extends PureComponent<{ children: ReactNode; codeSelectSelectedIndex?: number }, {}> {
|
||||
blockIndex: number;
|
||||
blockRef: React.RefObject<HTMLPreElement>;
|
||||
blockRef: RefObject<HTMLPreElement>;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.blockRef = React.createRef();
|
||||
this.blockRef = createRef();
|
||||
this.blockIndex = GlobalModel.inputModel.addCodeBlockToCodeSelect(this.blockRef);
|
||||
}
|
||||
|
||||
render() {
|
||||
let clickHandler: (e: React.MouseEvent<HTMLElement>, blockIndex: number) => void;
|
||||
let clickHandler: (e: JSX.TargetedMouseEvent<HTMLElement>, blockIndex: number) => void;
|
||||
let inputModel = GlobalModel.inputModel;
|
||||
clickHandler = (e: React.MouseEvent<HTMLElement>, blockIndex: number) => {
|
||||
clickHandler = (e: JSX.TargetedMouseEvent<HTMLElement>, blockIndex: number) => {
|
||||
inputModel.setCodeSelectSelectedCodeBlock(blockIndex);
|
||||
};
|
||||
let selected = this.blockIndex == this.props.codeSelectSelectedIndex;
|
||||
@@ -58,15 +59,12 @@ class CodeBlockMarkdown extends React.Component<{ children: React.ReactNode; cod
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class Markdown extends React.Component<
|
||||
{ text: string; style?: any; extraClassName?: string; codeSelect?: boolean },
|
||||
{}
|
||||
> {
|
||||
class Markdown extends PureComponent<{ text: string; style?: any; extraClassName?: string; codeSelect?: boolean }, {}> {
|
||||
CodeBlockRenderer(props: any, codeSelect: boolean, codeSelectIndex: number): any {
|
||||
if (codeSelect) {
|
||||
return <CodeBlockMarkdown codeSelectSelectedIndex={codeSelectIndex}>{props.children}</CodeBlockMarkdown>;
|
||||
} else {
|
||||
const clickHandler = (e: React.MouseEvent<HTMLElement>) => {
|
||||
const clickHandler = (e: JSX.TargetedMouseEvent<HTMLElement>) => {
|
||||
let blockText = (e.target as HTMLElement).innerText;
|
||||
if (blockText) {
|
||||
blockText = blockText.replace(/\n$/, ""); // remove trailing newline
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import { FunctionComponent } from "preact";
|
||||
import { PureComponent, ReactNode, createPortal } from "preact/compat";
|
||||
import { If } from "tsx-control-statements/components";
|
||||
import ReactDOM from "react-dom";
|
||||
import { Button } from "./button";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { GlobalModel } from "@/models";
|
||||
@@ -17,7 +17,7 @@ interface ModalHeaderProps {
|
||||
title: string;
|
||||
}
|
||||
|
||||
const ModalHeader: React.FC<ModalHeaderProps> = ({ onClose, keybindings, title }) => (
|
||||
const ModalHeader: FunctionComponent<ModalHeaderProps> = ({ onClose, keybindings, title }) => (
|
||||
<div className="wave-modal-header">
|
||||
<If condition={keybindings && onClose}>
|
||||
<ModalKeybindings onCancel={onClose}></ModalKeybindings>
|
||||
@@ -39,7 +39,7 @@ interface ModalFooterProps {
|
||||
keybindings?: boolean;
|
||||
}
|
||||
|
||||
class ModalKeybindings extends React.Component<{ onOk?: () => void; onCancel?: () => void }, {}> {
|
||||
class ModalKeybindings extends PureComponent<{ onOk?: () => void; onCancel?: () => void }, {}> {
|
||||
curId: string;
|
||||
|
||||
@boundMethod
|
||||
@@ -70,12 +70,12 @@ class ModalKeybindings extends React.Component<{ onOk?: () => void; onCancel?: (
|
||||
GlobalModel.keybindManager.unregisterDomain("modal-" + this.curId);
|
||||
}
|
||||
|
||||
render(): React.ReactNode {
|
||||
render(): ReactNode {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const ModalFooter: React.FC<ModalFooterProps> = ({
|
||||
const ModalFooter: FunctionComponent<ModalFooterProps> = ({
|
||||
onCancel,
|
||||
onOk,
|
||||
cancelLabel = "Cancel",
|
||||
@@ -101,11 +101,11 @@ const ModalFooter: React.FC<ModalFooterProps> = ({
|
||||
|
||||
interface ModalProps {
|
||||
className?: string;
|
||||
children?: React.ReactNode;
|
||||
children?: ReactNode;
|
||||
onClickBackdrop?: () => void;
|
||||
}
|
||||
|
||||
class Modal extends React.Component<ModalProps> {
|
||||
class Modal extends PureComponent<ModalProps> {
|
||||
static Header = ModalHeader;
|
||||
static Footer = ModalFooter;
|
||||
|
||||
@@ -127,7 +127,7 @@ class Modal extends React.Component<ModalProps> {
|
||||
}
|
||||
|
||||
render() {
|
||||
return ReactDOM.createPortal(this.renderModal(), document.getElementById("app"));
|
||||
return createPortal(this.renderModal(), document.getElementById("app"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user