Merge pull request #23 from amhsirak/develop

feat: attribute selection UI
This commit is contained in:
Karishma Shukla
2024-08-21 23:39:43 +05:30
committed by GitHub
2 changed files with 76 additions and 37 deletions

View File

@@ -37,9 +37,9 @@ const defaultModalStyle = {
bgcolor: 'background.paper', bgcolor: 'background.paper',
boxShadow: 24, boxShadow: 24,
p: 4, p: 4,
height: '60%', height: '30%',
display: 'block', display: 'block',
overflow: 'scroll', overflow: 'hidden',
padding: '5px 25px 10px 25px', padding: '5px 25px 10px 25px',
zIndex: 3147483647, zIndex: 3147483647,
}; };

View File

@@ -1,5 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { useSocketStore } from '../../context/socket'; import { useSocketStore } from '../../context/socket';
import { Button } from '@mui/material';
import Canvas from "../atoms/canvas"; import Canvas from "../atoms/canvas";
import { useBrowserDimensionsStore } from "../../context/browserDimensions"; import { useBrowserDimensionsStore } from "../../context/browserDimensions";
import { Highlighter } from "../atoms/Highlighter"; import { Highlighter } from "../atoms/Highlighter";
@@ -20,20 +21,29 @@ interface AttributeOption {
value: string; value: string;
} }
const getAttributeOptions = (tagName: string): AttributeOption[] => { const getAttributeOptions = (tagName: string, elementInfo: ElementInfo | null): AttributeOption[] => {
if (!elementInfo) return [];
switch (tagName.toLowerCase()) { switch (tagName.toLowerCase()) {
case 'a': case 'a':
return [ const anchorOptions: AttributeOption[] = [];
{ label: 'Text', value: 'innerText' }, if (elementInfo.innerText) {
{ label: 'URL', value: 'href' } anchorOptions.push({ label: `Text: ${elementInfo.innerText}`, value: 'innerText' });
]; }
if (elementInfo.url) {
anchorOptions.push({ label: `URL: ${elementInfo.url}`, value: 'href' });
}
return anchorOptions;
case 'img': case 'img':
return [ const imgOptions: AttributeOption[] = [];
{ label: 'Alt Text', value: 'alt' }, if (elementInfo.innerText) {
{ label: 'Source URL', value: 'src' } imgOptions.push({ label: `Alt Text: ${elementInfo.innerText}`, value: 'alt' });
]; }
if (elementInfo.imageUrl) {
imgOptions.push({ label: `Image URL: ${elementInfo.imageUrl}`, value: 'src' });
}
return imgOptions;
default: default:
return [{ label: 'Text', value: 'innerText' }]; return [{ label: `Text: ${elementInfo.innerText}`, value: 'innerText' }];
} }
}; };
@@ -117,36 +127,38 @@ export const BrowserWindow = () => {
clickY >= highlightRect.top && clickY >= highlightRect.top &&
clickY <= highlightRect.bottom clickY <= highlightRect.bottom
) { ) {
const options = getAttributeOptions(highlighterData.elementInfo?.tagName || '', highlighterData.elementInfo);
if (getText === true) { if (getText === true) {
const options = getAttributeOptions(highlighterData.elementInfo?.tagName || ''); if (options.length === 1) {
if (options.length > 1) { // Directly use the available attribute if only one option is present
const attribute = options[0].value;
const data = attribute === 'href' ? highlighterData.elementInfo?.url || '' :
attribute === 'src' ? highlighterData.elementInfo?.imageUrl || '' :
highlighterData.elementInfo?.innerText || '';
addTextStep('', data, {
selector: highlighterData.selector,
tag: highlighterData.elementInfo?.tagName,
attribute
});
} else {
// Show the modal if there are multiple options
setAttributeOptions(options); setAttributeOptions(options);
setSelectedElement({ setSelectedElement({
selector: highlighterData.selector, selector: highlighterData.selector,
info: highlighterData.elementInfo info: highlighterData.elementInfo
}); });
setShowAttributeModal(true); setShowAttributeModal(true);
} else {
addTextStep('', highlighterData.elementInfo?.innerText || '', {
selector: highlighterData.selector,
tag: highlighterData.elementInfo?.tagName,
attribute: 'innerText'
});
} }
} }
if (getList === true && !listSelector) { if (getList === true && !listSelector) {
setListSelector(highlighterData.selector); setListSelector(highlighterData.selector);
} else if (getList === true && listSelector) { } else if (getList === true && listSelector) {
const options = getAttributeOptions(highlighterData.elementInfo?.tagName || ''); if (options.length === 1) {
if (options.length > 1) { // Handle directly without showing the modal
setAttributeOptions(options); const attribute = options[0].value;
setSelectedElement({
selector: highlighterData.selector,
info: highlighterData.elementInfo
});
setShowAttributeModal(true);
} else {
const newField: TextStep = { const newField: TextStep = {
id: Date.now(), id: Date.now(),
type: 'text', type: 'text',
@@ -155,7 +167,7 @@ export const BrowserWindow = () => {
selectorObj: { selectorObj: {
selector: highlighterData.selector, selector: highlighterData.selector,
tag: highlighterData.elementInfo?.tagName, tag: highlighterData.elementInfo?.tagName,
attribute: 'innerText' attribute
} }
}; };
@@ -170,8 +182,15 @@ export const BrowserWindow = () => {
if (listSelector) { if (listSelector) {
addListStep(listSelector, { ...fields, [newField.label]: newField }); addListStep(listSelector, { ...fields, [newField.label]: newField });
} }
} else {
// Show the modal if there are multiple options
setAttributeOptions(options);
setSelectedElement({
selector: highlighterData.selector,
info: highlighterData.elementInfo
});
setShowAttributeModal(true);
} }
} }
} }
} }
@@ -239,13 +258,33 @@ export const BrowserWindow = () => {
> >
<div> <div>
<h2>Select Attribute</h2> <h2>Select Attribute</h2>
{attributeOptions.map((option) => ( <div style={{ display: 'flex', flexDirection: 'column', gap: '20px', marginTop: '30px' }}>
<button key={option.value} onClick={() => handleAttributeSelection(option.value)}> {attributeOptions.map((option) => (
{option.label} <Button
</button> variant="outlined"
))} size="medium"
key={option.value}
onClick={() => handleAttributeSelection(option.value)}
style={{
justifyContent: 'flex-start',
maxWidth: '80%',
overflow: 'hidden',
padding: '5px 10px',
}}
>
<span style={{
display: 'block',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
maxWidth: '100%'
}}>
{option.label}
</span>
</Button>
))}
</div>
</div> </div>
</GenericModal> </GenericModal>
) : null ) : null
} }