Skip to content

WIP (DO NOT MERGE): A4A Report builder prototype #103613

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

Draft
wants to merge 75 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
9bac961
Init menu item
madebynoam May 8, 2025
762e8ca
Move menu item down
madebynoam May 8, 2025
cb6f09a
Enable the page
madebynoam May 8, 2025
07dfe45
Quick layout fix
madebynoam May 8, 2025
4ae52c0
Add modal button
madebynoam May 8, 2025
b6b61fd
Modal size large
madebynoam May 8, 2025
c9d8297
Modal mock fields
madebynoam May 8, 2025
d143cef
Change title
madebynoam May 8, 2025
fb7b947
Wizard first pass
madebynoam May 8, 2025
af62c01
Add styling
madebynoam May 8, 2025
4e75c7a
Style modal footer
madebynoam May 8, 2025
b635fa2
Add checkbox for send monthly
madebynoam May 8, 2025
ae6f908
Add pick site dropdown
madebynoam May 16, 2025
c677b06
Remove logo field
madebynoam May 16, 2025
9cda4ea
Add Overview page
madebynoam May 21, 2025
fd406fb
Merge branch 'trunk' into report-builder-prototype
madebynoam May 21, 2025
c58738b
Clean up old stuff
madebynoam May 21, 2025
1cdb545
Update index.tsx
madebynoam May 21, 2025
5618611
Fix style
madebynoam May 21, 2025
7e2f1db
Update hero
madebynoam May 21, 2025
5e959e5
Copy update
madebynoam May 21, 2025
f2f16c7
Copy and image
madebynoam May 21, 2025
8aa411b
Add beta badge
madebynoam May 21, 2025
8f43a05
Size down the modal
madebynoam May 21, 2025
9dcf317
Update copy and image
madebynoam May 21, 2025
40e542e
Refactor styles, scroll to teammate email field
madebynoam May 21, 2025
b521616
Copy update
madebynoam May 21, 2025
bf1a02d
Refine copy and spacing
madebynoam May 22, 2025
838a0c2
Merge branch 'trunk' into report-builder-prototype
madebynoam May 22, 2025
6891d2e
Refactor asset names
madebynoam May 22, 2025
348dde4
Copy fix
madebynoam May 22, 2025
ae8a9b3
Adjust spacing and default as selected
madebynoam May 22, 2025
aef8d92
Merge branch 'trunk' into report-builder-prototype
madebynoam May 22, 2025
892d491
Update 3rd image and copy
madebynoam May 23, 2025
de6ab25
Merge branch 'trunk' into report-builder-prototype
madebynoam May 23, 2025
796544c
Merge branch 'trunk' into report-builder-prototype-i2
madebynoam May 26, 2025
17c8e00
Move form to page
madebynoam May 26, 2025
3b7c73e
Form styling
madebynoam May 26, 2025
d7571ce
Form styles
madebynoam May 26, 2025
82b2238
Fix help styling
madebynoam May 26, 2025
7f75522
Add site modal and image and copy updates
madebynoam May 27, 2025
d30f95f
Image update
madebynoam May 27, 2025
d1474d9
Style updates
madebynoam May 27, 2025
64ffb30
Update images
madebynoam May 27, 2025
05a1b72
Update report-mock-3.png
madebynoam May 27, 2025
de763ab
Sample report progress
madebynoam May 27, 2025
9ea61f9
Example details
madebynoam May 27, 2025
ced84cd
Spacing details
madebynoam May 27, 2025
f82163f
Dashboard
madebynoam May 27, 2025
8f54f95
Label update
madebynoam May 27, 2025
32cf53e
More example reports
madebynoam May 27, 2025
2bd70cb
Merge branch 'trunk' into report-builder-prototype-i2
madebynoam May 27, 2025
adcc719
Merge branch 'trunk' into report-builder-prototype
madebynoam May 27, 2025
908c6ff
Merge branch 'report-builder-prototype-i2' into report-builder-prototype
madebynoam May 27, 2025
3f8e1dd
Revert wrong formatting
madebynoam May 28, 2025
4f94448
Remove unused field
madebynoam May 29, 2025
60d1210
Merge branch 'trunk' into report-builder-prototype
madebynoam May 30, 2025
bfba293
Modal
madebynoam Jun 2, 2025
b242840
Full screem modal
madebynoam Jun 2, 2025
be26b2a
Refactor blue
madebynoam Jun 2, 2025
3223703
Merge branch 'trunk' into report-builder-prototype
madebynoam Jun 2, 2025
ff97d38
Add report footer, remove unused sections
madebynoam Jun 2, 2025
5a21bc0
Full width reports dash
madebynoam Jun 2, 2025
99066ae
add details button
madebynoam Jun 2, 2025
5387877
Remove unused dep
madebynoam Jun 2, 2025
989bee8
Remove columns
madebynoam Jun 2, 2025
5359cd0
Update help text
madebynoam Jun 2, 2025
a9d1237
Name change
madebynoam Jun 2, 2025
9707ebf
Swap button locations
madebynoam Jun 2, 2025
cbdc684
Responsiveness
madebynoam Jun 2, 2025
38b701e
Merge branch 'trunk' into report-builder-prototype
madebynoam Jun 2, 2025
ce93a2c
Email(s)
madebynoam Jun 2, 2025
144a481
Styling
madebynoam Jun 2, 2025
48480d5
Merge branch 'trunk' into report-builder-prototype
madebynoam Jun 2, 2025
1935a1e
Label style fix
madebynoam Jun 2, 2025
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
60 changes: 60 additions & 0 deletions client/a8c-for-agencies/components/select-site-button/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Button } from '@wordpress/components';
import { useTranslate } from 'i18n-calypso';
import { useCallback, useState } from 'react';
import { useDispatch } from 'calypso/state';
import { recordTracksEvent } from 'calypso/state/analytics/actions';
import SelectSiteModal from './modal';
import type { ReactNode } from 'react';

