From f5f6dc052e12cafa38d9db4c59c7d2fb10a94631 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Mon, 10 Apr 2023 09:44:25 -0700 Subject: [PATCH 1/6] fix column name date bug --- components/metrics/RealtimeChart.js | 2 +- lib/date.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/metrics/RealtimeChart.js b/components/metrics/RealtimeChart.js index 00bd0051..05da3cec 100644 --- a/components/metrics/RealtimeChart.js +++ b/components/metrics/RealtimeChart.js @@ -11,7 +11,7 @@ function mapData(data) { data?.reduce((obj, { timestamp }) => { const t = startOfMinute(new Date(timestamp)); if (t.getTime() > last) { - obj = { t: format(t, 'yyyy-LL-dd HH:mm:00'), y: 1 }; + obj = { x: format(t, 'yyyy-LL-dd HH:mm:00'), y: 1 }; arr.push(obj); last = t.getTime(); } else { diff --git a/lib/date.js b/lib/date.js index 13b19e36..6907786c 100644 --- a/lib/date.js +++ b/lib/date.js @@ -181,8 +181,8 @@ export function getDateArray(data, startDate, endDate, unit) { const n = diff(endDate, startDate) + 1; function findData(date) { - const d = data.find(({ x, t }) => { - return normalize(getDateFromString(x || t)).getTime() === date.getTime(); + const d = data.find(({ x }) => { + return normalize(getDateFromString(x)).getTime() === date.getTime(); }); return d?.y || 0; From 21e48c194e6dbd87b098d085e95f0ad36c1b25d0 Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Mon, 10 Apr 2023 09:56:25 -0700 Subject: [PATCH 2/6] fix system user insert mysql --- db/mysql/migrations/01_init/migration.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/mysql/migrations/01_init/migration.sql b/db/mysql/migrations/01_init/migration.sql index 6e310932..8687dd41 100644 --- a/db/mysql/migrations/01_init/migration.sql +++ b/db/mysql/migrations/01_init/migration.sql @@ -140,4 +140,4 @@ CREATE TABLE `team_website` ( ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- AddSystemUser -INSERT INTO "user" (user_id, username, role, password) VALUES ('41e2b680-648e-4b09-bcd7-3e2b10c06264' , 'admin', 'admin', '$2b$10$BUli0c.muyCW1ErNJc3jL.vFRFtFJWrT8/GcR4A.sUdCznaXiqFXa'); \ No newline at end of file +INSERT INTO user (user_id, username, role, password) VALUES ('41e2b680-648e-4b09-bcd7-3e2b10c06264' , 'admin', 'admin', '$2b$10$BUli0c.muyCW1ErNJc3jL.vFRFtFJWrT8/GcR4A.sUdCznaXiqFXa'); \ No newline at end of file From e2fcd40c2b9309df3564d36c8e5ca413ae412071 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Wed, 12 Apr 2023 13:40:19 -0700 Subject: [PATCH 3/6] Added SettingsTable. --- components/common/HamburgerButton.js | 14 ++ components/common/MobileMenu.js | 33 +++- components/common/MobileMenu.module.css | 10 + components/common/SettingsTable.js | 36 ++++ components/common/SettingsTable.module.css | 40 ++++ components/layout/NavBar.module.css | 4 + components/layout/PageHeader.js | 6 +- components/layout/PageHeader.module.css | 25 ++- components/layout/SettingsLayout.js | 8 +- components/layout/SettingsLayout.module.css | 6 +- components/layout/SideNav.module.css | 7 - components/pages/settings/teams/TeamsTable.js | 176 +++++++----------- components/pages/settings/users/UsersTable.js | 146 ++++++--------- .../pages/settings/websites/WebsitesTable.js | 96 +++------- .../websites/WebsitesTable.module.css | 13 ++ package.json | 4 +- pages/api/config.ts | 2 +- queries/admin/user.ts | 1 + yarn.lock | 8 +- 19 files changed, 335 insertions(+), 300 deletions(-) create mode 100644 components/common/SettingsTable.js create mode 100644 components/common/SettingsTable.module.css create mode 100644 components/pages/settings/websites/WebsitesTable.module.css diff --git a/components/common/HamburgerButton.js b/components/common/HamburgerButton.js index 77aaae75..9c92b282 100644 --- a/components/common/HamburgerButton.js +++ b/components/common/HamburgerButton.js @@ -19,6 +19,20 @@ export default function HamburgerButton() { !cloudMode && { label: formatMessage(labels.settings), value: '/settings', + children: [ + { + label: formatMessage(labels.websites), + value: '/settings/websites', + }, + { + label: formatMessage(labels.teams), + value: '/settings/teams', + }, + { + label: formatMessage(labels.users), + value: '/settings/users', + }, + ], }, { label: formatMessage(labels.profile), diff --git a/components/common/MobileMenu.js b/components/common/MobileMenu.js index aa737e7e..4168a6c6 100644 --- a/components/common/MobileMenu.js +++ b/components/common/MobileMenu.js @@ -1,17 +1,36 @@ import classNames from 'classnames'; +import { useRouter } from 'next/router'; import Link from 'next/link'; import styles from './MobileMenu.module.css'; export default function MobileMenu({ items = [], onClose }) { + const { pathname } = useRouter(); + + const Items = ({ items, className }) => ( +
+ {items.map(({ label, value, children }) => { + const selected = pathname === value; + + return ( + <> + + {label} + + {children && } + + ); + })} +
+ ); + return (
-
- {items.map(({ label, value }) => ( - - {label} - - ))} -
+
); } diff --git a/components/common/MobileMenu.module.css b/components/common/MobileMenu.module.css index aa9aafd0..cfe6cf37 100644 --- a/components/common/MobileMenu.module.css +++ b/components/common/MobileMenu.module.css @@ -25,5 +25,15 @@ } a.item { + color: var(--base600); +} + +a.item.selected, +.submenu a.item.selected { color: var(--base900); } + +.submenu a.item { + color: var(--base600); + margin-left: 40px; +} diff --git a/components/common/SettingsTable.js b/components/common/SettingsTable.js new file mode 100644 index 00000000..ac29d54e --- /dev/null +++ b/components/common/SettingsTable.js @@ -0,0 +1,36 @@ +import { Table, TableHeader, TableBody, TableRow, TableCell, TableColumn } from 'react-basics'; +import styles from './SettingsTable.module.css'; + +export default function SettingsTable({ columns = [], data = [], children, cellRender }) { + return ( + + + {(column, index) => { + return ( + + {column.label} + + ); + }} + + + {(row, keys, rowIndex) => { + row.action = children(row, keys, rowIndex); + + return ( + + {(data, key, colIndex) => { + return ( + + + {cellRender ? cellRender(row, data, key, colIndex) : data[key]} + + ); + }} + + ); + }} + +
+ ); +} diff --git a/components/common/SettingsTable.module.css b/components/common/SettingsTable.module.css new file mode 100644 index 00000000..023d1338 --- /dev/null +++ b/components/common/SettingsTable.module.css @@ -0,0 +1,40 @@ +.row .cell:last-child { + gap: 10px; + justify-content: flex-end; +} + +.label { + display: none; + font-weight: 700; +} + +@media screen and (max-width: 992px) { + .header .cell { + display: none; + } + + .label { + display: block; + min-width: 100px; + } + + .row .cell { + padding-left: 0; + flex-basis: 100%; + } +} + +@media screen and (max-width: 1200px) { + .row { + flex-wrap: wrap; + } + + .header .cell:last-child { + display: none; + } + + .row .cell:last-child { + padding-left: 0; + flex-basis: 100%; + } +} diff --git a/components/layout/NavBar.module.css b/components/layout/NavBar.module.css index 6c2faaaf..05dce2af 100644 --- a/components/layout/NavBar.module.css +++ b/components/layout/NavBar.module.css @@ -49,6 +49,10 @@ border-bottom: 2px solid transparent; } +.links span { + white-space: nowrap; +} + .links a:hover { color: var(--font-color100); border-bottom: 2px solid var(--primary400); diff --git a/components/layout/PageHeader.js b/components/layout/PageHeader.js index 0d014316..05c87f73 100644 --- a/components/layout/PageHeader.js +++ b/components/layout/PageHeader.js @@ -1,13 +1,9 @@ import React from 'react'; -import classNames from 'classnames'; -import { useBreakpoint } from 'react-basics'; import styles from './PageHeader.module.css'; export default function PageHeader({ title, children }) { - const breakPoint = useBreakpoint(); - return ( -
+
{title}
{children}
diff --git a/components/layout/PageHeader.module.css b/components/layout/PageHeader.module.css index d5481727..8a2a6800 100644 --- a/components/layout/PageHeader.module.css +++ b/components/layout/PageHeader.module.css @@ -16,6 +16,10 @@ color: var(--base900); } +.header > div { + line-height: 60px; +} + .title { display: flex; align-items: center; @@ -25,7 +29,22 @@ line-height: 50px; } -.xs .actions, -.sm .actions { - flex-basis: 100%; +.actions { + display: flex; + justify-content: flex-end; +} + +@media only screen and (max-width: 992px) { + .header { + margin-bottom: 10px; + } + + .title { + font-size: 18px; + } + + .actions { + flex-basis: 100%; + order: -1; + } } diff --git a/components/layout/SettingsLayout.js b/components/layout/SettingsLayout.js index 2b98aca5..ea0456e0 100644 --- a/components/layout/SettingsLayout.js +++ b/components/layout/SettingsLayout.js @@ -20,16 +20,16 @@ export default function SettingsLayout({ children }) { { key: 'profile', label: formatMessage(labels.profile), url: '/settings/profile' }, ].filter(n => n); - const getKey = () => items.find(({ url }) => pathname.startsWith(url))?.key; + const getKey = () => items.find(({ url }) => pathname === url)?.key; return ( - + {!cloudMode && ( - + )} - + {children} diff --git a/components/layout/SettingsLayout.module.css b/components/layout/SettingsLayout.module.css index 068681f5..569b903b 100644 --- a/components/layout/SettingsLayout.module.css +++ b/components/layout/SettingsLayout.module.css @@ -8,6 +8,8 @@ min-height: 50vh; } -.hideMenu .content { - margin: 0 auto; +@media only screen and (max-width: 768px) { + .menu { + display: none; + } } diff --git a/components/layout/SideNav.module.css b/components/layout/SideNav.module.css index 8b7d0d42..b664194d 100644 --- a/components/layout/SideNav.module.css +++ b/components/layout/SideNav.module.css @@ -13,10 +13,3 @@ padding: 0; border-radius: var(--border-radius); } - -@media only screen and (max-width: 768px) { - .menu { - flex-direction: row; - flex-wrap: wrap; - } -} diff --git a/components/pages/settings/teams/TeamsTable.js b/components/pages/settings/teams/TeamsTable.js index 1319c6d4..854b7bd9 100644 --- a/components/pages/settings/teams/TeamsTable.js +++ b/components/pages/settings/teams/TeamsTable.js @@ -1,126 +1,90 @@ import Link from 'next/link'; -import { - Button, - Flexbox, - Icon, - Icons, - Modal, - ModalTrigger, - Table, - TableBody, - TableCell, - TableColumn, - TableHeader, - TableRow, - Text, -} from 'react-basics'; +import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics'; import TeamDeleteForm from './TeamDeleteForm'; import TeamLeaveForm from './TeamLeaveForm'; import useMessages from 'hooks/useMessages'; import useUser from 'hooks/useUser'; import { ROLES } from 'lib/constants'; +import SettingsTable from 'components/common/SettingsTable'; export default function TeamsTable({ data = [], onDelete }) { const { formatMessage, labels } = useMessages(); const { user } = useUser(); const columns = [ - { name: 'name', label: formatMessage(labels.name), style: { flex: 2 } }, + { name: 'name', label: formatMessage(labels.name) }, { name: 'owner', label: formatMessage(labels.owner) }, { name: 'action', label: ' ' }, ]; + const cellRender = (row, data, key) => { + if (key === 'owner') { + return row.teamUser.find(({ role }) => role === ROLES.teamOwner)?.user?.username; + } + return data[key]; + }; + return ( - - - {(column, index) => { - return ( - - {column.label} - - ); - }} - - - {(row, keys, rowIndex) => { - const { id, teamUser } = row; - const owner = row.teamUser.find(({ role }) => role === ROLES.teamOwner); - const showDelete = user.id === owner?.userId; - const teamUserId = teamUser.find(a => a.userId === user.id).id; + + {row => { + const { id, teamUser } = row; + const owner = teamUser.find(({ role }) => role === ROLES.teamOwner); + const showDelete = user.id === owner?.userId; - const rowData = { - ...row, - owner: owner?.user?.username, - action: ( - - - - - {showDelete && ( - - - - {close => ( - - )} - - - )} - {!showDelete && ( - - - - {close => ( - - )} - - - )} - - ), - }; - - return ( - - {(data, key, colIndex) => { - return ( - - - {data[key]} - - - ); - }} - - ); - }} - -
+ return ( + <> + + + + {showDelete && ( + + + + {close => ( + + )} + + + )} + {!showDelete && ( + + + + {close => ( + + )} + + + )} + + ); + }} + ); } diff --git a/components/pages/settings/users/UsersTable.js b/components/pages/settings/users/UsersTable.js index 1542fe28..5ea3806c 100644 --- a/components/pages/settings/users/UsersTable.js +++ b/components/pages/settings/users/UsersTable.js @@ -1,109 +1,71 @@ -import { - Button, - Text, - Icon, - Table, - TableBody, - TableCell, - TableColumn, - TableHeader, - TableRow, - Flexbox, - Icons, - ModalTrigger, - Modal, -} from 'react-basics'; +import { Button, Text, Icon, Icons, ModalTrigger, Modal } from 'react-basics'; import { formatDistance } from 'date-fns'; import Link from 'next/link'; import useUser from 'hooks/useUser'; import UserDeleteForm from './UserDeleteForm'; import { ROLES } from 'lib/constants'; import useMessages from 'hooks/useMessages'; +import SettingsTable from 'components/common/SettingsTable'; export default function UsersTable({ data = [], onDelete }) { const { formatMessage, labels } = useMessages(); const { user } = useUser(); const columns = [ - { name: 'username', label: formatMessage(labels.username), style: { flex: 2 } }, - { name: 'role', label: formatMessage(labels.role), style: { flex: 1 } }, - { name: 'created', label: formatMessage(labels.created), style: { flex: 1 } }, - { name: 'action', label: ' ', style: { flex: 2 } }, + { name: 'username', label: formatMessage(labels.username), style: { flex: 1.5 } }, + { name: 'role', label: formatMessage(labels.role) }, + { name: 'created', label: formatMessage(labels.created) }, + { name: 'action', label: ' ' }, ]; - return ( - - - {(column, index) => { - return ( - - {column.label} - - ); - }} - - - {(row, keys, rowIndex) => { - const rowData = { - ...row, - created: formatDistance(new Date(row.createdAt), new Date(), { - addSuffix: true, - }), - role: formatMessage( - labels[Object.keys(ROLES).find(key => ROLES[key] === row.role)] || labels.unknown, - ), - action: ( - <> - - - - - - - {close => ( - - )} - - - - ), - }; + const cellRender = (row, data, key) => { + if (key === 'created') { + return formatDistance(new Date(row.createdAt), new Date(), { + addSuffix: true, + }); + } + if (key === 'role') { + return formatMessage( + labels[Object.keys(ROLES).find(key => ROLES[key] === row.role)] || labels.unknown, + ); + } + return data[key]; + }; - return ( - - {(data, key, colIndex) => { - return ( - - - {data[key]} - - - ); - }} - - ); - }} - -
+ return ( + + {(row, keys, rowIndex) => { + return ( + <> + + + + + + + {close => ( + + )} + + + + ); + }} + ); } diff --git a/components/pages/settings/websites/WebsitesTable.js b/components/pages/settings/websites/WebsitesTable.js index d658be48..0ed79e4f 100644 --- a/components/pages/settings/websites/WebsitesTable.js +++ b/components/pages/settings/websites/WebsitesTable.js @@ -1,83 +1,45 @@ import Link from 'next/link'; -import { - Table, - TableHeader, - TableBody, - TableRow, - TableCell, - TableColumn, - Button, - Text, - Icon, - Icons, - Flexbox, - useBreakpoint, -} from 'react-basics'; +import { Button, Text, Icon, Icons } from 'react-basics'; +import SettingsTable from 'components/common/SettingsTable'; import useMessages from 'hooks/useMessages'; import useConfig from 'hooks/useConfig'; export default function WebsitesTable({ data = [] }) { const { formatMessage, labels } = useMessages(); const { openExternal } = useConfig(); - const breakPoint = useBreakpoint(); const columns = [ - { name: 'name', label: formatMessage(labels.name), style: { flex: 2 } }, + { name: 'name', label: formatMessage(labels.name) }, { name: 'domain', label: formatMessage(labels.domain) }, - { name: 'action', label: ' ', style: { flexBasis: '100%' } }, + { name: 'action', label: ' ' }, ]; return ( - - - {(column, index) => { - return ( - - {column.label} - - ); - }} - - - {(row, keys, rowIndex) => { - const { id } = row; + + {row => { + const { id } = row; - row.action = ( - - - - - - - - - ); - - return ( - - {(data, key, colIndex) => { - return ( - - - {data[key]} - - - ); - }} - - ); - }} - -
+ return ( + <> + + + + + + + + ); + }} + ); } diff --git a/components/pages/settings/websites/WebsitesTable.module.css b/components/pages/settings/websites/WebsitesTable.module.css new file mode 100644 index 00000000..a26c349f --- /dev/null +++ b/components/pages/settings/websites/WebsitesTable.module.css @@ -0,0 +1,13 @@ +@media screen and (max-width: 992px) { + .row { + flex-wrap: wrap; + } + + .header .actions { + display: none; + } + + .actions { + flex-basis: 100%; + } +} diff --git a/package.json b/package.json index b63935a2..c699d1f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "umami", - "version": "2.0.0-beta.4", + "version": "2.0.0-beta.5", "description": "A simple, fast, privacy-focused alternative to Google Analytics.", "author": "Mike Cao ", "license": "MIT", @@ -94,7 +94,7 @@ "node-fetch": "^3.2.8", "npm-run-all": "^4.1.5", "react": "^18.2.0", - "react-basics": "^0.75.0", + "react-basics": "^0.76.0", "react-beautiful-dnd": "^13.1.0", "react-dom": "^18.2.0", "react-intl": "^5.24.7", diff --git a/pages/api/config.ts b/pages/api/config.ts index bccfd048..a8ae1cb0 100644 --- a/pages/api/config.ts +++ b/pages/api/config.ts @@ -16,7 +16,7 @@ export default async (req: NextApiRequest, res: NextApiResponse) trackerScriptName: process.env.TRACKER_SCRIPT_NAME, updatesDisabled: !!process.env.DISABLE_UPDATES, telemetryDisabled: !!process.env.DISABLE_TELEMETRY, - cloudMode: !!process.env.CLOUD_MODE, + cloudMode: false, //!!process.env.CLOUD_MODE, }); } diff --git a/queries/admin/user.ts b/queries/admin/user.ts index 431e934b..1f3a2bd0 100644 --- a/queries/admin/user.ts +++ b/queries/admin/user.ts @@ -23,6 +23,7 @@ export async function getUser( export async function getUsers(): Promise { return prisma.client.user.findMany({ + take: 100, where: { deletedAt: null, }, diff --git a/yarn.lock b/yarn.lock index b759ff50..10c18dc6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6727,10 +6727,10 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-basics@^0.75.0: - version "0.75.0" - resolved "https://registry.yarnpkg.com/react-basics/-/react-basics-0.75.0.tgz#501ba7fae6e0659ec8f7e811a4303ef83bd57b13" - integrity sha512-mDm+L/cw4LX4LylJW0MyV+YFxhZ0tMa/bCIs1QsApcRGvF4ahlB1rdwWn6/p01PVSHe7xS/55lSklp3b7IWOaw== +react-basics@^0.76.0: + version "0.76.0" + resolved "https://registry.yarnpkg.com/react-basics/-/react-basics-0.76.0.tgz#7369ba68409388f458a2ecf73a86603884fc0711" + integrity sha512-RRtudldMecbuT/ap1giy6OdNc1t8gfGdyfXDTy4x99PWN9kvfS8MU11cfyQif8F0C6v9wKFu2taxklQQarE+mw== dependencies: classnames "^2.3.1" date-fns "^2.29.3" From 4a1c6f40a659dd66b673105e2340aac0a710a0bf Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Wed, 12 Apr 2023 13:41:00 -0700 Subject: [PATCH 4/6] Fix config. --- pages/api/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/api/config.ts b/pages/api/config.ts index a8ae1cb0..bccfd048 100644 --- a/pages/api/config.ts +++ b/pages/api/config.ts @@ -16,7 +16,7 @@ export default async (req: NextApiRequest, res: NextApiResponse) trackerScriptName: process.env.TRACKER_SCRIPT_NAME, updatesDisabled: !!process.env.DISABLE_UPDATES, telemetryDisabled: !!process.env.DISABLE_TELEMETRY, - cloudMode: false, //!!process.env.CLOUD_MODE, + cloudMode: !!process.env.CLOUD_MODE, }); } From b32ced55019e39390b658c931659eba8ea48997a Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Wed, 12 Apr 2023 17:43:08 -0700 Subject: [PATCH 5/6] Responsive fixes for settings pages. --- components/common/HamburgerButton.js | 16 +-- components/common/MobileMenu.js | 8 +- components/common/SettingsTable.module.css | 4 + components/layout/PageHeader.module.css | 2 +- .../settings/profile/DateRangeSetting.js | 2 +- .../pages/settings/profile/LanguageSetting.js | 2 +- .../pages/settings/profile/TimezoneSetting.js | 5 +- .../pages/settings/teams/TeamEditForm.js | 2 +- .../pages/settings/teams/TeamMembers.js | 2 +- .../pages/settings/teams/TeamMembersTable.js | 87 ++++++--------- .../pages/settings/teams/TeamWebsites.js | 12 +-- .../pages/settings/teams/TeamWebsitesTable.js | 102 ++++++------------ .../pages/settings/users/UserWebsites.js | 2 +- .../settings/websites/WebsiteEditForm.js | 2 +- package.json | 2 +- yarn.lock | 8 +- 16 files changed, 97 insertions(+), 161 deletions(-) diff --git a/components/common/HamburgerButton.js b/components/common/HamburgerButton.js index 9c92b282..a2d26779 100644 --- a/components/common/HamburgerButton.js +++ b/components/common/HamburgerButton.js @@ -13,32 +13,32 @@ export default function HamburgerButton() { const menuItems = [ { label: formatMessage(labels.dashboard), - value: '/dashboard', + url: '/dashboard', }, - { label: formatMessage(labels.realtime), value: '/realtime' }, + { label: formatMessage(labels.realtime), url: '/realtime' }, !cloudMode && { label: formatMessage(labels.settings), - value: '/settings', + url: '/settings', children: [ { label: formatMessage(labels.websites), - value: '/settings/websites', + url: '/settings/websites', }, { label: formatMessage(labels.teams), - value: '/settings/teams', + url: '/settings/teams', }, { label: formatMessage(labels.users), - value: '/settings/users', + url: '/settings/users', }, ], }, { label: formatMessage(labels.profile), - value: '/settings/profile', + url: '/settings/profile', }, - !cloudMode && { label: formatMessage(labels.logout), value: '/logout' }, + !cloudMode && { label: formatMessage(labels.logout), url: '/logout' }, ].filter(n => n); const handleClick = () => setActive(state => !state); diff --git a/components/common/MobileMenu.js b/components/common/MobileMenu.js index 4168a6c6..44c8da84 100644 --- a/components/common/MobileMenu.js +++ b/components/common/MobileMenu.js @@ -8,14 +8,14 @@ export default function MobileMenu({ items = [], onClose }) { const Items = ({ items, className }) => (
- {items.map(({ label, value, children }) => { - const selected = pathname === value; + {items.map(({ label, url, children }) => { + const selected = pathname.startsWith(url); return ( <> diff --git a/components/common/SettingsTable.module.css b/components/common/SettingsTable.module.css index 023d1338..fd6cddfa 100644 --- a/components/common/SettingsTable.module.css +++ b/components/common/SettingsTable.module.css @@ -1,3 +1,7 @@ +.cell { + align-items: center; +} + .row .cell:last-child { gap: 10px; justify-content: flex-end; diff --git a/components/layout/PageHeader.module.css b/components/layout/PageHeader.module.css index 8a2a6800..1dd212bc 100644 --- a/components/layout/PageHeader.module.css +++ b/components/layout/PageHeader.module.css @@ -26,7 +26,7 @@ font-size: 24px; font-weight: 700; gap: 20px; - line-height: 50px; + height: 60px; } .actions { diff --git a/components/pages/settings/profile/DateRangeSetting.js b/components/pages/settings/profile/DateRangeSetting.js index 23921d31..2c2d70fc 100644 --- a/components/pages/settings/profile/DateRangeSetting.js +++ b/components/pages/settings/profile/DateRangeSetting.js @@ -12,7 +12,7 @@ export default function DateRangeSetting() { const handleReset = () => setDateRange(DEFAULT_DATE_RANGE); return ( - + diff --git a/components/pages/settings/profile/LanguageSetting.js b/components/pages/settings/profile/LanguageSetting.js index 8130d33a..e5fc874d 100644 --- a/components/pages/settings/profile/LanguageSetting.js +++ b/components/pages/settings/profile/LanguageSetting.js @@ -14,7 +14,7 @@ export default function LanguageSetting() { const renderValue = value => languages[value].label; return ( - + saveTimezone(getTimezone()); return ( - + {item => {item}} diff --git a/components/pages/settings/teams/TeamEditForm.js b/components/pages/settings/teams/TeamEditForm.js index 1a9a8baa..a51d4735 100644 --- a/components/pages/settings/teams/TeamEditForm.js +++ b/components/pages/settings/teams/TeamEditForm.js @@ -41,7 +41,7 @@ export default function TeamEditForm({ teamId, data, onSave, readOnly }) { }; return ( -
+ diff --git a/components/pages/settings/teams/TeamMembers.js b/components/pages/settings/teams/TeamMembers.js index ab435c4d..cafb4581 100644 --- a/components/pages/settings/teams/TeamMembers.js +++ b/components/pages/settings/teams/TeamMembers.js @@ -12,7 +12,7 @@ export default function TeamMembers({ teamId, readOnly }) { ); if (isLoading) { - return ; + return ; } const handleSave = async () => { diff --git a/components/pages/settings/teams/TeamMembersTable.js b/components/pages/settings/teams/TeamMembersTable.js index b13e57cd..ae030e4e 100644 --- a/components/pages/settings/teams/TeamMembersTable.js +++ b/components/pages/settings/teams/TeamMembersTable.js @@ -1,72 +1,45 @@ import useMessages from 'hooks/useMessages'; import useUser from 'hooks/useUser'; import { ROLES } from 'lib/constants'; -import { - Flexbox, - Table, - TableBody, - TableCell, - TableColumn, - TableHeader, - TableRow, -} from 'react-basics'; import TeamMemberRemoveButton from './TeamMemberRemoveButton'; +import SettingsTable from 'components/common/SettingsTable'; export default function TeamMembersTable({ data = [], onSave, readOnly }) { const { formatMessage, labels } = useMessages(); const { user } = useUser(); const columns = [ - { name: 'username', label: formatMessage(labels.username), style: { flex: 2 } }, - { name: 'role', label: formatMessage(labels.role), style: { flex: 1 } }, - { name: 'action', label: '', style: { flex: 1 } }, + { name: 'username', label: formatMessage(labels.username) }, + { name: 'role', label: formatMessage(labels.role) }, + { name: 'action', label: ' ' }, ]; - return ( - - - {(column, index) => { - return ( - - {column.label} - - ); - }} - - - {(row, keys, rowIndex) => { - const rowData = { - username: row?.user?.username, - role: formatMessage( - labels[Object.keys(ROLES).find(key => ROLES[key] === row.role) || labels.unknown], - ), - action: !readOnly && ( - - - - ), - }; + const cellRender = (row, data, key) => { + if (key === 'username') { + return row?.user?.username; + } + if (key === 'role') { + return formatMessage( + labels[Object.keys(ROLES).find(key => ROLES[key] === row.role) || labels.unknown], + ); + } + return data[key]; + }; - return ( - - {(data, key, colIndex) => { - return ( - - - {data[key]} - - - ); - }} - - ); - }} - -
+ return ( + + {row => { + return ( + !readOnly && ( + + ) + ); + }} + ); } diff --git a/components/pages/settings/teams/TeamWebsites.js b/components/pages/settings/teams/TeamWebsites.js index a1bcdee8..3e91b69c 100644 --- a/components/pages/settings/teams/TeamWebsites.js +++ b/components/pages/settings/teams/TeamWebsites.js @@ -9,7 +9,6 @@ import { Text, useToast, } from 'react-basics'; -import EmptyPlaceholder from 'components/common/EmptyPlaceholder'; import TeamWebsitesTable from 'components/pages/settings/teams/TeamWebsitesTable'; import TeamAddWebsiteForm from 'components/pages/settings/teams/TeamAddWebsiteForm'; import useApi from 'hooks/useApi'; @@ -25,7 +24,7 @@ export default function TeamWebsites({ teamId }) { const hasData = data && data.length !== 0; if (isLoading) { - return ; + return ; } const handleSave = async () => { @@ -50,15 +49,8 @@ export default function TeamWebsites({ teamId }) { return (
{toast} - {hasData && ( - {addButton} - )} + {addButton} {hasData && } - {!hasData && ( - - {addButton} - - )}
); } diff --git a/components/pages/settings/teams/TeamWebsitesTable.js b/components/pages/settings/teams/TeamWebsitesTable.js index 2d8a2a2d..a84598e8 100644 --- a/components/pages/settings/teams/TeamWebsitesTable.js +++ b/components/pages/settings/teams/TeamWebsitesTable.js @@ -1,23 +1,14 @@ import useMessages from 'hooks/useMessages'; import useUser from 'hooks/useUser'; import Link from 'next/link'; -import { - Button, - Flexbox, - Icon, - Icons, - Table, - TableBody, - TableCell, - TableColumn, - TableHeader, - TableRow, - Text, -} from 'react-basics'; +import { Button, Icon, Icons, Text } from 'react-basics'; import TeamWebsiteRemoveButton from './TeamWebsiteRemoveButton'; +import SettingsTable from 'components/common/SettingsTable'; +import useConfig from 'hooks/useConfig'; export default function TeamWebsitesTable({ data = [], onSave }) { const { formatMessage, labels } = useMessages(); + const { openExternal } = useConfig(); const { user } = useUser(); const columns = [ { name: 'name', label: formatMessage(labels.name) }, @@ -26,62 +17,37 @@ export default function TeamWebsitesTable({ data = [], onSave }) { ]; return ( - - - {(column, index) => { - return ( - - {column.label} - - ); - }} - - - {(row, keys, rowIndex) => { - const { teamId } = row; - const { id: websiteId, name, domain, userId } = row.website; - const { teamUser } = row.team; - const owner = teamUser[0]; - const canRemove = user.id === userId || user.id === owner.userId; + + {row => { + const { teamId } = row; + const { id: websiteId, name, domain, userId } = row.website; + const { teamUser } = row.team; + const owner = teamUser[0]; + const canRemove = user.id === userId || user.id === owner.userId; - row.name = name; - row.domain = domain; + row.name = name; + row.domain = domain; - row.action = ( - - - - - {canRemove && ( - - )} - - ); - - return ( - - {(data, key, colIndex) => { - return ( - - - {data[key]} - - - ); - }} - - ); - }} - -
+ return ( + <> + + + + {canRemove && ( + + )} + + ); + }} + ); } diff --git a/components/pages/settings/users/UserWebsites.js b/components/pages/settings/users/UserWebsites.js index 72222b13..1f44fb52 100644 --- a/components/pages/settings/users/UserWebsites.js +++ b/components/pages/settings/users/UserWebsites.js @@ -12,7 +12,7 @@ export default function UserWebsites({ userId }) { const hasData = data && data.length !== 0; if (isLoading) { - return ; + return ; } return ( diff --git a/components/pages/settings/websites/WebsiteEditForm.js b/components/pages/settings/websites/WebsiteEditForm.js index 01383f5a..4cf899b1 100644 --- a/components/pages/settings/websites/WebsiteEditForm.js +++ b/components/pages/settings/websites/WebsiteEditForm.js @@ -20,7 +20,7 @@ export default function WebsiteEditForm({ websiteId, data, onSave }) { }; return ( - + diff --git a/package.json b/package.json index c699d1f3..d9cac6af 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "node-fetch": "^3.2.8", "npm-run-all": "^4.1.5", "react": "^18.2.0", - "react-basics": "^0.76.0", + "react-basics": "^0.77.0", "react-beautiful-dnd": "^13.1.0", "react-dom": "^18.2.0", "react-intl": "^5.24.7", diff --git a/yarn.lock b/yarn.lock index 10c18dc6..423a2fd8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6727,10 +6727,10 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-basics@^0.76.0: - version "0.76.0" - resolved "https://registry.yarnpkg.com/react-basics/-/react-basics-0.76.0.tgz#7369ba68409388f458a2ecf73a86603884fc0711" - integrity sha512-RRtudldMecbuT/ap1giy6OdNc1t8gfGdyfXDTy4x99PWN9kvfS8MU11cfyQif8F0C6v9wKFu2taxklQQarE+mw== +react-basics@^0.77.0: + version "0.77.0" + resolved "https://registry.yarnpkg.com/react-basics/-/react-basics-0.77.0.tgz#31d35b4db8119c699eeab24a7cab10a613b549f4" + integrity sha512-L14dZqlg7P9m700OvND1fsdZA/vvLH3W0Ntw5Oyk2RxE47K6oMESSuPhDi1yC2QjDYwFdKzGSsgJGfWlc++Kww== dependencies: classnames "^2.3.1" date-fns "^2.29.3" From a30147547bff5b25fd9c4ffe8ec243124a35a42c Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Wed, 12 Apr 2023 17:47:11 -0700 Subject: [PATCH 6/6] Fix dropdown css. --- components/layout/PageHeader.module.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/components/layout/PageHeader.module.css b/components/layout/PageHeader.module.css index 1dd212bc..5ea85b70 100644 --- a/components/layout/PageHeader.module.css +++ b/components/layout/PageHeader.module.css @@ -16,10 +16,6 @@ color: var(--base900); } -.header > div { - line-height: 60px; -} - .title { display: flex; align-items: center;