From 5708b3f19f4290f952bcd4a2bdf4933343a3d60c Mon Sep 17 00:00:00 2001 From: sawka Date: Thu, 2 Nov 2023 01:02:50 -0700 Subject: [PATCH] working on small history UI updates --- src/app/assets/icons/checked-checkbox.svg | 6 + src/app/common/themes/themes.less | 2 + src/app/history/history.less | 75 +++++++++--- src/app/history/history.tsx | 136 +++++++++++++++++----- src/app/magiclayout.ts | 1 - src/plugins/markdown/markdown.tsx | 5 +- 6 files changed, 179 insertions(+), 46 deletions(-) create mode 100644 src/app/assets/icons/checked-checkbox.svg diff --git a/src/app/assets/icons/checked-checkbox.svg b/src/app/assets/icons/checked-checkbox.svg new file mode 100644 index 000000000..d7f354fae --- /dev/null +++ b/src/app/assets/icons/checked-checkbox.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/app/common/themes/themes.less b/src/app/common/themes/themes.less index 606bdd04c..fcb94aae7 100644 --- a/src/app/common/themes/themes.less +++ b/src/app/common/themes/themes.less @@ -22,6 +22,8 @@ @text-secondary: #C3C8C2; @text-caption: #8b918a; +@accent-color: #3B3F3A; + @status-outline: #151715; @dropdown-menu: rgba(21, 23, 21, 1); diff --git a/src/app/history/history.less b/src/app/history/history.less index d71a43656..a90f5e6a9 100644 --- a/src/app/history/history.less +++ b/src/app/history/history.less @@ -9,6 +9,31 @@ fill: @base-color; } + .history-checkbox { + &.state-unchecked { + width: 16px; + height: 16px; + border-radius: 4px; + border: 1px solid #3B3F3A; + background: rgba(213, 254, 175, 0.03); + } + + &.checkbox-icon { + width: 16px; + height: 16px; + position: relative; + top: 2px; + } + + &.state-partial { + width: 16px; + height: 16px; + fill: rgba(213, 254, 175, 0.03); + stroke-width: 1px; + stroke: #3B3F3A; + } + } + .is-left { position: absolute; left: 0.5em; @@ -152,6 +177,7 @@ margin-top: 10px; margin-left: 10px; align-items: center; + height: 32px; .is-hidden { display: none; @@ -162,14 +188,20 @@ padding-top: 4px; } + .trash-icon { + width: 12px; + height: 12px; + fill: @text-secondary; + } + .control-checkbox { - margin: 0.3em 1.2em; + margin-left: 15px; } .control-button { cursor: pointer; color: #aaa; - margin-left: 10px; + margin-left: 12px; .icon { vertical-align: text-bottom; @@ -277,19 +309,21 @@ tr.history-item { padding: 0 10px 0 10px; display: flex; - border-top: 1px solid #333; + border-bottom: 1px solid rgba(250, 250, 250, 0.10); align-items: center; + height: 40px; + color: @text-secondary; &.is-selected { - background-color: #003; + background-color: #222; } &.is-selected:hover { - background-color: #336; + background-color: #333; } &:hover { - background-color: #333; + background-color: #222; td.bookmark i { display: block; @@ -304,8 +338,7 @@ td.selectbox { flex: 0 0 auto; - flex-basis: 24px; - margin-right: 1em; + flex-basis: 25px; cursor: pointer; } @@ -318,16 +351,15 @@ td.ts { flex: 0 0 auto; - flex-basis: 74px; - font-weight: bold; - margin-right: 1em; + flex-basis: 86px; + margin-left: 24px; } td.workspace { flex: 0 0 auto; flex-basis: 120px; text-overflow: ellipsis; - margin-right: 1em; + margin-left: 24px; } td.remote { @@ -337,17 +369,15 @@ padding-right: 5px; max-width: 150px; overflow: hidden; - margin-right: 2em; + margin-left: 24px; } td.cmdstr { color: @term-white; flex: 1 0 0; - padding-left: 20px; border-radius: 3px; white-space: pre; max-height: 70px; - cursor: pointer; min-width: 300px; padding-top: 4px; padding-bottom: 4px; @@ -361,6 +391,21 @@ visibility: visible; } } + + td.downarrow { + display: flex; + width: 32px; + justify-content: center; + align-items: center; + align-self: stretch; + cursor: pointer; + + .down-icon { + width: 16px; + height: 16px; + flex-shrink: 0; + } + } } } diff --git a/src/app/history/history.tsx b/src/app/history/history.tsx index 3f19cde59..b64858f43 100644 --- a/src/app/history/history.tsx +++ b/src/app/history/history.tsx @@ -27,6 +27,9 @@ import { ReactComponent as SquareCheckIcon } from "../assets/icons/history/squar import { ReactComponent as SquareMinusIcon } from "../assets/icons/history/square-minus.svg"; import { ReactComponent as SquareIcon } from "../assets/icons/history/square.svg"; import { ReactComponent as TrashIcon } from "../assets/icons/trash.svg"; +import { ReactComponent as CheckedCheckbox } from "../assets/icons/checked-checkbox.svg"; +import { ReactComponent as CheckIcon } from "../assets/icons/line/check.svg"; +import { ReactComponent as CopyIcon } from "../assets/icons/history/copy.svg"; import "./history.less"; @@ -91,6 +94,86 @@ function formatSessionName(snames: Record, sessionId: string): s return "#" + sname; } +@mobxReact.observer +class HistoryCheckbox extends React.Component<{ checked: boolean, partialCheck?: boolean, onClick?: () => void }, {}> { + @boundMethod + clickHandler(): void { + if (this.props.onClick) { + this.props.onClick(); + } + } + + render() { + if (this.props.checked) { + return ; + } + if (this.props.partialCheck) { + return ( + + + + + + ); + } + else { + return
+ } + } +} + +class HistoryCmdStr extends React.Component< + { + cmdstr: string; + onUse: () => void; + onCopy: () => void; + isCopied: boolean; + fontSize: "normal" | "large"; + limitHeight: boolean; + }, + {} +> { + @boundMethod + handleUse(e: any) { + e.stopPropagation(); + if (this.props.onUse != null) { + this.props.onUse(); + } + } + + @boundMethod + handleCopy(e: any) { + e.stopPropagation(); + if (this.props.onCopy != null) { + this.props.onCopy(); + } + } + + render() { + let { isCopied, cmdstr, fontSize, limitHeight } = this.props; + return ( +
+ +
+
copied
+
+
+
+ +
+
+ {cmdstr} +
+
+
+ +
+
+
+ ); + } +} + @mobxReact.observer class HistoryView extends React.Component<{}, {}> { tableRef: React.RefObject = React.createRef(); @@ -330,13 +413,6 @@ class HistoryView extends React.Component<{}, {}> { let hasMore = hvm.hasMore.get(); let offset = hvm.offset.get(); let numSelected = hvm.selectedItems.size; - let controlCheckboxIcon = ; - if (numSelected > 0) { - controlCheckboxIcon = ; - } - if (numSelected > 0 && numSelected == items.length) { - controlCheckboxIcon = ; - } let activeItemId = hvm.activeItem.get(); let activeItem = hvm.getHistoryItemById(activeItemId); let activeLine: LineType = null; @@ -376,8 +452,8 @@ class HistoryView extends React.Component<{}, {}> {
{hvm.searchSessionId.get() == null - ? "Limit Workspace" - : formatSessionName(snames, hvm.searchSessionId.get())} + ? "Limit Workspace" + : formatSessionName(snames, hvm.searchSessionId.get())}
@@ -410,8 +486,8 @@ class HistoryView extends React.Component<{}, {}> {
{hvm.searchRemoteId.get() == null - ? "Limit Remote" - : formatRemoteName(rnames, { remoteid: hvm.searchRemoteId.get() })} + ? "Limit Remote" + : formatRemoteName(rnames, { remoteid: hvm.searchRemoteId.get() })}
@@ -486,7 +562,7 @@ class HistoryView extends React.Component<{}, {}> {
- {controlCheckboxIcon} + 0 && numSelected == items.length} partialCheck={numSelected > 0}/>
{ onClick={this.handleClickDelete} > - -  Delete Items + +  Delete Items
@@ -527,21 +603,10 @@ class HistoryView extends React.Component<{}, {}> { className={cn("history-item", { "is-selected": hvm.selectedItems.get(item.historyid) })} > this.handleSelect(item.historyid)}> - - - - - - + - - - - {getHistoryViewTs(nowDate, item.ts)} - {formatSSName(snames, scrnames, item)} - {formatRemoteName(rnames, item.remote)} - this.activateItem(item.historyid)}> - + this.handleUse(item)} onCopy={() => this.handleCopy(item)} @@ -550,6 +615,21 @@ class HistoryView extends React.Component<{}, {}> { limitHeight={true} /> + {formatSSName(snames, scrnames, item)} + {formatRemoteName(rnames, item.remote)} + {getHistoryViewTs(nowDate, item.ts)} + this.activateItem(item.historyid)}> + + + + + + + + + + + diff --git a/src/app/magiclayout.ts b/src/app/magiclayout.ts index dcba46209..31d9a745c 100644 --- a/src/app/magiclayout.ts +++ b/src/app/magiclayout.ts @@ -21,7 +21,6 @@ let MagicLayout = { // the 3 is for descenders, which get cut off in the terminal without this TermDescendersHeight: 3, TermWidthBuffer: 15, - }; let m = MagicLayout; diff --git a/src/plugins/markdown/markdown.tsx b/src/plugins/markdown/markdown.tsx index dd720f3ff..ea393765b 100644 --- a/src/plugins/markdown/markdown.tsx +++ b/src/plugins/markdown/markdown.tsx @@ -13,10 +13,11 @@ import "./markdown.less"; type OV = mobx.IObservableValue; const MaxMarkdownSize = 200000; +const DefaultMaxMarkdownWidth = 1000; @mobxReact.observer class SimpleMarkdownRenderer extends React.Component< - { data: T.ExtBlob; context: T.RendererContext; opts: T.RendererOpts; savedHeight: number }, + { data: T.ExtBlob; context: T.RendererContext; opts: T.RendererOpts; savedHeight: number, lineState: T.LineStateType }, {} > { markdownText: OV = mobx.observable.box(null, { name: "markdownText" }); @@ -73,7 +74,7 @@ class SimpleMarkdownRenderer extends React.Component< maxHeight: opts.maxSize.height, }} > - +
);