export type SelectSiteButtonProps = {
onSiteSelect: ( siteId: number, siteDomain: string ) => void;
buttonLabel?: string;
modalTitle?: string;
modalSubtitle?: string;
helpText?: ReactNode;
trackingEvent?: string;
className?: string;
};

const SelectSiteButton = ( {
onSiteSelect,
buttonLabel,
modalTitle,
modalSubtitle,
helpText,
trackingEvent = 'calypso_select_site_button_click',
className,
}: SelectSiteButtonProps ) => {
const translate = useTranslate();
const dispatch = useDispatch();
const [ isOpen, setIsOpen ] = useState( false );

const handleOpenModal = useCallback( () => {
setIsOpen( true );
dispatch( recordTracksEvent( trackingEvent ) );
}, [ dispatch, trackingEvent ] );

return (
<>
<Button
__next40pxDefaultSize
variant="secondary"
onClick={ handleOpenModal }
className={ className }
>
{ buttonLabel || translate( 'Select a site' ) }
</Button>

{ isOpen && (
<SelectSiteModal
onClose={ () => setIsOpen( false ) }
onSiteSelect={ onSiteSelect }
title={ modalTitle }
subtitle={ helpText || modalSubtitle }
/>
) }
</>
);
};

export default SelectSiteButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import './style.scss';

export { default } from './button';
export type { SelectSiteButtonProps } from './button';
66 changes: 66 additions & 0 deletions client/a8c-for-agencies/components/select-site-button/modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Button } from '@wordpress/components';
import { useTranslate } from 'i18n-calypso';
import { useState } from 'react';
import A4AModal from 'calypso/a8c-for-agencies/components/a4a-modal';
import { A4A_SITES_LINK } from 'calypso/a8c-for-agencies/components/sidebar-menu/lib/constants';
import { useDispatch } from 'calypso/state';
import { recordTracksEvent } from 'calypso/state/analytics/actions';
import SelectSiteTable, { type SiteItem } from './site-table';
import type { ReactNode } from 'react';

type SelectSiteModalProps = {
onClose: () => void;
onSiteSelect: ( siteId: number, siteDomain: string ) => void;
title?: string;
subtitle?: ReactNode;
};

const SelectSiteModal = ( { onClose, onSiteSelect, title, subtitle }: SelectSiteModalProps ) => {
const translate = useTranslate();
const dispatch = useDispatch();

const [ selectedSite, setSelectedSite ] = useState< SiteItem | null >( null );

const handleSelectSite = () => {
if ( selectedSite ) {
onSiteSelect( selectedSite.id, selectedSite.site );
onClose();
}
};

return (
<A4AModal
title={ title || translate( 'Select a site' ) }
subtile={
subtitle ||
translate(
"If you don't see the site in the list, connect it first via the {{a}}Sites Dashboard{{/a}}.",
{
components: {
a: (
<a
href={ A4A_SITES_LINK }
onClick={ () =>
dispatch(
recordTracksEvent( 'calypso_select_site_modal_sites_dashboard_click' )
)
}
/>
),
},
}
)
}
onClose={ onClose }
extraActions={
<Button variant="primary" onClick={ handleSelectSite } disabled={ ! selectedSite }>
{ translate( 'Select site' ) }
</Button>
}
>
<SelectSiteTable setSelectedSite={ setSelectedSite } selectedSite={ selectedSite } />
</A4AModal>
);
};

