Skip to content

Commit 0ba7672

Browse files
committed
[gephi-lite] Fine-tunes attributes editing
Details: - Clarifies colors styles for the data table - Improves table cell hover and interaction management - Fixes number attributes editing when value is 0 - Fixes autocomplete for all attribute inputs
1 parent 9936acc commit 0ba7672

File tree

5 files changed

+70
-25
lines changed

5 files changed

+70
-25
lines changed

packages/gephi-lite/src/components/common-icons.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { FieldModelType } from "@gephi/gephi-lite-sdk";
2+
import { FC } from "react";
23
import { IconType } from "react-icons";
34
import {
45
Bs123,
@@ -15,6 +16,7 @@ import {
1516
} from "react-icons/bs";
1617
import { GrOverview } from "react-icons/gr";
1718
import { ImFilesEmpty } from "react-icons/im";
19+
import { IconBaseProps } from "react-icons/lib/iconBase";
1820
import { MdLogin, MdLogout, MdOutlineRefresh, MdOutlineSaveAlt } from "react-icons/md";
1921
import {
2022
PiArrowSquareOut,
@@ -118,3 +120,7 @@ export const FieldModelIcons: Record<FieldModelType, IconType> = {
118120
keywords: BsFillTagsFill,
119121
date: BsCalendar3,
120122
};
123+
export const FieldModelIcon: FC<IconBaseProps & { type: FieldModelType }> = ({ type, ...props }) => {
124+
const Icon = FieldModelIcons[type];
125+
return <Icon {...props} />;
126+
};

packages/gephi-lite/src/components/data/Attribute.tsx

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
} from "@gephi/gephi-lite-sdk";
1111
import { isNil } from "lodash";
1212
import { DateTime } from "luxon";
13-
import { FC, createElement, useCallback, useMemo } from "react";
13+
import { FC, createElement, useCallback, useEffect, useMemo, useRef } from "react";
1414
import { useTranslation } from "react-i18next";
1515
import ReactLinkify from "react-linkify";
1616
import { MultiValueProps, OptionProps, SingleValueProps, components } from "react-select";
@@ -73,22 +73,40 @@ export const AttributeEditors: {
7373
field: FieldModel<ItemType, false, K>;
7474
}>;
7575
} = {
76-
text: ({ value, onChange }) => (
77-
<input
78-
className="form-control"
79-
type="string"
80-
value={value || ""}
81-
onChange={(e) => onChange(e.target.value || undefined)}
82-
/>
83-
),
84-
number: ({ value, onChange }) => (
85-
<input
86-
className="form-control"
87-
type="number"
88-
value={value || ""}
89-
onChange={(e) => onChange(e.target.value ? +e.target.value : undefined)}
90-
/>
91-
),
76+
text: ({ value, onChange }) => {
77+
const ref = useRef<HTMLInputElement>(null);
78+
useEffect(() => {
79+
if (ref.current) ref.current.focus();
80+
}, []);
81+
82+
return (
83+
<input
84+
ref={ref}
85+
autoFocus
86+
className="form-control"
87+
type="string"
88+
value={value ?? ""}
89+
onChange={(e) => onChange(e.target.value || undefined)}
90+
/>
91+
);
92+
},
93+
number: ({ value, onChange }) => {
94+
const ref = useRef<HTMLInputElement>(null);
95+
useEffect(() => {
96+
if (ref.current) ref.current.focus();
97+
}, []);
98+
99+
return (
100+
<input
101+
ref={ref}
102+
autoFocus
103+
className="form-control"
104+
type="number"
105+
value={value ?? ""}
106+
onChange={(e) => onChange(e.target.value ? +e.target.value : undefined)}
107+
/>
108+
);
109+
},
92110
category: ({ value, onChange, field }) => {
93111
const values = useDataCollection(field);
94112
const options = useMemo(() => Array.from(values).map(optionize), [values]);
@@ -111,6 +129,7 @@ export const AttributeEditors: {
111129

112130
return (
113131
<CreatableSelect<BaseOption>
132+
autoFocus
114133
menuPosition="absolute"
115134
value={!isNil(value) ? optionize(value) : undefined}
116135
onChange={(newValue) => onChange(newValue?.value)}
@@ -150,8 +169,9 @@ export const AttributeEditors: {
150169

151170
return (
152171
<CreatableSelect<BaseOption, true>
153-
menuPosition="absolute"
154172
isMulti
173+
autoFocus
174+
menuPosition="absolute"
155175
value={value?.map(optionize)}
156176
onChange={(newValue) => onChange(newValue.length ? newValue.map((o) => o.value) : undefined)}
157177
options={options}
@@ -164,6 +184,7 @@ export const AttributeEditors: {
164184
},
165185
date: ({ value, onChange }) => (
166186
<input
187+
autoFocus
167188
className="form-control"
168189
type="datetime-local"
169190
value={value?.toFormat("yyyy-MM-dd'T'HH:mm") ?? ""}

packages/gephi-lite/src/styles/_data-table.scss

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
@use "sass:map";
22

3+
$table-bg: $gray-200;
4+
$table-editable-columns-cell-bg: $white;
5+
$table-editable-columns-cell-hover-bg: $gray-100;
6+
$table-editable-columns-header-bg: $gray-200;
7+
$table-non-editable-columns-cell-bg: $gray-100;
8+
$table-non-editable-columns-header-bg: $gray-300;
9+
310
.data-table {
4-
background: $gray-100;
11+
background: $table-bg;
512
border: $table-border-color;
613
display: grid;
714
grid-template-rows: auto 1fr;
@@ -31,8 +38,9 @@
3138
font-weight: $font-weight-base;
3239
position: relative;
3340

41+
background: $table-editable-columns-header-bg;
3442
&.protected {
35-
background: $gray-200;
43+
background: $table-non-editable-columns-header-bg;
3644
}
3745

3846
& > div.content-wrapper {
@@ -95,6 +103,15 @@
95103

96104
padding: map.get($spacers, 1) map.get($spacers, 2);
97105

106+
background: $table-non-editable-columns-cell-bg;
107+
&.editable {
108+
background: $table-editable-columns-cell-bg;
109+
110+
&:hover {
111+
background: $table-editable-columns-cell-hover-bg;
112+
}
113+
}
114+
98115
&.editable {
99116
padding: 0;
100117

packages/gephi-lite/src/views/dataPage/dataTable/DataCell.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import { useGraphDatasetActions } from "../../../core/context/dataContexts";
88

99
export const ReadDataCell = forwardRef<
1010
HTMLSpanElement,
11-
{ value: Scalar; field: FieldModel; onDoubleClick?: MouseEventHandler }
12-
>(({ value, field, onDoubleClick }, ref) => {
11+
{ value: Scalar; field: FieldModel; onClick?: MouseEventHandler }
12+
>(({ value, field, onClick }, ref) => {
1313
return (
14-
<span ref={ref} className="data-cell" onDoubleClick={onDoubleClick}>
14+
<span ref={ref} className="data-cell" onClick={onClick}>
1515
<RenderItemAttribute value={value} field={field} />
1616
</span>
1717
);
@@ -93,7 +93,7 @@ export const DataCell: FC<{ type: ItemType; id: string; field: FieldModel; value
9393
const [isEditing, setIsEditing] = useState(false);
9494

9595
return !isEditing ? (
96-
<ReadDataCell {...props} onDoubleClick={() => setIsEditing(true)} />
96+
<ReadDataCell {...props} onClick={() => setIsEditing(true)} />
9797
) : (
9898
<EditDataCell {...props} close={() => setIsEditing(false)} />
9999
);

packages/gephi-lite/src/views/dataPage/dataTable/useDataTableColumns.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useTranslation } from "react-i18next";
55
import { PiDotsThreeVertical } from "react-icons/pi";
66

77
import Dropdown from "../../../components/Dropdown";
8+
import { FieldModelIcon } from "../../../components/common-icons";
89
import { EdgeComponentById } from "../../../components/data/Edge";
910
import { NodeComponentById } from "../../../components/data/Node";
1011
import ConfirmModal from "../../../components/modals/ConfirmModal";
@@ -149,7 +150,7 @@ export const useDataTableColumns = (itemIDs: string[]) => {
149150
header: ({ header }) => (
150151
<>
151152
<span className="column-title" onClick={header.column.getToggleSortingHandler()}>
152-
{field.id}
153+
<FieldModelIcon type={field.type} /> {field.id}
153154
</span>
154155

155156
<Arrow

0 commit comments

Comments
 (0)