From 6550d26b80bb1d5f25dee2e28f8b6de76e71612d Mon Sep 17 00:00:00 2001 From: Rohid Date: Fri, 30 Aug 2024 00:08:24 +0600 Subject: [PATCH] assign custom project name to url --- src/components/CustomProjectNameList.tsx | 93 ++++++++++++++++++++++++ src/components/Options.tsx | 56 +++++++++----- src/components/SitesList.tsx | 81 ++++++++++++++------- src/core/WakaTimeCore.ts | 13 +++- src/utils/settings.ts | 9 +++ 5 files changed, 205 insertions(+), 47 deletions(-) create mode 100644 src/components/CustomProjectNameList.tsx diff --git a/src/components/CustomProjectNameList.tsx b/src/components/CustomProjectNameList.tsx new file mode 100644 index 0000000..b502681 --- /dev/null +++ b/src/components/CustomProjectNameList.tsx @@ -0,0 +1,93 @@ +import React, { useCallback } from 'react'; +import { ProjectName } from '../utils/settings'; + +type Props = { + handleChange: (sites: ProjectName[]) => void; + helpText: string; + label: string; + projectNamePlaceholder?: string; + sites: ProjectName[]; + urlPlaceholder?: string; +}; + +export default function CustomProjectNameList({ + handleChange, + label, + urlPlaceholder, + projectNamePlaceholder, + sites, +}: Props): JSX.Element { + const handleAddNewSite = useCallback(() => { + handleChange([...sites, { projectName: '', url: '' }]); + }, [handleChange, sites]); + + const handleUrlChangeForSite = useCallback( + (event: React.ChangeEvent, index: number) => { + handleChange( + sites.map((item, i) => (i === index ? { ...item, url: event.target.value } : item)), + ); + }, + [handleChange, sites], + ); + + const handleOnProjectNameChange = useCallback( + (event: React.ChangeEvent, index: number) => { + handleChange( + sites.map((item, i) => (i === index ? { ...item, projectName: event.target.value } : item)), + ); + }, + [handleChange, sites], + ); + + const handleRemoveSite = useCallback( + (index: number) => { + handleChange(sites.filter((_, i) => i !== index)); + }, + [handleChange, sites], + ); + + return ( +
+ + + {sites.length > 0 && ( +
+ {sites.map((site, i) => ( +
+
+ handleUrlChangeForSite(e, i)} + /> +
+
+ handleOnProjectNameChange(e, i)} + /> +
+ +
+ ))} +
+ )} + + +
+ ); +} diff --git a/src/components/Options.tsx b/src/components/Options.tsx index 90002b2..33fdee2 100644 --- a/src/components/Options.tsx +++ b/src/components/Options.tsx @@ -2,8 +2,9 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import config, { SuccessOrFailType } from '../config/config'; import apiKeyInvalid from '../utils/apiKey'; import { IS_CHROME } from '../utils/operatingSystem'; -import { getSettings, saveSettings, Settings } from '../utils/settings'; +import { getSettings, ProjectName, saveSettings, Settings } from '../utils/settings'; import { logUserIn } from '../utils/user'; +import CustomProjectNameList from './CustomProjectNameList'; import SitesList from './SitesList'; interface State extends Settings { @@ -19,6 +20,7 @@ export default function Options(): JSX.Element { allowList: [], apiKey: '', apiUrl: config.apiUrl, + customProjectNames: [], denyList: [], extensionStatus: 'allGood', hostname: '', @@ -54,16 +56,19 @@ export default function Options(): JSX.Element { state.apiUrl = state.apiUrl.slice(0, -1); } await saveSettings({ - allowList: state.allowList, + allowList: state.allowList.filter((item) => !!item.trim()), apiKey: state.apiKey, apiUrl: state.apiUrl, - denyList: state.denyList, + customProjectNames: state.customProjectNames.filter( + (item) => !!item.url.trim() && !!item.projectName.trim(), + ), + denyList: state.denyList.filter((item) => !!item.trim()), extensionStatus: state.extensionStatus, hostname: state.hostname, loggingEnabled: state.loggingEnabled, loggingStyle: state.loggingStyle, loggingType: state.loggingType, - socialMediaSites: state.socialMediaSites, + socialMediaSites: state.socialMediaSites.filter((item) => !!item.trim()), theme: state.theme, trackSocialMedia: state.trackSocialMedia, }); @@ -74,17 +79,24 @@ export default function Options(): JSX.Element { } }; - const updateDenyListState = useCallback((sites: string) => { + const updateDenyListState = useCallback((denyList: string[]) => { setState((oldState) => ({ ...oldState, - denyList: sites.trim().split('\n'), + denyList, })); }, []); - const updateAllowListState = useCallback((sites: string) => { + const updateAllowListState = useCallback((allowList: string[]) => { setState((oldState) => ({ ...oldState, - allowList: sites.trim().split('\n'), + allowList, + })); + }, []); + + const updateCustomProjectNamesState = useCallback((customProjectNames: ProjectName[]) => { + setState((oldState) => ({ + ...oldState, + customProjectNames, })); }, []); @@ -124,7 +136,7 @@ export default function Options(): JSX.Element { ); @@ -133,9 +145,9 @@ export default function Options(): JSX.Element { ); }, [ @@ -230,6 +242,13 @@ export default function Options(): JSX.Element { + +
{ - setState({ - ...state, - socialMediaSites: sites.split('\n'), - }); + handleChange={(socialMediaSites) => { + setState((oldState) => ({ + ...oldState, + socialMediaSites, + })); }} label="Social" - sites={state.socialMediaSites.join('\n')} + sites={state.socialMediaSites} helpText="Sites that you don't want to show in your reports." - rows={5} />
diff --git a/src/components/SitesList.tsx b/src/components/SitesList.tsx index 86023ca..2f6ce29 100644 --- a/src/components/SitesList.tsx +++ b/src/components/SitesList.tsx @@ -1,47 +1,74 @@ -import React from 'react'; +import React, { useCallback } from 'react'; type Props = { - handleChange: (sites: string) => void; + handleChange: (sites: string[]) => void; helpText: string; label: string; - placeholder?: string; - rows?: number; - sites: string; + projectNamePlaceholder?: string; + sites: string[]; + urlPlaceholder?: string; }; export default function SitesList({ handleChange, label, - placeholder, - rows, + urlPlaceholder, sites, helpText, }: Props): JSX.Element { - const textareaChange = (event: React.ChangeEvent) => { - handleChange(event.target.value); - }; + const handleAddNewSite = useCallback(() => { + handleChange([...sites, '']); + }, [handleChange, sites]); + + const handleUrlChangeForSite = useCallback( + (event: React.ChangeEvent, index: number) => { + handleChange(sites.map((item, i) => (i === index ? event.target.value : item))); + }, + [handleChange, sites], + ); + + const handleRemoveSite = useCallback( + (index: number) => { + handleChange(sites.filter((_, i) => i !== index)); + }, + [handleChange, sites], + ); return ( -
-