Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Status controls could have a way to have icons instead of the default letters #2177

Merged

Conversation

Vaibhav91one
Copy link
Contributor

@Vaibhav91one Vaibhav91one commented Oct 28, 2024

resolves #1157

Copy link
Member

@FredLL-Avaiga FredLL-Avaiga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tx @Vaibhav91one Looks good
need tests
what if

  • the dev does not want icons but wants to keep the initials ?
  • the dev wants to set its own icons ?

@Vaibhav91one
Copy link
Contributor Author

Tx @Vaibhav91one Looks good need tests what if

  • the dev does not want icons but wants to keep the initials ?
  • the dev wants to set its own icons ?

So, the dev can use getInitials function which was being used before for the initials and if dev wants to set its own icons, just go to getStatusIcon function and change the icon which are being chosen according to the switch case. @FredLL-Avaiga

@FredLL-Avaiga
Copy link
Member

FredLL-Avaiga commented Oct 29, 2024

Tx @Vaibhav91one Looks good need tests what if

  • the dev does not want icons but wants to keep the initials ?
  • the dev wants to set its own icons ?

So, the dev can use getInitials function which was being used before for the initials and if dev wants to set its own icons, just go to getStatusIcon function and change the icon which are being chosen according to the switch case. @FredLL-Avaiga

I suppose I was not clear enough.
The "dev" in this case is the person who writes a Taipy Application (he has no knowledge of js/ts or even how this works).
He just wants to show a status by writing some python/markdown that use the taipy components.

@Vaibhav91one
Copy link
Contributor Author

Tx @Vaibhav91one Looks good need tests what if

  • the dev does not want icons but wants to keep the initials ?
  • the dev wants to set its own icons ?

So, the dev can use getInitials function which was being used before for the initials and if dev wants to set its own icons, just go to getStatusIcon function and change the icon which are being chosen according to the switch case. @FredLL-Avaiga