export default SelectSiteModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { filterSortAndPaginate } from '@wordpress/dataviews';
import { useTranslate } from 'i18n-calypso';
import { useCallback, useMemo, useState } from 'react';
import A4ATablePlaceholder from 'calypso/a8c-for-agencies/components/a4a-table-placeholder';
import { initialDataViewsState } from 'calypso/a8c-for-agencies/components/items-dashboard/constants';
import ItemsDataViews from 'calypso/a8c-for-agencies/components/items-dashboard/items-dataviews';
import { DataViewsState } from 'calypso/a8c-for-agencies/components/items-dashboard/items-dataviews/interfaces';
import {
useFetchAllManagedSites,
type SiteItem,
} from 'calypso/a8c-for-agencies/sections/migrations/hooks/use-fetch-all-managed-sites';
import FormRadio from 'calypso/components/forms/form-radio';
import { useDispatch } from 'calypso/state';
import { recordTracksEvent } from 'calypso/state/analytics/actions';

type SelectSiteTableProps = {
selectedSite: SiteItem | null;
setSelectedSite: ( site: SiteItem | null ) => void;
};

const SelectSiteTable = ( { selectedSite, setSelectedSite }: SelectSiteTableProps ) => {
const translate = useTranslate();
const dispatch = useDispatch();

const { items, isLoading } = useFetchAllManagedSites();

const [ dataViewsState, setDataViewsState ] = useState< DataViewsState >( {
...initialDataViewsState,
fields: [ 'site' ],
} );

const onSelectSite = useCallback(
( item: SiteItem ) => {
setSelectedSite( item );
dispatch( recordTracksEvent( 'calypso_select_site_table_select_site_click' ) );
},
[ dispatch, setSelectedSite ]
);

const fields = useMemo( () => {
const siteColumn = {
id: 'site',
label: translate( 'Site' ),
getValue: ( { item }: { item: SiteItem } ) => item.site,
render: ( { item }: { item: SiteItem } ) => (
<div>
<FormRadio
htmlFor={ `site-${ item.id }` }
id={ `site-${ item.id }` }
checked={ selectedSite?.id === item.id }
onChange={ () => onSelectSite( item ) }
label={ item.site }
/>
</div>
),
enableGlobalSearch: true,
enableHiding: false,
enableSorting: false,
};

return [ siteColumn ];
}, [ onSelectSite, selectedSite?.id, translate ] );

const { data: allSites, paginationInfo } = useMemo( () => {
return filterSortAndPaginate( items as SiteItem[], dataViewsState, fields );
}, [ items, dataViewsState, fields ] );

return (
<div className="redesigned-a8c-table show-overflow-overlay search-enabled">
{ isLoading ? (
<A4ATablePlaceholder />
) : (
<ItemsDataViews
data={ {
items: allSites,
fields,
getItemId: ( item ) => `${ item.id }`,
pagination: paginationInfo,
enableSearch: true,
actions: [],
dataViewsState: dataViewsState,
setDataViewsState: setDataViewsState,
defaultLayouts: { table: {} },
} }
/>
) }
</div>
);
};

