Skip to content

Commit

Permalink
feat(weave): dataset editing UI
Browse files Browse the repository at this point in the history
  • Loading branch information
bcsherma committed Jan 7, 2025
1 parent 7a6bf49 commit d966b60
Show file tree
Hide file tree
Showing 5 changed files with 910 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import {Box} from '@mui/material';
import {GridRenderCellParams} from '@mui/x-data-grid-pro';
import {
GridEditInputCell,
GridRenderEditCellParams,
} from '@mui/x-data-grid-pro';
import {Icon} from '@wandb/weave/components/Icon';
import React, {useState} from 'react';
import styled from 'styled-components';

interface CellViewingRendererProps extends GridRenderCellParams {
isEdited?: boolean;
isDeleted?: boolean;
isNew?: boolean;
}

export const CellViewingRenderer: React.FC<CellViewingRendererProps> = ({
value,
isEdited = false,
isDeleted = false,
isNew = false,
api,
id,
field,
...other
}) => {
const handleEditClick = (event: React.MouseEvent) => {
event.stopPropagation();
api.startCellEditMode({id, field});
};

const [isHovered, setIsHovered] = useState(false);

return (
<Box
onClick={handleEditClick}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
sx={{
position: 'relative',
height: '100%',
width: '100%',
fontFamily: '"Source Sans Pro", sans-serif',
fontSize: '14px',
lineHeight: '1.5',
cursor: 'pointer',
backgroundColor: isDeleted
? 'rgba(255, 0, 0, 0.1)'
: isEdited
? 'rgba(0, 128, 128, 0.2)' // teal/300 20% for light mode
: isNew
? 'rgba(0, 255, 0, 0.1)'
: 'transparent',
opacity: isDeleted ? 0.5 : 1,
textDecoration: isDeleted ? 'line-through' : 'none',
borderRadius: '2px',
transition: 'background-color 0.5s ease',
padding: '12px',
'&:hover': {
backgroundColor: 'rgba(0, 0, 0, 0.1)',
},
}}>
{isHovered && (
<Box
sx={{
position: 'absolute',
top: 12,
right: 12,
opacity: 0,
transition: 'opacity 0.2s ease',
cursor: 'pointer',
animation: isHovered ? 'fadeIn 0.2s ease forwards' : 'none',
'@keyframes fadeIn': {
'0%': {
opacity: 0,
},
'100%': {
opacity: 0.5,
},
},
'&:hover': {
opacity: 0.8,
},
}}>
<Icon name="pencil-edit" size="medium" />
</Box>
)}
{value}
</Box>
);
};

const StyledEditCell = styled(GridEditInputCell)`
textarea {
height: 100% !important;
padding: 12px;
padding-top: 26px;
font-family: 'Source Sans Pro', sans-serif;
vertical-align: top;
}
.MuiInputBase-root {
height: 100%;
align-items: flex-start;
}
.MuiInputBase-input {
height: 100% !important;
}
`;

export const CellEditingRenderer: React.FC<
GridRenderEditCellParams
> = params => {
return <StyledEditCell {...params} multiline={true} />;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, {createContext, useCallback, useContext, useState} from 'react';

interface DatasetEditContextType {
editedCellsMap: Map<string, any>;
setEditedCellsMap: React.Dispatch<React.SetStateAction<Map<string, any>>>;
editedRows: Map<string, any>;
setEditedRows: React.Dispatch<React.SetStateAction<Map<string, any>>>;
processRowUpdate: (newRow: any, oldRow: any) => any;
deletedRows: number[];
setDeletedRows: React.Dispatch<React.SetStateAction<number[]>>;
addedRows: Map<string, any>;
setAddedRows: React.Dispatch<React.SetStateAction<Map<string, any>>>;
}

export const DatasetEditContext = createContext<
DatasetEditContextType | undefined
>(undefined);

export const useDatasetEditContext = () => {
const context = useContext(DatasetEditContext);
if (!context) {
throw new Error(
'useDatasetEditContext must be used within a DatasetEditProvider'
);
}
return context;
};

export const DatasetEditProvider = ({
children,
}: {
children: React.ReactNode;
}) => {
const [editedCellsMap, setEditedCellsMap] = useState<Map<string, any>>(
new Map()
);
const [editedRows, setEditedRows] = useState<Map<string, any>>(new Map());
const [deletedRows, setDeletedRows] = useState<number[]>([]);
const [addedRows, setAddedRows] = useState<Map<string, any>>(new Map());

const processRowUpdate = useCallback((newRow: any, oldRow: any) => {
const changedField = Object.keys(newRow).find(
key => newRow[key] !== oldRow[key] && key !== 'id'
);

if (changedField) {
const rowKey = `${newRow.id}`;
if (rowKey.startsWith('new-')) {
setAddedRows(prev => {
const updatedMap = new Map(prev);
updatedMap.set(rowKey, newRow);
return updatedMap;
});
} else {
setEditedCellsMap(prev => {
const existingEdits = prev.get(rowKey) || {};
const updatedMap = new Map(prev);
updatedMap.set(rowKey, {
...existingEdits,
[changedField]: newRow[changedField],
});
return updatedMap;
});
setEditedRows(prev => {
const updatedMap = new Map(prev);
updatedMap.set(rowKey, newRow);
return updatedMap;
});
}
}
return newRow;
}, []);

return (
<DatasetEditContext.Provider
value={{
editedCellsMap,
setEditedCellsMap,
editedRows,
setEditedRows,
processRowUpdate,
deletedRows,
setDeletedRows,
addedRows,
setAddedRows,
}}>
{children}
</DatasetEditContext.Provider>
);
};
Loading

0 comments on commit d966b60

Please sign in to comment.