diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e74f40..1095249 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - markdown support for page paragraphs and field description - hideable omf badge - login notes +- username in admin toolbar +- github stars in multiple places ### Changed ### Fixed @@ -23,6 +25,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - number field defaults - translations for field validation - number validation +- side menu only shows accessible entries ### Security diff --git a/assets/global.scss b/assets/global.scss index e54bd6f..bc41a8e 100644 --- a/assets/global.scss +++ b/assets/global.scss @@ -1,5 +1,6 @@ @import "variables"; @import "node_modules/swiper/swiper.scss"; +@import "../node_modules/react-github-button/assets/style.css"; :root { --backgroundColor: #{$background-color}; diff --git a/components/auth/footer.tsx b/components/auth/footer.tsx index 04a6450..7904c37 100644 --- a/components/auth/footer.tsx +++ b/components/auth/footer.tsx @@ -3,6 +3,7 @@ import { Button, Select } from 'antd' import Link from 'next/link' import { useRouter } from 'next/router' import React from 'react' +import GitHubButton from 'react-github-button' import { useTranslation } from 'react-i18next' import { SETTINGS_QUERY, SettingsQueryData } from '../../graphql/query/settings.query' import { languages } from '../../i18n' @@ -71,6 +72,7 @@ const AuthFooterInner: React.FC = (props) => { ))} + ) diff --git a/components/sidemenu.tsx b/components/sidemenu.tsx index 0fca80e..e25d5fe 100644 --- a/components/sidemenu.tsx +++ b/components/sidemenu.tsx @@ -10,6 +10,7 @@ export interface SideMenuElement { group?: boolean href?: string icon?: JSX.Element + role?: 'superuser' | 'admin' } export const sideMenu: SideMenuElement[] = [ @@ -42,6 +43,7 @@ export const sideMenu: SideMenuElement[] = [ key: 'administration', name: 'admin:administration', group: true, + role: 'superuser', items: [ { key: 'users', diff --git a/components/structure.tsx b/components/structure.tsx index 4953bab..98b46c1 100644 --- a/components/structure.tsx +++ b/components/structure.tsx @@ -1,12 +1,16 @@ import { CaretDownOutlined, UserOutlined } from '@ant-design/icons' import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons/lib' -import { Dropdown, Layout, Menu, PageHeader, Select, Spin, Tag } from 'antd' +import { useQuery } from '@apollo/react-hooks' +import { Dropdown, Layout, Menu, PageHeader, Select, Space, Spin, Tag } from 'antd' import Link from 'next/link' import { useRouter } from 'next/router' import React, { CSSProperties, FunctionComponent } from 'react' import { useTranslation } from 'react-i18next' +import { ME_QUERY, MeQueryData } from '../graphql/query/me.query' +import { SETTINGS_QUERY, SettingsQueryData } from '../graphql/query/settings.query' import { languages } from '../i18n' import { sideMenu, SideMenuElement } from './sidemenu' +import GitHubButton from 'react-github-button' import { useWindowSize } from './use.window.size' import { clearAuth } from './with.auth' @@ -40,6 +44,7 @@ const Structure: FunctionComponent = (props) => { const [selected, setSelected] = React.useState() const [sidebar, setSidebar] = React.useState(size.width < 700) const router = useRouter() + const user = useQuery(ME_QUERY) React.useEffect(() => { if (sidebar !== size.width < 700) { @@ -62,62 +67,74 @@ const Structure: FunctionComponent = (props) => { }, [props.selected]) const buildMenu = (data: SideMenuElement[]): JSX.Element[] => { - return data.map( - (element): JSX.Element => { - if (element.items && element.items.length > 0) { - if (element.group) { + return data + .filter((element) => { + if (!element.role) { + return true + } + + if (user.loading) { + return false + } + + return user.data.me.roles.includes(element.role) + }) + .map( + (element): JSX.Element => { + if (element.items && element.items.length > 0) { + if (element.group) { + return ( + + {element.icon} + {t(element.name)} + + } + > + {buildMenu(element.items)} + + ) + } + return ( - + {element.icon} {t(element.name)} - + } > {buildMenu(element.items)} - + ) } return ( - { + if (element.href) { + await router.push(element.href) + } + }} key={element.key} - title={ - - {element.icon} - {t(element.name)} - - } > - {buildMenu(element.items)} - + {element.icon} + {t(element.name)} + ) } - - return ( - { - if (element.href) { - await router.push(element.href) - } - }} - key={element.key} - > - {element.icon} - {t(element.name)} - - ) - } - ) + ) } const signOut = (): void => { @@ -165,16 +182,17 @@ const Structure: FunctionComponent = (props) => { onVisibleChange={setUserMenu} visible={userMenu} > -
+
Hi {user.data && user.data.me.username},
-
+ @@ -224,6 +242,9 @@ const Structure: FunctionComponent = (props) => { ))} + + + Version: {process.env.version} diff --git a/package.json b/package.json index 90bc20d..141d2af 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ohmyform-react", - "version": "0.9.1", + "version": "0.9.5", "license": "AGPL-3.0-or-later", "scripts": { "start:dev": "next dev -p 4000", @@ -29,6 +29,7 @@ "react": "16.13.1", "react-color": "^2.18.1", "react-dom": "16.13.1", + "react-github-button": "^0.1.11", "react-i18next": "^11.5.0", "react-icons": "^3.10.0", "react-id-swiper": "^3.0.0", diff --git a/yarn.lock b/yarn.lock index 5529551..350517b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6244,6 +6244,13 @@ react-dom@16.13.1: prop-types "^15.6.2" scheduler "^0.19.1" +react-github-button@^0.1.11: + version "0.1.11" + resolved "https://registry.yarnpkg.com/react-github-button/-/react-github-button-0.1.11.tgz#fc61e1f1e1371169d3618c1ba37306ba04081e56" + integrity sha1-/GHh8eE3EWnTYYwbo3MGugQIHlY= + dependencies: + prop-types "^15.5.10" + react-i18next@^11.5.0: version "11.5.0" resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.5.0.tgz#84a9bb535d44c0c1b336b94de164515c2cc2a714"