mirror of
https://github.com/kremalicious/umami.git
synced 2025-02-05 17:05:46 +01:00
add active website tracking with pin icon
This commit is contained in:
parent
1225473c20
commit
65c4627900
@ -7,6 +7,19 @@
|
||||
|
||||
.item {
|
||||
padding: 5px 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pinActive {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.pin {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.item h1 {
|
||||
@ -26,6 +39,10 @@
|
||||
background: var(--base50);
|
||||
}
|
||||
|
||||
.websiteActive .text {
|
||||
border: 1px solid var(--base800);
|
||||
}
|
||||
|
||||
.active .text {
|
||||
border-color: var(--base600);
|
||||
box-shadow: 4px 4px 4px var(--base100);
|
||||
|
@ -2,6 +2,7 @@ import { useState, useMemo } from 'react';
|
||||
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
|
||||
import classNames from 'classnames';
|
||||
import { Button, Loading } from 'react-basics';
|
||||
import Icons from 'components/icons';
|
||||
import { firstBy } from 'thenby';
|
||||
import useDashboard, { saveDashboard } from 'store/dashboard';
|
||||
import { useMessages, useWebsites } from 'components/hooks';
|
||||
@ -11,9 +12,10 @@ const DRAG_ID = 'dashboard-website-ordering';
|
||||
|
||||
export function DashboardEdit({ teamId }: { teamId: string }) {
|
||||
const settings = useDashboard();
|
||||
const { websiteOrder } = settings;
|
||||
const { websiteOrder, websiteActive } = settings;
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const [order, setOrder] = useState(websiteOrder || []);
|
||||
const [active, setActive] = useState(websiteActive || []);
|
||||
const {
|
||||
result,
|
||||
query: { isLoading },
|
||||
@ -40,19 +42,27 @@ export function DashboardEdit({ teamId }: { teamId: string }) {
|
||||
setOrder(orderedWebsites.map(website => website?.id || 0));
|
||||
}
|
||||
|
||||
function handleActiveWebsites(id: string) {
|
||||
setActive(prevActive =>
|
||||
prevActive.includes(id) ? prevActive.filter(a => a !== id) : [...prevActive, id],
|
||||
);
|
||||
}
|
||||
|
||||
function handleSave() {
|
||||
saveDashboard({
|
||||
editing: false,
|
||||
websiteOrder: order,
|
||||
websiteActive: active,
|
||||
});
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
saveDashboard({ editing: false, websiteOrder });
|
||||
saveDashboard({ editing: false, websiteOrder, websiteActive });
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
setOrder([]);
|
||||
setActive([]);
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
@ -88,11 +98,16 @@ export function DashboardEdit({ teamId }: { teamId: string }) {
|
||||
ref={provided.innerRef}
|
||||
className={classNames(styles.item, {
|
||||
[styles.active]: snapshot.isDragging,
|
||||
[styles.websiteActive]: active.includes(id),
|
||||
})}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
onClick={() => handleActiveWebsites(id)}
|
||||
>
|
||||
<div className={styles.text}>
|
||||
<div className={styles.pinActive}>
|
||||
{active.includes(id) ? <Icons.PushPin className={styles.pin} /> : null}
|
||||
</div>
|
||||
<h1>{name}</h1>
|
||||
<h2>{domain}</h2>
|
||||
</div>
|
||||
|
@ -18,17 +18,16 @@ export default function WebsiteChartList({
|
||||
limit?: number;
|
||||
}) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { websiteOrder } = useDashboard();
|
||||
const { websiteOrder, websiteActive } = useDashboard();
|
||||
const { renderTeamUrl } = useTeamUrl();
|
||||
const { dir } = useLocale();
|
||||
|
||||
const ordered = useMemo(
|
||||
() =>
|
||||
websites
|
||||
.map(website => ({ ...website, order: websiteOrder.indexOf(website.id) || 0 }))
|
||||
.sort(firstBy('order')),
|
||||
[websites, websiteOrder],
|
||||
);
|
||||
const ordered = useMemo(() => {
|
||||
return websites
|
||||
.filter(website => (websiteActive.length ? websiteActive.includes(website.id) : true))
|
||||
.map(website => ({ ...website, order: websiteOrder.indexOf(website.id) || 0 }))
|
||||
.sort(firstBy('order'));
|
||||
}, [websites, websiteOrder, websiteActive]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
8
src/assets/pushpin.svg
Normal file
8
src/assets/pushpin.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<svg
|
||||
viewBox="0 0 1024 1024"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
width="1em"
|
||||
>
|
||||
<path d="M878.3 392.1L631.9 145.7c-6.5-6.5-15-9.7-23.5-9.7s-17 3.2-23.5 9.7L423.8 306.9c-12.2-1.4-24.5-2-36.8-2-73.2 0-146.4 24.1-206.5 72.3-15.4 12.3-16.6 35.4-2.7 49.4l181.7 181.7-215.4 215.2a15.8 15.8 0 00-4.6 9.8l-3.4 37.2c-.9 9.4 6.6 17.4 15.9 17.4.5 0 1 0 1.5-.1l37.2-3.4c3.7-.3 7.2-2 9.8-4.6l215.4-215.4 181.7 181.7c6.5 6.5 15 9.7 23.5 9.7 9.7 0 19.3-4.2 25.9-12.4 56.3-70.3 79.7-158.3 70.2-243.4l161.1-161.1c12.9-12.8 12.9-33.8 0-46.8z" />
|
||||
</svg>
|
After Width: | Height: | Size: 571 B |
@ -19,6 +19,7 @@ import Moon from 'assets/moon.svg';
|
||||
import Nodes from 'assets/nodes.svg';
|
||||
import Overview from 'assets/overview.svg';
|
||||
import Profile from 'assets/profile.svg';
|
||||
import PushPin from 'assets/pushpin.svg';
|
||||
import Reports from 'assets/reports.svg';
|
||||
import Sun from 'assets/sun.svg';
|
||||
import User from 'assets/user.svg';
|
||||
@ -47,6 +48,7 @@ const icons = {
|
||||
Nodes,
|
||||
Overview,
|
||||
Profile,
|
||||
PushPin,
|
||||
Reports,
|
||||
Sun,
|
||||
User,
|
||||
|
@ -6,6 +6,7 @@ export const initialState = {
|
||||
showCharts: true,
|
||||
limit: DEFAULT_WEBSITE_LIMIT,
|
||||
websiteOrder: [],
|
||||
websiteActive: [],
|
||||
editing: false,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user