export default SelectSiteTable;
11 changes: 11 additions & 0 deletions client/a8c-for-agencies/components/select-site-button/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.redesigned-a8c-table {
&.show-overflow-overlay {
overflow: visible;
}

&.search-enabled {
.dataviews-module__table-header {
padding-top: 16px;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
people,
starEmpty,
plugins,
chartBar,
} from '@wordpress/icons';
import { useTranslate } from 'i18n-calypso';
import { useMemo } from 'react';
Expand All @@ -36,16 +37,20 @@ import {
A4A_AGENCY_TIER_LINK,
A4A_MIGRATIONS_OVERVIEW_LINK,
A4A_WOOPAYMENTS_LINK,
A4A_REPORTS_LINK,
A4A_REPORTS_OVERVIEW_LINK,
A4A_REPORTS_DASHBOARD_LINK,
} from '../lib/constants';
import { createItem } from '../lib/utils';
import type { SidebarMenuItem } from '../lib/types';

const useMainMenuItems = ( path: string ) => {
const translate = useTranslate();

const agency = useSelector( getActiveAgency );

const menuItems = useMemo( () => {
let referralItems = [] as any[];
let referralItems = [] as SidebarMenuItem[];

if ( isSectionNameEnabled( 'a8c-for-agencies-referrals' ) ) {
referralItems = [
Expand Down Expand Up @@ -73,7 +78,22 @@ const useMainMenuItems = ( path: string ) => {
},
withChevron: true,
}
: {};
: ( {} as SidebarMenuItem );

const reportsSubMenuItems: SidebarMenuItem[] = [
{
icon: home,
link: A4A_REPORTS_OVERVIEW_LINK,
title: translate( 'Overview' ),
trackEventProps: { menu_item: 'Automattic for Agencies / Reports / Overview' },
},
{
icon: category,
link: A4A_REPORTS_DASHBOARD_LINK,
title: translate( 'Dashboard' ),
trackEventProps: { menu_item: 'Automattic for Agencies / Reports / Dashboard' },
},
];

return [
{
Expand Down Expand Up @@ -119,12 +139,13 @@ const useMainMenuItems = ( path: string ) => {
migrationMenuItem,
{
icon: <img src={ wooPaymentsIcon } alt="WooPayments" />,
path: '/',
path: A4A_WOOPAYMENTS_LINK,
link: A4A_WOOPAYMENTS_LINK,
title: translate( 'WooPayments' ),
trackEventProps: {
menu_item: 'Automattic for Agencies / WooPayments',
},
withChevron: true,
},
...( isSectionNameEnabled( 'a8c-for-agencies-plugins' )
? [
Expand All @@ -139,6 +160,22 @@ const useMainMenuItems = ( path: string ) => {
},
]
: [] ),
{
icon: chartBar,
path: A4A_REPORTS_LINK,
link: A4A_REPORTS_OVERVIEW_LINK,
title: (
<>
{ translate( 'Reports' ) }
<span className="sidebar-menu__beta-badge">{ translate( 'Beta' ) }</span>
</>
),
trackEventProps: {
menu_item: 'Automattic for Agencies / Reports',
},
withChevron: true,
subMenuItems: reportsSubMenuItems.map( ( item ) => createItem( item, path ) ),
},
...( config.isEnabled( 'a4a-partner-directory' ) ||
config.isEnabled( 'a8c-for-agencies-agency-tier' )
? [
Expand Down Expand Up @@ -194,7 +231,8 @@ const useMainMenuItems = ( path: string ) => {
: [] ),
]
.map( ( item ) => createItem( item, path ) )
.filter( ( item ) => isPathAllowed( item.link, agency ) );
.filter( ( item ) => isPathAllowed( item.link, agency ) )
.filter( Boolean ) as SidebarMenuItem[];
}, [ agency, path, translate ] );
return menuItems;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { category, home } from '@wordpress/icons';
import { useTranslate } from 'i18n-calypso';
import { useMemo } from 'react';
import {
A4A_REPORTS_LINK,
A4A_REPORTS_DASHBOARD_LINK,
A4A_REPORTS_OVERVIEW_LINK,
} from '../lib/constants';
import { createItem } from '../lib/utils';

const useReportsMenuItems = ( path: string ) => {
const translate = useTranslate();

const menuItems = useMemo( () => {
return [
createItem(
{
icon: home,
path: A4A_REPORTS_LINK,
link: A4A_REPORTS_OVERVIEW_LINK,
title: translate( 'Overview' ),
trackEventProps: {
menu_item: 'Automattic for Agencies / Reports / Overview',
},
},
path
),
createItem(
{
icon: category,
path: A4A_REPORTS_LINK,
link: A4A_REPORTS_DASHBOARD_LINK,
title: translate( 'Dashboard' ),
trackEventProps: {
menu_item: 'Automattic for Agencies / Reports / Dashboard',
},
},
path
),
]
.map( ( item ) => createItem( item, path ) )
.map( ( item ) => ( {
...item,
isSelected: item.link === path,
} ) );
}, [ path, translate ] );
return menuItems;
};

export default useReportsMenuItems;
Loading