diff --git a/components/pages/WebsiteList.js b/components/pages/WebsiteList.js index 9e3c641a..07cc4107 100644 --- a/components/pages/WebsiteList.js +++ b/components/pages/WebsiteList.js @@ -1,3 +1,4 @@ +import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'; import { FormattedMessage } from 'react-intl'; import Link from 'components/common/Link'; import WebsiteChart from 'components/metrics/WebsiteChart'; @@ -7,19 +8,36 @@ import Arrow from 'assets/arrow-right.svg'; import styles from './WebsiteList.module.css'; import { orderByWebsiteMap } from 'lib/format'; import { useMemo } from 'react'; -import useStore from 'store/app'; +import useStore, { setDashboard } from 'store/app'; const selector = state => state.dashboard; export default function WebsiteList({ websites, showCharts, limit }) { const store = useStore(selector); - const { websiteOrdering } = store; + const { websiteOrdering, changeOrderMode } = store; const ordered = useMemo( () => orderByWebsiteMap(websites, websiteOrdering), [websites, websiteOrdering], ); + const dragId = 'dashboard-website-ordering'; + + function handleWebsiteDrag({ destination, source }) { + if (!destination || destination.index === source.index) return; + + const orderedWebsites = [...ordered]; + const [removed] = orderedWebsites.splice(source.index, 1); + orderedWebsites.splice(destination.index, 0, removed); + + setDashboard({ + ...store, + websiteOrdering: orderedWebsites + .map((i, k) => ({ [i.website_uuid]: k })) + .reduce((a, b) => ({ ...a, ...b })), + }); + } + if (websites.length === 0) { return ( @@ -40,19 +58,57 @@ export default function WebsiteList({ websites, showCharts, limit }) { } return ( -
- {ordered.map(({ website_id, name, domain }, index) => - index < limit ? ( -
- -
- ) : null, +
+ {changeOrderMode ? ( + + + {provided => ( +
+ {ordered.map(({ website_id, name, domain }, index) => + index < limit ? ( +
+ + {provided => ( +
+ +
+ )} +
+
+ ) : null, + )} +
+ )} +
+
+ ) : ( + ordered.map(({ website_id, name, domain }, index) => + index < limit ? ( +
+ +
+ ) : null, + ) )}
); diff --git a/components/pages/WebsiteList.module.css b/components/pages/WebsiteList.module.css index fc6a94c2..9b5e6968 100644 --- a/components/pages/WebsiteList.module.css +++ b/components/pages/WebsiteList.module.css @@ -9,3 +9,12 @@ border-bottom: 0; margin-bottom: 20px; } + +.websiteDragActive { + opacity: 0.6; + cursor: grab; +} + +.websiteDragActive:active { + cursor: grabbing; +} diff --git a/components/settings/DashboardSettingsButton.js b/components/settings/DashboardSettingsButton.js index 8bdaf311..1c4b98c7 100644 --- a/components/settings/DashboardSettingsButton.js +++ b/components/settings/DashboardSettingsButton.js @@ -3,6 +3,9 @@ import { FormattedMessage } from 'react-intl'; import MenuButton from 'components/common/MenuButton'; import Gear from 'assets/gear.svg'; import useStore, { setDashboard } from 'store/app'; +import Button from 'components/common/Button'; +import Check from 'assets/check.svg'; +import styles from './DashboardSettingsButton.module.css'; const selector = state => state.dashboard; @@ -14,14 +17,41 @@ export default function DashboardSettingsButton() { label: , value: 'charts', }, + { + label: , + value: 'order', + }, ]; function handleSelect(value) { if (value === 'charts') { setDashboard({ ...settings, showCharts: !settings.showCharts }); } + if (value === 'order') { + setDashboard({ ...settings, changeOrderMode: !settings.changeOrderMode }); + } //setDashboard(value); } + function handleExitChangeOrderMode() { + setDashboard({ ...settings, changeOrderMode: !settings.changeOrderMode }); + } + + function resetWebsiteOrder() { + setDashboard({ ...settings, websiteOrdering: {} }); + } + + if (settings.changeOrderMode) + return ( +
+ + +
+ ); + return } options={menuOptions} onSelect={handleSelect} hideLabel />; } diff --git a/components/settings/DashboardSettingsButton.module.css b/components/settings/DashboardSettingsButton.module.css new file mode 100644 index 00000000..6e0d19c2 --- /dev/null +++ b/components/settings/DashboardSettingsButton.module.css @@ -0,0 +1,5 @@ +.buttonGroup { + display: flex; + place-items: center; + gap: 10px; +} diff --git a/lang/en-US.json b/lang/en-US.json index 69a68980..0687e553 100644 --- a/lang/en-US.json +++ b/lang/en-US.json @@ -10,6 +10,7 @@ "label.back": "Back", "label.cancel": "Cancel", "label.change-password": "Change password", + "label.change-order": "Change order", "label.confirm-password": "Confirm password", "label.copy-to-clipboard": "Copy to clipboard", "label.current-password": "Current password", @@ -22,6 +23,7 @@ "label.delete-website": "Delete website", "label.dismiss": "Dismiss", "label.domain": "Domain", + "label.done": "Done", "label.edit": "Edit", "label.edit-account": "Edit account", "label.edit-website": "Edit website", diff --git a/store/app.js b/store/app.js index 0b2abd47..fd84b975 100644 --- a/store/app.js +++ b/store/app.js @@ -13,6 +13,7 @@ export const defaultDashboardConfig = { showCharts: true, limit: DEFAULT_WEBSITE_LIMIT, websiteOrdering: {}, + changeOrderMode: false, }; const initialState = {