Convert history table to use div (#407)

* convert table to div

* remove comment

* more history UI updates.  copy/use controls, change font, fix scroll area

* use css variables

* fix textfield placeholder color

* put back input styles

* change overflow-x to auto
This commit is contained in:
Red J Adaya 2024-03-08 14:48:52 +08:00 committed by GitHub
parent 2a5857bc3d
commit c5d4a0e1f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 177 additions and 172 deletions

View File

@ -188,7 +188,7 @@
/* table colors */
--table-border-color: rgba(241, 246, 243, 0.15);
--table-thead-border-top-color: rgba(250, 250, 250, 0.1);
--table-thead-border-bottom-color: var(--table-border-color);
--table-thead-bright-border-color: #ccc;
--table-thead-bg-color: rgba(250, 250, 250, 0.02);
--table-tr-border-bottom-color: rgba(241, 246, 243, 0.15);
--table-tr-hover-bg-color: rgba(255, 255, 255, 0.06);

View File

@ -47,6 +47,8 @@
--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);
--form-element-disabled-text-color: #b7b7b7;
--form-element-placeholder-color: #b7b7b7;
/* modal colors */
--modal-header-bottom-border-color: rgba(0, 0, 0, 0.3);

View File

@ -166,7 +166,7 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
const curTheme = GlobalModel.getTheme();
return (
<MainView viewName="clientsettings" title="Client Settings" onClose={this.handleClose}>
<MainView className="clientsettings-view" title="Client Settings" onClose={this.handleClose}>
<div className="content">
<div className="settings-field">
<div className="settings-label">Term Font Size</div>

View File

@ -5,6 +5,7 @@
width: 100%;
border: 2px solid var(--form-element-border-color);
border-radius: 6px;
line-height: 22px;
background: var(--form-element-bg-color);
&.no-label {

View File

@ -10,17 +10,17 @@ import "./mainview.less";
@mobxReact.observer
class MainView extends React.Component<{
viewName: string;
title: string;
onClose: () => void;
children: React.ReactNode;
className?: string;
}> {
render() {
const sidebarModel = GlobalModel.mainSidebarModel;
const maxWidthSubtractor = sidebarModel.getCollapsed() ? 0 : sidebarModel.getWidth();
return (
<div
className={cn("mainview", `${this.props.viewName}-view`)}
className={cn("mainview", this.props.className)}
style={{ maxWidth: `calc(100vw - ${maxWidthSubtractor}px)` }}
>
<div className="header-container bottom-border">

View File

@ -64,6 +64,10 @@
&.offset-left {
padding: 5px 16px 5px 0;
}
input::placeholder {
color: var(--form-element-placeholder-color);
}
}
}

View File

@ -28,7 +28,7 @@
thead {
border-radius: var(--sizing-2-xs, 4px);
border-bottom: 2px solid var(--table-thead-border-bottom-color);
border-bottom: 2px solid var(--table-thead-bright-border-color);
th {
height: 32px;

View File

@ -126,7 +126,7 @@ class ConnectionsView extends React.Component<{ model: RemotesModel }, { hovered
let item: RemoteType = null;
return (
<MainView viewName="connections" title="Connections" onClose={this.handleClose}>
<MainView className="connections-view" title="Connections" onClose={this.handleClose}>
<table
className="connections-table"
cellSpacing="0"

View File

@ -1,5 +1,6 @@
.history-view {
padding-bottom: 10px;
min-height: 0;
.icon {
width: 1.5em !important;
@ -8,6 +9,14 @@
fill: var(--app-text-color);
}
.mainview-content {
display: flex;
flex-direction: column;
flex-grow: 1;
padding: 10px 10px 0 10px;
min-height: 0;
}
.history-checkbox {
&.state-unchecked {
width: 16px;
@ -51,16 +60,6 @@
color: var(--app-text-color);
}
.main-search {
.field {
width: 80%;
}
input::placeholder {
color: #777;
}
}
.advanced-search {
display: flex;
flex-direction: row;
@ -68,37 +67,7 @@
.workspace-dropdown,
.remote-dropdown {
width: 200px;
}
.dropdown {
font-size: 0.8em;
padding: 0.5em 1em;
.label {
display: inline;
vertical-align: middle;
color: var(--app-text-color);
}
.icon {
vertical-align: middle;
margin-left: 1em;
}
}
.session-dropdown,
.remote-dropdown {
.dropdown-item {
color: var(--app-text-color);
cursor: pointer;
&:hover {
background-color: #666;
}
}
.dropdown-content {
border-radius: 0 0 4px 4px;
width: 16em;
}
width: 170px;
}
.remote-dropdown {
@ -115,10 +84,6 @@
align-items: center;
height: 34px;
&.is-active {
background-color: #666;
}
.checkbox-container {
position: relative;
top: 2px;
@ -151,7 +116,7 @@
margin-top: 10px;
margin-left: 10px;
align-items: center;
height: 32px;
height: 35px;
flex-shrink: 0;
.is-hidden {
@ -159,8 +124,14 @@
}
&.is-top {
border-top: 1px solid #333;
border-bottom: 2px solid var(--table-thead-bright-border-color);
border-top: 1px solid var(--table-thead-border-top-color);
padding-top: 4px;
padding-bottom: 4px;
}
&.is-bottom {
border-top: 2px solid var(--table-thead-bright-border-color);
}
.trash-icon {
@ -175,7 +146,7 @@
.control-button {
cursor: pointer;
color: #aaa;
color: var(--form-element-label-color);
margin-left: 12px;
.icon {
@ -215,8 +186,11 @@
&.is-disabled {
cursor: default;
color: #777;
font-weight: normal;
.icon {
fill: var(--form-element-disabled-text-color);
}
}
}
@ -230,7 +204,7 @@
flex-direction: row;
justify-content: center;
padding: 30px 0 30px 0;
border: 1px solid white;
border: 1px solid var(--app-border-color);
border-radius: 3px;
margin: 20px 50px 20px 20px;
}
@ -239,16 +213,24 @@
flex-grow: 1;
min-height: 200px;
overflow-y: auto;
height: calc(100vh - 186px); // 186px is sum of all the heights above the history-scroll-region
}
.history-table {
margin: 0px 10px 10px 10px;
table-layout: fixed;
border-top: 2px solid #ccc;
display: flex;
flex-direction: column;
width: calc(100% - 20px);
flex-grow: 1;
min-height: 200px;
tr.active-history-item {
td {
.row.active-history-item {
display: flex;
border-bottom: 1px solid var(--table-tr-border-bottom-color);
align-items: center;
padding: 0 10px;
.cell {
padding-right: 10px;
.line-container {
@ -287,12 +269,13 @@
}
}
tr.history-item {
.row.history-item {
padding: 0 10px 0 10px;
display: flex;
border-bottom: 1px solid var(--table-tr-border-bottom-color);
align-items: center;
color: var(--app-text-color);
font: var(--base-font);
&.is-selected {
background-color: var(--table-tr-selected-bg-color);
@ -310,41 +293,27 @@
}
}
td {
.cell {
display: flex;
padding-top: 5px;
padding-bottom: 5px;
padding-left: 5px;
}
td.selectbox {
flex: 0 0 auto;
flex-basis: 25px;
.selectbox {
flex: 0 0 30px;
cursor: pointer;
}
td.bookmark {
flex: 0 0 auto;
flex-basis: 20px;
margin-right: 1em;
cursor: pointer;
}
td.ts {
flex: 0 0 auto;
flex-basis: 86px;
margin-left: 24px;
}
td.workspace {
flex: 0 0 auto;
flex-basis: 120px;
.workspace {
flex: 0 0 120px;
text-overflow: ellipsis;
margin-left: 24px;
overflow: hidden;
}
td.remote {
flex: 0 0 auto;
flex-basis: 150px;
.remote {
flex: 0 0 150px;
text-overflow: ellipsis;
padding-right: 5px;
max-width: 150px;
@ -352,29 +321,53 @@
margin-left: 24px;
}
td.cmdstr {
color: var(--app-text-color);
flex: 1 0 0;
.ts {
flex: 0 0 86px;
margin-left: 24px;
}
.cmdstr {
flex-grow: 1;
border-radius: 3px;
white-space: pre;
max-height: 70px;
min-width: 300px;
padding-top: 0;
padding-bottom: 0;
overflow-x: auto;
position: relative;
.cmdstr-code {
display: flex;
flex-direction: row;
align-items: flex-end;
padding-top: 4px;
padding-bottom: 4px;
overflow: hidden;
}
.actions-block {
display: flex;
flex-direction: row;
.action-item:hover {
color: var(--app-text-color);
cursor: pointer;
}
.use-button {
visibility: hidden;
}
&:hover .use-button {
visibility: visible;
.activate-item-spacer {
cursor: pointer;
}
}
td.downarrow {
display: flex;
width: 32px;
&:hover .cmdstr .actions-block {
visibility: visible;
}
.downarrow {
flex: 0 0 32px;
justify-content: center;
align-items: center;
align-self: stretch;

View File

@ -153,16 +153,16 @@ class HistoryCmdStr extends React.Component<
<div>copied</div>
</div>
</If>
<div key="use" className="use-button hoverEffect" title="Use Command" onClick={this.handleUse}>
<CheckIcon className="icon" />
</div>
<div key="code" className="code-div">
<code>{cmdstr}</code>
</div>
<div key="copy" className="copy-control hoverEffect">
<div className="inner-copy" onClick={this.handleCopy} title="copy">
<div key="copy" className="actions-block">
<div className="action-item" onClick={this.handleCopy} title="copy">
<CopyIcon className="icon" />
</div>
<div key="use" className="action-item" title="Use Command" onClick={this.handleUse}>
<CheckIcon className="icon" />
</div>
</div>
</div>
);
@ -447,7 +447,7 @@ class HistoryView extends React.Component<{}, {}> {
let remoteId: string = null;
return (
<MainView viewName="history" title="History" onClose={this.handleClose}>
<MainView className="history-view" title="History" onClose={this.handleClose}>
<div key="search" className="history-search">
<div className="main-search field">
<TextField
@ -544,19 +544,18 @@ class HistoryView extends React.Component<{}, {}> {
</div>
</If>
<div key="hsr" className="history-scroll-region">
<table className="history-table" cellSpacing="0" cellPadding="0" border={0} ref={this.tableRef}>
<tbody>
<div className="history-table" ref={this.tableRef}>
<For index="idx" each="item" of={items}>
<tr
<div
key={item.historyid}
className={cn("history-item", {
className={cn("row history-item", {
"is-selected": hvm.selectedItems.get(item.historyid),
})}
>
<td className="selectbox" onClick={() => this.handleSelect(item.historyid)}>
<div className="cell selectbox" onClick={() => this.handleSelect(item.historyid)}>
<HistoryCheckbox checked={hvm.selectedItems.get(item.historyid)} />
</td>
<td className="cmdstr">
</div>
<div className="cell cmdstr">
<HistoryCmdStr
cmdstr={item.cmdstr}
onUse={() => this.handleUse(item)}
@ -565,11 +564,15 @@ class HistoryView extends React.Component<{}, {}> {
fontSize="normal"
limitHeight={true}
/>
</td>
<td className="workspace text-standard">{formatSSName(snames, scrnames, item)}</td>
<td className="remote text-standard">{formatRemoteName(rnames, item.remote)}</td>
<td className="ts text-standard">{getHistoryViewTs(nowDate, item.ts)}</td>
<td className="downarrow" onClick={() => this.activateItem(item.historyid)}>
<div
className="flex-spacer activate-item-spacer"
onClick={() => this.activateItem(item.historyid)}
/>
</div>
<div className="cell workspace">{formatSSName(snames, scrnames, item)}</div>
<div className="cell remote">{formatRemoteName(rnames, item.remote)}</div>
<div className="cell ts">{getHistoryViewTs(nowDate, item.ts)}</div>
<div className="cell downarrow" onClick={() => this.activateItem(item.historyid)}>
<If condition={activeItemId != item.historyid}>
<svg
xmlns="http://www.w3.org/2000/svg"
@ -598,24 +601,26 @@ class HistoryView extends React.Component<{}, {}> {
/>
</svg>
</If>
</td>
</tr>
</div>
</div>
<If condition={activeItemId == item.historyid}>
<tr className="active-history-item">
<td colSpan={6}>
<div className="row active-history-item">
<div className="cell">
<LineContainer
key={activeItemId}
historyId={activeItemId}
width={this.tableWidth.get()}
/>
</td>
</tr>
</div>
</div>
</If>
</For>
</tbody>
</table>
</div>
<div key="control2" className={cn("control-bar", { "is-hidden": items.length == 0 || !hasMore })}>
</div>
<div
key="control2"
className={cn("control-bar", "is-bottom", { "is-hidden": items.length == 0 || !hasMore })}
>
<div className="spacer" />
<div className="showing-text">
Showing {offset + 1}-{offset + items.length}