I suppose I was not clear enough. The "dev" in this case is the person who writes a Taipy Application (he has no knowledge of js/ts or even how this works. He just wants to show a status by writing some python/markdown that use the taipy components.

Oh, I thought a developer from taipy team, mb. So, for the intials ig a different component would be better and if we are talking about setting custom icons, rn there is no way to do that as the icons are according to status.

@FredLL-Avaiga
Copy link
Member

Oh, I thought a developer from taipy team, mb. So, for the intials ig a different component would be better and if we are talking about setting custom icons, rn there is no way to do that as the icons are according to status.

  • A simple property could be used to define with_icons or not
  • svg files could be provided for each type of status ...

@Vaibhav91one
Copy link
Contributor Author

Oh, I thought a developer from taipy team, mb. So, for the intials ig a different component would be better and if we are talking about setting custom icons, rn there is no way to do that as the icons are according to status.

  • A simple property could be used to define with_icons or not
  • svg files could be provided for each type of status ...

Hmm, Got it will look into it and update the PR.

@Vaibhav91one
Copy link
Contributor Author

Hey @FredLL-Avaiga , I was adding the requested changes and require some guidance, please look into the following,

In the statusProps I have added the following:

interface StatusProps extends TaipyBaseProps {
    value: StatusType;
    onClose?: (evt: MouseEvent) => void;
    icon?: ReactNode; // Custom delete icon
    withIcons?: boolean; 
    customSvg?: ReactNode; 
}

And then the function for choosing whether it will be initials, icon or customSvg

const getStatusIcon = (status: string, withIcons?: boolean, customSvg?: ReactNode) => {
    const color = status2Color(status);
    const iconProps = { 
        sx: { fontSize: 20, color: `${color}.main` } // Customize icon size and color
    };

    if (customSvg) {
        return <div style={{ color: `${color}.main` }}>{customSvg}</div>; // Render the custom SVG
    }

    if (withIcons) {
        switch (status2Color(status)) {
            case "success":
                return <CheckCircleIcon {...iconProps} />;
            case "warning":
                return <WarningIcon {...iconProps} />;
            case "error":
                return <ErrorIcon {...iconProps} />;
            default:
                return <InfoIcon {...iconProps} />;
        }
    } else {
        return getInitials(status); 
    }
};

Later in status component, I am taking the props and using them,

const Status = (props: StatusProps) => {
    const { value, id, withIcons = false, customSvg } = props;

    const className = useClassNames(props.libClassName, props.dynamicClassName, props.className);


    const chipProps = useMemo(() => {
        const cp: Record<string, unknown> = {};
        const statusColor = status2Color(value.status);
        cp.color = statusColor;
        cp.avatar = (
            <Avatar 
                sx={{ 
                    bgcolor: "transparent",
                    color: `${statusColor}.main`
                }}
            >
                {getStatusIcon(value.status, withIcons, customSvg)}
            </Avatar>
        );
        if (props.onClose) {
            cp.onDelete = props.onClose;
        }
        if (props.icon) {
            cp.deleteIcon = props.icon;
        }
        return cp;
    }, [value.status, props.onClose, props.icon, withIcons, customSvg]);

    return <Chip id={id} variant="outlined" {...chipProps} label={value.message} sx={chipSx} className={className} />;
};

My py script is the following:

from taipy.gui import Gui
from taipy.gui.icon import Icon

status = [
    ("warning", "Task is launched."),
    ("warning", "Taks is waiting."),
    ("error", "Task timeout."),
    ("info", "Process was cancelled.")
]

without_close = True
withIcons = True
icon = Icon("./halloween-clown.png", "Charles")

page = """
<|{status}|status|{withIcons}|customSvg={icon}|>
"""

if __name__ == "__main__":
    Gui(page).run(title="Status")

The issue here is I am not able to read the props being passed, I don't seem to get what I am doing wrong.

@FredLL-Avaiga
Copy link
Member

Why don't you update your PR with this changes so that we can discuss on something concrete ?
You'll have to define new properties in the status declaration block in

("without_close", PropertyType.boolean, False),

you cannot pass a ReactNode typed property, but you can pass an URL or a svg string, like it's done in the image component.

const svgFile = p.substring(p.length - 4).toLowerCase() === ".svg";

@Vaibhav91one
Copy link
Contributor Author

Why don't you update your PR with this changes so that we can discuss on something concrete ? You'll have to define new properties in the status declaration block in

("without_close", PropertyType.boolean, False),

you cannot pass a ReactNode typed property, but you can pass an URL or a svg string, like it's done in the image component.

const svgFile = p.substring(p.length - 4).toLowerCase() === ".svg";

Will do this and update the PR.

@Vaibhav91one
Copy link
Contributor Author

Why don't you update your PR with this changes so that we can discuss on something concrete ? You'll have to define new properties in the status declaration block in

("without_close", PropertyType.boolean, False),

you cannot pass a ReactNode typed property, but you can pass an URL or a svg string, like it's done in the image component.

const svgFile = p.substring(p.length - 4).toLowerCase() === ".svg";

Will do this and update the PR.

Hi @FredLL-Avaiga , sorry for disturbing again, but after making changes in factory.py, do I need to do anything else besides running npm run build:dev in taipy-gui. Also, I tried to run factory.py but it showed the following error.

    from ..types import PropertyType
ImportError: attempted relative import with no known parent package

@FredLL-Avaiga
Copy link
Member

Why don't you update your PR with this changes so that we can discuss on something concrete ? You'll have to define new properties in the status declaration block in

("without_close", PropertyType.boolean, False),

you cannot pass a ReactNode typed property, but you can pass an URL or a svg string, like it's done in the image component.

const svgFile = p.substring(p.length - 4).toLowerCase() === ".svg";

Will do this and update the PR.

Hi @FredLL-Avaiga , sorry for disturbing again, but after making changes in factory.py, do I need to do anything else besides running npm run build:dev in taipy-gui. Also, I tried to run factory.py but it showed the following error.

    from ..types import PropertyType
ImportError: attempted relative import with no known parent package

You need to create a python script and run it to show your component on a page
there are examples in doc/gui/examples

@Vaibhav91one
Copy link
Contributor Author

Why don't you update your PR with this changes so that we can discuss on something concrete ? You'll have to define new properties in the status declaration block in

("without_close", PropertyType.boolean, False),

you cannot pass a ReactNode typed property, but you can pass an URL or a svg string, like it's done in the image component.

const svgFile = p.substring(p.length - 4).toLowerCase() === ".svg";

Will do this and update the PR.

Hi @FredLL-Avaiga , sorry for disturbing again, but after making changes in factory.py, do I need to do anything else besides running npm run build:dev in taipy-gui. Also, I tried to run factory.py but it showed the following error.

    from ..types import PropertyType
ImportError: attempted relative import with no known parent package

You need to create a python script and run it to show your component on a page there are examples in doc/gui/examples

Oh, that's clear to me, the python script is working. The only thing I am not understanding is the property. As you guided I created a with_icons property same as without_close which will be False by default and similar to without_close I am using that in python script but the Status component is showing undefined for the prop which is withIcons.

taipy/taipy/gui/_renderers/factory.py:

 .set_attributes(
            [
                ("without_close", PropertyType.boolean, False),
                ("with_icons", PropertyType.boolean, False),
                ("hover_text", PropertyType.dynamic_string),
            ]
        ),

Python Script:

with_icons = True
content = "./halloween-clown.png"

page = """
<|{status}|status|{with_icons}|>
<|{content}|image|label=This is an image|on_action=function_name|>
"""

if __name__ == "__main__":
    Gui(page).run(title="Status")

Status Component:

interface StatusProps extends TaipyBaseProps {
    value: StatusType;
    onClose?: (evt: MouseEvent) => void;
    icon?: ReactNode; // Custom delete icon
    withIcons?: boolean; 
    content?: string; 
}

@FredLL-Avaiga
Copy link
Member

<|{status}|status|{with_icons}|>

<|{status}|status|with_icons|> or <|{status}|status|with_icons=True|>

@Vaibhav91one
Copy link
Contributor Author

<|{status}|status|{with_icons}|>

<|{status}|status|with_icons|> or <|{status}|status|with_icons=True|>

Tried the above, still not working.

@FredLL-Avaiga
Copy link
Member

FredLL-Avaiga commented Nov 6, 2024

@Vaibhav91one
Copy link
Contributor Author

Oh, will do that. Thanks @FredLL-Avaiga.

@Vaibhav91one
Copy link
Contributor Author

Hi @FredLL-Avaiga, did the requested changes PFA, screenshots and python script for testing.

  1. Default behaviour :
    default

  2. with_icons property:
    with_icons

  3. custom_icon property:
    custom_icon works with single svg also
    CustomIcons

Python Script for debugging:

from taipy.gui import Gui

status = [
    ("warning", "Task is launched."),
    ("warning", "Taks is waiting."),
    ("error", "Task timeout."),
    ("info", "Process was cancelled.")
]

with_icons = True

// For SVG url
custom_icon = "https://www.svgrepo.com/show/530594/pants.svg;https://www.svgrepo.com/show/530595/hotel.svg;https://www.svgrepo.com/show/530596/diving-goggles.svg;https://www.svgrepo.com/show/530597/hat.svg;https://www.svgrepo.com/show/530598/building.svg"

// for Local SVG Icons
custom_icon = "./mickey-and-goofy-halloween.svg;./mickey-and-goofy-halloween.svg;./mickey-and-goofy-halloween.svg;./mickey-and-goofy-halloween.svg;./mickey-and-goofy-halloween.svg"



page = """
<|{status}|status|{custom_icon}|>
<|{status}|status|{with_icons}|>
<|{status}|status|>
"""

if __name__ == "__main__":
    Gui(page).run(title="Status")
    

@FredLL-Avaiga
Copy link
Member

can you fix the linter issues ?

@Vaibhav91one
Copy link
Contributor Author

can you fix the linter issues ?

Yeah will do that, It was in factory.py file right?

@Vaibhav91one
Copy link
Contributor Author

@FredLL-Avaiga Did the requested changes and added few test cases.

@FredLL-Avaiga
Copy link
Member

front end test fails

@Vaibhav91one
Copy link
Contributor Author

front end test fails

Hi @FredLL-Avaiga , it was useMemo Hooks that were causing the issue. All Tests passed for StatusList component.

@FredLL-Avaiga FredLL-Avaiga added 📈 Improvement Improvement of a feature. 🖰 GUI Related to GUI 🟨 Priority: Medium Not blocking but should be addressed hacktoberfest hacktoberfest issues labels Nov 19, 2024
@FredLL-Avaiga FredLL-Avaiga added the ✅ hacktoberfest: approved An approved PR for Hacktoberfest rewarding label Nov 19, 2024
@jrobinAV jrobinAV added the hacktoberfest - 200💎💎 Issues rewarded by 200 points label Nov 19, 2024
@jrobinAV jrobinAV merged commit f080490 into Avaiga:develop Nov 19, 2024
132 checks passed
@jrobinAV
Copy link
Member

Thank you @Vaibhav91one !

@Vaibhav91one
Copy link
Contributor Author

Thank you @jrobinAV and @FredLL-Avaiga thank you for the guidance, learned a lot.

@RymMichaut
Copy link
Member

hey @Vaibhav91one congratulations!
Please reach out to me at [email protected] to prepare your swag shipping

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🖰 GUI Related to GUI hacktoberfest - 200💎💎 Issues rewarded by 200 points ✅ hacktoberfest: approved An approved PR for Hacktoberfest rewarding hacktoberfest hacktoberfest issues 📈 Improvement Improvement of a feature. 🟨 Priority: Medium Not blocking but should be addressed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature Improvement: Status controls could have a way to have icons instead of the default letters
4 participants