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

Channels UI polish #4820

Merged
merged 3 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions assets/js/dashboard/hooks/use-previous.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useRef, useEffect } from 'react';

function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T | undefined>(undefined);

useEffect(() => {
// Update the ref with the current value after render
ref.current = value;
}, [value]);

// Return the previous value
return ref.current;
}

export default usePrevious;
2 changes: 1 addition & 1 deletion assets/js/dashboard/stats/locations/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,4 @@ function LocationsWithContext() {
const site = useSiteContext();
return <Locations site={site} query={query} />
}
export default LocationsWithContext
export default LocationsWithContext
53 changes: 41 additions & 12 deletions assets/js/dashboard/stats/sources/source-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
import * as storage from '../../util/storage';
import * as url from '../../util/url';
import * as api from '../../api';
import usePrevious from '../../hooks/use-previous';
import ListReport from '../reports/list';
import * as metrics from '../reports/metrics';
import { hasGoalFilter } from "../../util/filters";
import { getFiltersByKeyPrefix, hasGoalFilter } from "../../util/filters";
import { Menu, Transition } from '@headlessui/react';
import { ChevronDownIcon } from '@heroicons/react/20/solid';
import classNames from 'classnames';
Expand All @@ -15,11 +16,11 @@
import { sourcesRoute, channelsRoute, utmCampaignsRoute, utmContentsRoute, utmMediumsRoute, utmSourcesRoute, utmTermsRoute } from '../../router';

const UTM_TAGS = {
utm_medium: { label: 'UTM Medium', shortLabel: 'UTM Medium', endpoint: '/utm_mediums' },
utm_source: { label: 'UTM Source', shortLabel: 'UTM Source', endpoint: '/utm_sources' },
utm_campaign: { label: 'UTM Campaign', shortLabel: 'UTM Campai', endpoint: '/utm_campaigns' },
utm_content: { label: 'UTM Content', shortLabel: 'UTM Conten', endpoint: '/utm_contents' },
utm_term: { label: 'UTM Term', shortLabel: 'UTM Term', endpoint: '/utm_terms' },
utm_medium: { title: 'UTM Mediums', label: 'Medium', endpoint: '/utm_mediums' },
utm_source: { title: 'UTM Sources', label: 'Source', endpoint: '/utm_sources' },
utm_campaign: { title: 'UTM Campaigns', label: 'Campaign', endpoint: '/utm_campaigns' },
utm_content: { title: 'UTM Contents', label: 'Content', endpoint: '/utm_contents' },
utm_term: { title: 'UTM Terms', label: 'Term', endpoint: '/utm_terms' },
}

function AllSources({ afterFetchData }) {
Expand Down Expand Up @@ -67,7 +68,7 @@
)
}

function Channels({ afterFetchData }) {
function Channels({ onClick, afterFetchData }) {
const { query } = useQueryContext();
const site = useSiteContext();

Expand Down Expand Up @@ -95,6 +96,7 @@
afterFetchData={afterFetchData}
getFilterFor={getFilterFor}
keyLabel="Channel"
onClick={onClick}
metrics={chooseMetrics()}
detailsLinkProps={{ path: channelsRoute.path, search: (search) => search }}
color="bg-blue-50"
Expand Down Expand Up @@ -146,6 +148,15 @@
)
}

const labelFor = {
'channels': 'Top Channels',
'all': 'Top Sources'
}

for (const [key, utm_tag] of Object.entries(UTM_TAGS)) {
labelFor[key] = utm_tag.title
}

export default function SourceList() {
const site = useSiteContext();
const { query } = useQueryContext();
Expand All @@ -154,9 +165,23 @@
const [currentTab, setCurrentTab] = useState(storedTab || 'all')
const [loading, setLoading] = useState(true)
const [skipImportedReason, setSkipImportedReason] = useState(null)
const previousQuery = usePrevious(query);
ukutaht marked this conversation as resolved.
Show resolved Hide resolved

useEffect(() => setLoading(true), [query, currentTab])

useEffect(() => {
const isRemovingFilter = (filterName) => {
if (!previousQuery) return false

return getFiltersByKeyPrefix(previousQuery, filterName).length > 0 &&
getFiltersByKeyPrefix(query, filterName).length == 0
}

if (currentTab == 'all' && isRemovingFilter('channel')) {
setTab('channels')()
}
}, [query, currentTab])

Check warning on line 183 in assets/js/dashboard/stats/sources/source-list.js

View workflow job for this annotation

GitHub Actions / Build and test

React Hook useEffect has missing dependencies: 'previousQuery' and 'setTab'. Either include them or remove the dependency array

function setTab(tab) {
return () => {
storage.setItem(tabKey, tab)
Expand All @@ -168,14 +193,14 @@
const activeClass = 'inline-block h-5 text-indigo-700 dark:text-indigo-500 font-bold active-prop-heading truncate text-left'
const defaultClass = 'hover:text-indigo-600 cursor-pointer truncate text-left'
const dropdownOptions = Object.keys(UTM_TAGS)
let buttonText = UTM_TAGS[currentTab] ? UTM_TAGS[currentTab].label : 'Campaigns'
let buttonText = UTM_TAGS[currentTab] ? UTM_TAGS[currentTab].title : 'Campaigns'

return (
<div className="flex text-xs font-medium text-gray-500 dark:text-gray-400 space-x-2">
<div className={currentTab === 'all' ? activeClass : defaultClass} onClick={setTab('all')}>All</div>
{site.flags.channels &&
<div className={currentTab === 'channels' ? activeClass : defaultClass} onClick={setTab('channels')}>Channels</div>
}
<div className={currentTab === 'all' ? activeClass : defaultClass} onClick={setTab('all')}>Sources</div>

<Menu as="div" className="relative inline-block text-left">
<div>
Expand Down Expand Up @@ -208,7 +233,7 @@
currentTab === option ? 'font-bold' : ''
)}
>
{UTM_TAGS[option].label}
{UTM_TAGS[option].title}
</span>
)}
</Menu.Item>
Expand All @@ -222,11 +247,15 @@
)
}

function onChannelClick() {
setTab('all')()
}

function renderContent() {
if (currentTab === 'all') {
return <AllSources afterFetchData={afterFetchData} />
} else if (currentTab == 'channels') {
return <Channels afterFetchData={afterFetchData} />
return <Channels onClick={onChannelClick} afterFetchData={afterFetchData} />
} else {
return <UTMSources tab={currentTab} afterFetchData={afterFetchData} />
}
Expand All @@ -243,7 +272,7 @@
<div className="w-full flex justify-between">
<div className="flex gap-x-1">
<h3 className="font-bold dark:text-gray-100">
Top Sources
{labelFor[currentTab]}
</h3>
<ImportedQueryUnsupportedWarning loading={loading} skipImportedReason={skipImportedReason} />
</div>
Expand Down