mirror of
https://github.com/cssgunc/compass.git
synced 2025-04-09 22:00:18 -04:00
Add single tag selection and editting row (#52)
This commit is contained in:
parent
251222167d
commit
dff05af79c
|
@ -108,7 +108,6 @@ const CreateDrawer: FunctionComponent<CreateDrawerProps> = ({
|
||||||
|
|
||||||
switch (detail.inputType) {
|
switch (detail.inputType) {
|
||||||
case "select-one":
|
case "select-one":
|
||||||
case "select-multiple":
|
|
||||||
initializeSelectField(detail.key);
|
initializeSelectField(detail.key);
|
||||||
inputField = (
|
inputField = (
|
||||||
<TagsInput
|
<TagsInput
|
||||||
|
@ -121,6 +120,40 @@ const CreateDrawer: FunctionComponent<CreateDrawerProps> = ({
|
||||||
detail.presetOptionsSetter ||
|
detail.presetOptionsSetter ||
|
||||||
(() => {})
|
(() => {})
|
||||||
}
|
}
|
||||||
|
singleValue={true}
|
||||||
|
onTagsChange={(
|
||||||
|
tags: Set<string>
|
||||||
|
) => {
|
||||||
|
setNewItemContent(
|
||||||
|
(prev: any) => ({
|
||||||
|
...prev,
|
||||||
|
[detail.key]:
|
||||||
|
tags.size > 0
|
||||||
|
? Array.from(
|
||||||
|
tags
|
||||||
|
)[0]
|
||||||
|
: null,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case "select-multiple":
|
||||||
|
initializeSelectField(detail.key);
|
||||||
|
inputField = (
|
||||||
|
<TagsInput
|
||||||
|
key={`${detail.key}-${renderKey}`}
|
||||||
|
presetValue={
|
||||||
|
newItemContent[detail.key] || []
|
||||||
|
}
|
||||||
|
presetOptions={
|
||||||
|
detail.presetOptionsValues || []
|
||||||
|
}
|
||||||
|
setPresetOptions={
|
||||||
|
detail.presetOptionsSetter ||
|
||||||
|
(() => {})
|
||||||
|
}
|
||||||
onTagsChange={(
|
onTagsChange={(
|
||||||
tags: Set<string>
|
tags: Set<string>
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -48,12 +48,14 @@ const Drawer: FunctionComponent<DrawerProps> = ({
|
||||||
const [isFavorite, setIsFavorite] = useState(false);
|
const [isFavorite, setIsFavorite] = useState(false);
|
||||||
const [tempRowContent, setTempRowContent] = useState(rowContent);
|
const [tempRowContent, setTempRowContent] = useState(rowContent);
|
||||||
|
|
||||||
const onRowUpdate = (updatedRow: any) => {};
|
const handleTempRowContentChangeHTML = (
|
||||||
|
|
||||||
const handleTempRowContentChange = (
|
|
||||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
|
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
|
||||||
) => {
|
) => {
|
||||||
const { name, value } = e.target;
|
const { name, value } = e.target;
|
||||||
|
handleTempRowContentChange(name, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTempRowContentChange = (name: string, value: any) => {
|
||||||
setTempRowContent((prev: any) => ({
|
setTempRowContent((prev: any) => ({
|
||||||
...prev,
|
...prev,
|
||||||
[name]: value,
|
[name]: value,
|
||||||
|
@ -68,10 +70,22 @@ const Drawer: FunctionComponent<DrawerProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleDrawer = () => {
|
const toggleDrawer = () => {
|
||||||
|
if (setRowContent && isOpen) {
|
||||||
|
setRowContent((prev: any) => {
|
||||||
|
return prev.map((row: any) => {
|
||||||
|
if (row.id === tempRowContent.id) {
|
||||||
|
return tempRowContent;
|
||||||
|
}
|
||||||
|
return row;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setIsOpen(!isOpen);
|
setIsOpen(!isOpen);
|
||||||
if (isFull) {
|
if (isFull) {
|
||||||
setIsFull(!isFull);
|
setIsFull(!isFull);
|
||||||
}
|
}
|
||||||
|
console.log("Send API request to update row content");
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleDrawerFullScreen = () => setIsFull(!isFull);
|
const toggleDrawerFullScreen = () => setIsFull(!isFull);
|
||||||
|
@ -143,16 +157,15 @@ const Drawer: FunctionComponent<DrawerProps> = ({
|
||||||
|
|
||||||
switch (detail.inputType) {
|
switch (detail.inputType) {
|
||||||
case "select-one":
|
case "select-one":
|
||||||
case "select-multiple":
|
|
||||||
valueToRender = (
|
valueToRender = (
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<div className="hover:bg-gray-50 rounded-md px-2 py-1">
|
<div className="rounded-md px-2 py-1">
|
||||||
<TagsInput
|
<TagsInput
|
||||||
presetValue={
|
presetValue={
|
||||||
typeof value ===
|
typeof value ===
|
||||||
"string"
|
"string"
|
||||||
? [value]
|
? [value]
|
||||||
: value
|
: value || []
|
||||||
}
|
}
|
||||||
presetOptions={
|
presetOptions={
|
||||||
detail.presetOptionsValues ||
|
detail.presetOptionsValues ||
|
||||||
|
@ -162,6 +175,51 @@ const Drawer: FunctionComponent<DrawerProps> = ({
|
||||||
detail.presetOptionsSetter ||
|
detail.presetOptionsSetter ||
|
||||||
(() => {})
|
(() => {})
|
||||||
}
|
}
|
||||||
|
singleValue={true}
|
||||||
|
onTagsChange={(
|
||||||
|
tags: Set<string>
|
||||||
|
) => {
|
||||||
|
const tagsArray =
|
||||||
|
Array.from(tags);
|
||||||
|
handleTempRowContentChange(
|
||||||
|
detail.key,
|
||||||
|
tagsArray.length > 0
|
||||||
|
? tagsArray[0]
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case "select-multiple":
|
||||||
|
valueToRender = (
|
||||||
|
<div className="flex-1">
|
||||||
|
<div className="rounded-md px-2 py-1">
|
||||||
|
<TagsInput
|
||||||
|
presetValue={
|
||||||
|
typeof value ===
|
||||||
|
"string"
|
||||||
|
? [value]
|
||||||
|
: value || []
|
||||||
|
}
|
||||||
|
presetOptions={
|
||||||
|
detail.presetOptionsValues ||
|
||||||
|
[]
|
||||||
|
}
|
||||||
|
setPresetOptions={
|
||||||
|
detail.presetOptionsSetter ||
|
||||||
|
(() => {})
|
||||||
|
}
|
||||||
|
onTagsChange={(
|
||||||
|
tags: Set<string>
|
||||||
|
) => {
|
||||||
|
handleTempRowContentChange(
|
||||||
|
detail.key,
|
||||||
|
Array.from(tags)
|
||||||
|
);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -175,7 +233,7 @@ const Drawer: FunctionComponent<DrawerProps> = ({
|
||||||
name={detail.key}
|
name={detail.key}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={
|
onChange={
|
||||||
handleTempRowContentChange
|
handleTempRowContentChangeHTML
|
||||||
}
|
}
|
||||||
onKeyDown={handleEnterPress}
|
onKeyDown={handleEnterPress}
|
||||||
rows={4}
|
rows={4}
|
||||||
|
@ -203,7 +261,7 @@ const Drawer: FunctionComponent<DrawerProps> = ({
|
||||||
name={detail.key}
|
name={detail.key}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={
|
onChange={
|
||||||
handleTempRowContentChange
|
handleTempRowContentChangeHTML
|
||||||
}
|
}
|
||||||
onKeyDown={handleEnterPress}
|
onKeyDown={handleEnterPress}
|
||||||
className="w-full p-1 focus:outline-gray-200 bg-transparent"
|
className="w-full p-1 focus:outline-gray-200 bg-transparent"
|
||||||
|
@ -221,7 +279,7 @@ const Drawer: FunctionComponent<DrawerProps> = ({
|
||||||
name={detail.key}
|
name={detail.key}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={
|
onChange={
|
||||||
handleTempRowContentChange
|
handleTempRowContentChangeHTML
|
||||||
}
|
}
|
||||||
onKeyDown={handleEnterPress}
|
onKeyDown={handleEnterPress}
|
||||||
className="w-full p-1 font-normal hover:text-gray-400 focus:outline-gray-200 underline text-gray-500 bg-transparent"
|
className="w-full p-1 font-normal hover:text-gray-400 focus:outline-gray-200 underline text-gray-500 bg-transparent"
|
||||||
|
|
|
@ -33,7 +33,7 @@ export const FilterBox = () => {
|
||||||
>
|
>
|
||||||
<span>{tag}</span>
|
<span>{tag}</span>
|
||||||
<span
|
<span
|
||||||
className="ml-2 cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() => handleTagChange(tag)}
|
onClick={() => handleTagChange(tag)}
|
||||||
>
|
>
|
||||||
×
|
×
|
||||||
|
|
|
@ -113,10 +113,6 @@ export default function Table<T extends DataPoint>({
|
||||||
// });
|
// });
|
||||||
// };
|
// };
|
||||||
|
|
||||||
const addData = () => {
|
|
||||||
setData([...data]);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add data manipulation options to the first column
|
// Add data manipulation options to the first column
|
||||||
columns.unshift(
|
columns.unshift(
|
||||||
columnHelper.display({
|
columnHelper.display({
|
||||||
|
@ -139,11 +135,6 @@ export default function Table<T extends DataPoint>({
|
||||||
setQuery(String(target.value));
|
setQuery(String(target.value));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCellChange = (e: ChangeEvent, key: Key) => {
|
|
||||||
const target = e.target as HTMLInputElement;
|
|
||||||
console.log(key);
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Filtering
|
// TODO: Filtering
|
||||||
|
|
||||||
// TODO: Sorting
|
// TODO: Sorting
|
||||||
|
@ -163,16 +154,6 @@ export default function Table<T extends DataPoint>({
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleRowData = (row: any) => {
|
|
||||||
const rowData: any = {};
|
|
||||||
row.cells.forEach((cell: any) => {
|
|
||||||
rowData[cell.column.id] = cell.value;
|
|
||||||
});
|
|
||||||
// Use rowData object containing data from all columns for the current row
|
|
||||||
console.log(rowData);
|
|
||||||
return rowData;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div className="flex flex-row justify-end">
|
<div className="flex flex-row justify-end">
|
||||||
|
|
|
@ -99,7 +99,7 @@ export default function UserTable({ data, setData }: UserTableProps) {
|
||||||
cell: (info) => (
|
cell: (info) => (
|
||||||
<div className="flex flex-wrap gap-2 items-center px-2">
|
<div className="flex flex-wrap gap-2 items-center px-2">
|
||||||
<Tag>
|
<Tag>
|
||||||
{info.getValue().length != 0
|
{info.getValue() && info.getValue().length != 0
|
||||||
? info.getValue()
|
? info.getValue()
|
||||||
: "no role"}
|
: "no role"}
|
||||||
</Tag>
|
</Tag>
|
||||||
|
|
|
@ -9,6 +9,7 @@ interface TagsInputProps {
|
||||||
presetValue: string[];
|
presetValue: string[];
|
||||||
setPresetOptions: Dispatch<SetStateAction<string[]>>;
|
setPresetOptions: Dispatch<SetStateAction<string[]>>;
|
||||||
onTagsChange?: (tags: Set<string>) => void;
|
onTagsChange?: (tags: Set<string>) => void;
|
||||||
|
singleValue?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TagsInput: React.FC<TagsInputProps> = ({
|
const TagsInput: React.FC<TagsInputProps> = ({
|
||||||
|
@ -16,6 +17,7 @@ const TagsInput: React.FC<TagsInputProps> = ({
|
||||||
presetOptions,
|
presetOptions,
|
||||||
setPresetOptions,
|
setPresetOptions,
|
||||||
onTagsChange,
|
onTagsChange,
|
||||||
|
singleValue = false,
|
||||||
}) => {
|
}) => {
|
||||||
const [inputValue, setInputValue] = useState("");
|
const [inputValue, setInputValue] = useState("");
|
||||||
const [cellSelected, setCellSelected] = useState(false);
|
const [cellSelected, setCellSelected] = useState(false);
|
||||||
|
@ -65,6 +67,10 @@ const TagsInput: React.FC<TagsInputProps> = ({
|
||||||
|
|
||||||
const handleAddTag = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
const handleAddTag = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||||
if (e.key === "Enter" && inputValue.trim()) {
|
if (e.key === "Enter" && inputValue.trim()) {
|
||||||
|
if (singleValue && tags.size >= 1) {
|
||||||
|
// Don't add new tag if we're in single value mode and already have a tag
|
||||||
|
return;
|
||||||
|
}
|
||||||
addTag(e);
|
addTag(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -81,7 +87,11 @@ const TagsInput: React.FC<TagsInputProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectTag = (tagToAdd: string) => {
|
const handleSelectTag = (tagToAdd: string) => {
|
||||||
if (!tags.has(tagToAdd)) {
|
if (singleValue) {
|
||||||
|
const newTags = new Set([tagToAdd]);
|
||||||
|
setTags(newTags);
|
||||||
|
onTagsChange?.(newTags);
|
||||||
|
} else if (!tags.has(tagToAdd)) {
|
||||||
const newTags = new Set(Array.from(tags).concat(tagToAdd));
|
const newTags = new Set(Array.from(tags).concat(tagToAdd));
|
||||||
setTags(newTags);
|
setTags(newTags);
|
||||||
onTagsChange?.(newTags);
|
onTagsChange?.(newTags);
|
||||||
|
@ -151,31 +161,45 @@ const TagsInput: React.FC<TagsInputProps> = ({
|
||||||
active
|
active
|
||||||
tags={tags}
|
tags={tags}
|
||||||
/>
|
/>
|
||||||
<input
|
{(!singleValue || tags.size === 0) && (
|
||||||
type="text"
|
<input
|
||||||
value={inputValue}
|
type="text"
|
||||||
placeholder="Search for an option..."
|
value={inputValue}
|
||||||
onChange={handleInputChange}
|
placeholder={
|
||||||
onKeyDown={handleAddTag}
|
singleValue && tags.size > 0
|
||||||
className="focus:outline-none bg-transparent"
|
? ""
|
||||||
autoFocus
|
: "Search for an option..."
|
||||||
/>
|
}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
onKeyDown={handleAddTag}
|
||||||
|
className="focus:outline-none bg-transparent"
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex rounded-b-md bg-white flex-col border-t border-gray-100 text-2xs font-medium text-gray-500 p-2">
|
<div className="flex rounded-b-md bg-white flex-col border-t border-gray-100 text-2xs font-medium text-gray-500 p-2">
|
||||||
<p className="capitalize">
|
<p className="capitalize">
|
||||||
Select an option or create one
|
{singleValue && tags.size > 0
|
||||||
|
? "Only one option can be selected"
|
||||||
|
: "Select an option or create one"}
|
||||||
</p>
|
</p>
|
||||||
<TagDropdown
|
{(!singleValue || tags.size === 0) && (
|
||||||
handleDeleteTag={handleDeleteTagOption}
|
<>
|
||||||
handleEditTag={handleEditTag}
|
<TagDropdown
|
||||||
handleAdd={handleSelectTag}
|
handleDeleteTag={
|
||||||
tags={filteredOptions}
|
handleDeleteTagOption
|
||||||
/>
|
}
|
||||||
{inputValue.length > 0 && (
|
handleEditTag={handleEditTag}
|
||||||
<CreateNewTagAction
|
handleAdd={handleSelectTag}
|
||||||
input={inputValue}
|
tags={filteredOptions}
|
||||||
addTag={addTag}
|
/>
|
||||||
/>
|
{inputValue.length > 0 && (
|
||||||
|
<CreateNewTagAction
|
||||||
|
input={inputValue}
|
||||||
|
addTag={addTag}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,7 +8,7 @@ export interface Tags {
|
||||||
|
|
||||||
export const TagsArray = ({ tags, handleDelete, active = false }: Tags) => {
|
export const TagsArray = ({ tags, handleDelete, active = false }: Tags) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex ml-2 flex-wrap gap-2 items-center min-h-[24px] min-w-[100px] rounded-md hover:bg-gray-100 p-1">
|
<div className="flex flex-wrap gap-2 items-center min-h-[24px] min-w-[100px] rounded-md hover:bg-gray-100 p-1">
|
||||||
{Array.from(tags).length > 0 ? (
|
{Array.from(tags).length > 0 ? (
|
||||||
Array.from(tags).map((tag, index) => {
|
Array.from(tags).map((tag, index) => {
|
||||||
return (
|
return (
|
||||||
|
|
Loading…
Reference in New Issue
Block a user