mirror of
https://github.com/plausible/analytics.git
synced 2024-11-26 23:27:54 +03:00
Adds site switching keybindings (#735)
* Changes 30d and 6mo keybinds, adds site switch keybinds * Fixes datepicker helpers * Changelog
This commit is contained in:
parent
e58ab08b7b
commit
524b4c52f6
@ -5,7 +5,8 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
### Added
|
||||
- Stats API [currently in beta] plausible/analytics#679
|
||||
- 30 day and 6 month keybindings (`3` and `6`, respectively) plausible/analytics#709
|
||||
- 30 day and 6 month keybindings (`T` and `S`, respectively) plausible/analytics#709
|
||||
- Site switching keybinds (1-9 for respective sites) plausible/analytics#735
|
||||
|
||||
### Fixed
|
||||
- Capitalized date/time selection keybinds not working plausible/analytics#709
|
||||
|
@ -100,7 +100,7 @@ class DatePicker extends React.Component {
|
||||
|
||||
this.setState({open: false});
|
||||
|
||||
const keys = ['d', 'r', 'w', 'm', 'y', '3', '6'];
|
||||
const keys = ['d', 'r', 'w', 'm', 'y', 't', 's'];
|
||||
const redirects = [{date: false, period: 'day'}, {period: 'realtime'}, {date: false, period: '7d'}, {date: false, period: 'month'}, {date: false, period: '12mo'}, {date: false, period: '30d'}, {date: false, period: '6mo'}];
|
||||
|
||||
if (keys.includes(e.key.toLowerCase())) {
|
||||
@ -302,8 +302,8 @@ class DatePicker extends React.Component {
|
||||
'Last 7 days': 'W',
|
||||
'Month to Date': 'M',
|
||||
'Last 12 months': 'Y',
|
||||
'Last 6 months': '6',
|
||||
'Last 30 days': '3',
|
||||
'Last 6 months': 'S',
|
||||
'Last 30 days': 'T',
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -5,6 +5,8 @@ export default class SiteSwitcher extends React.Component {
|
||||
constructor() {
|
||||
super()
|
||||
this.handleClick = this.handleClick.bind(this)
|
||||
this.handleKeydown = this.handleKeydown.bind(this);
|
||||
this.populateSites = this.populateSites.bind(this);
|
||||
this.state = {
|
||||
open: false,
|
||||
sites: null,
|
||||
@ -14,13 +16,26 @@ export default class SiteSwitcher extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.populateSites();
|
||||
document.addEventListener("keydown", this.handleKeydown);
|
||||
document.addEventListener('mousedown', this.handleClick, false);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener("keydown", this.handleKeydown);
|
||||
document.removeEventListener('mousedown', this.handleClick, false);
|
||||
}
|
||||
|
||||
populateSites() {
|
||||
fetch('/api/sites')
|
||||
.then( response => {
|
||||
if (!response.ok) { throw response }
|
||||
return response.json()
|
||||
})
|
||||
.then((sites) => this.setState({loading: false, sites: sites}))
|
||||
.catch((e) => this.setState({loading: false, error: e}))
|
||||
}
|
||||
|
||||
handleClick(e) {
|
||||
if (this.dropDownNode && this.dropDownNode.contains(e.target)) return;
|
||||
if (!this.state.open) return;
|
||||
@ -28,28 +43,39 @@ export default class SiteSwitcher extends React.Component {
|
||||
this.setState({open: false})
|
||||
}
|
||||
|
||||
handleKeydown(e) {
|
||||
const { query, history, site } = this.props;
|
||||
const { sites } = this.state;
|
||||
|
||||
if (e.ctrlKey || e.metaKey || e.altKey || e.isComposing || e.keyCode === 229 || !sites) return
|
||||
|
||||
const siteNum = parseInt(e.key)
|
||||
|
||||
if (1 <= siteNum <= 9 && siteNum <= sites.length && sites[siteNum-1] !== site.domain) {
|
||||
window.location = `/${encodeURIComponent(sites[siteNum-1])}`
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
toggle() {
|
||||
if (!this.props.loggedIn) return;
|
||||
|
||||
this.setState({open: !this.state.open})
|
||||
|
||||
if (!this.state.sites) {
|
||||
fetch('/api/sites')
|
||||
.then( response => {
|
||||
if (!response.ok) { throw response }
|
||||
return response.json()
|
||||
})
|
||||
.then((sites) => this.setState({loading: false, sites: sites}))
|
||||
.catch((e) => this.setState({loading: false, error: e}))
|
||||
this.populateSites();
|
||||
}
|
||||
}
|
||||
|
||||
renderSiteLink(domain) {
|
||||
renderSiteLink(domain, index) {
|
||||
const extraClass = domain === this.props.site.domain ? 'font-medium text-gray-900 dark:text-gray-100 cursor-default font-bold' : 'hover:bg-gray-100 dark:hover:bg-gray-900 hover:text-gray-900 dark:hover:text-gray-100 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-900 focus:text-gray-900 dark:focus:text-gray-100'
|
||||
return (
|
||||
<a href={domain === this.props.site.domain ? null : `/${encodeURIComponent(domain)}`} key={domain} className={`block truncate px-4 py-2 md:text-sm leading-5 text-gray-700 dark:text-gray-300 ${extraClass}`}>
|
||||
<img src={`https://icons.duckduckgo.com/ip3/${domain}.ico`} referrerPolicy="no-referrer" className="inline w-4 mr-2 align-middle" />
|
||||
<span>{domain}</span>
|
||||
<a href={domain === this.props.site.domain ? null : `/${encodeURIComponent(domain)}`} key={domain} className={`flex items-center justify-between truncate px-4 py-2 md:text-sm leading-5 text-gray-700 dark:text-gray-300 ${extraClass}`}>
|
||||
<span>
|
||||
<img src={`https://icons.duckduckgo.com/ip3/${domain}.ico`} referrerPolicy="no-referrer" className="inline w-4 mr-2 align-middle" />
|
||||
<span>{domain}</span>
|
||||
</span>
|
||||
{index < 9 && <span>{index+1}</span>}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
@ -75,7 +101,7 @@ export default class SiteSwitcher extends React.Component {
|
||||
<div className="border-t border-gray-200 dark:border-gray-500"></div>
|
||||
<div className="py-1">
|
||||
<a href='/sites/new' className="group flex items-center px-4 py-2 md:text-sm leading-5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-900 hover:text-gray-900 dark:hover:text-gray-100 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-900 focus:text-gray-900 dark:focus:text-gray-100" role="menuitem">
|
||||
<svg className="mr-2 h-4 w-4 text-gray-500 dark:text-gray-200 group-hover:text-gray-600 dark:group-hover:text-gray-400 group-focus:text-gray-500 dark:group-focus:text-gray-200" fill="none" stroke="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path></svg>
|
||||
<svg className="mr-2 h-4 w-4 text-gray-500 dark:text-gray-200 group-hover:text-gray-600 dark:group-hover:text-gray-400 group-focus:text-gray-500 dark:group-focus:text-gray-200" fill="none" stroke="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path></svg>
|
||||
Add Site
|
||||
</a>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user