Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bookmarks panel to console overview #7016

Merged
merged 32 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3c45789
console: Fix toggle and spinner
ryaplots Apr 2, 2024
28b8479
console: Add top entities panel
ryaplots Apr 2, 2024
831676e
console: Add individual lists
ryaplots Apr 2, 2024
41a1dac
console: Add per entity bookmark store
ryaplots Apr 2, 2024
1dd8356
console: Add top entities panel to overview
ryaplots Apr 2, 2024
9416c8d
console: Fix usebookmark method
ryaplots Apr 2, 2024
0f5b5aa
console: Add messages
ryaplots Apr 2, 2024
90a0298
console: Fix gradient
ryaplots Apr 2, 2024
103f31f
console: Fix panel height and overlay render
ryaplots Apr 2, 2024
61d1f00
console: Fix bookmarks dropdown
ryaplots Apr 2, 2024
67a1a37
console: Add bookmarks in the sidebar
ryaplots Apr 4, 2024
1a76087
console: Add through pagination request
ryaplots Apr 4, 2024
b0872a5
console: Fix dropdown
ryaplots Apr 4, 2024
b38329d
console: Add order to bookmarks request
ryaplots Apr 4, 2024
b779ccd
console: Fetch bookmarks in the sidebar
ryaplots Apr 4, 2024
d21b82f
console: Add dependencies
ryaplots Apr 4, 2024
563ba43
Merge branch 'feature/console-redesign' into feature/bookmarks-panel
ryaplots Apr 9, 2024
486c2f1
console: Fix linitng
ryaplots Apr 9, 2024
521be25
console: Avoid repetition
ryaplots Apr 15, 2024
880be33
Merge branch 'feature/console-redesign' into feature/bookmarks-panel
ryaplots Apr 15, 2024
609a608
console: Add section label dropdown
ryaplots Apr 15, 2024
b9a23cc
console: Avoid repetition
ryaplots Apr 15, 2024
f9e67e3
console: Add messages
ryaplots Apr 15, 2024
0bbf861
console: Fix header
ryaplots Apr 15, 2024
f13b5b7
console: Fix messages
ryaplots Apr 15, 2024
27b25d7
console: Fix messages and add error handling
ryaplots Apr 17, 2024
f73fe05
console: Fix breadcrumbs
ryaplots Apr 19, 2024
37de2ea
console: Make only one fetch and fill in array of items from store
ryaplots Apr 21, 2024
2d6f519
console: Fix panel height
ryaplots Apr 21, 2024
07bb6ef
console: Fix navigation
ryaplots Apr 21, 2024
79f8fa3
console: Center vertically and add fetching true
ryaplots Apr 22, 2024
b6bb7c4
Merge branch 'feature/console-redesign' into feature/bookmarks-panel
ryaplots Apr 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/webui/components/dropdown/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ DropdownItem.propTypes = {
active: PropTypes.bool,
exact: PropTypes.bool,
external: PropTypes.bool,
icon: PropTypes.string,
icon: PropTypes.shape({}),
messageClassName: PropTypes.string,
path: PropTypes.string,
showActive: PropTypes.bool,
Expand Down
1 change: 1 addition & 0 deletions pkg/webui/components/header/header.styl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
.bookmarks-dropdown
max-width: 19.3rem
width: 19.3rem // Avoids flash of small container when dropdown is opened
padding: 0

.logo
height: $cs.l
Expand Down
2 changes: 1 addition & 1 deletion pkg/webui/components/panel/toggle/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Toggle.propTypes = {
onToggleChange: PropTypes.func.isRequired,
options: PropTypes.arrayOf(
PropTypes.shape({
label: PropTypes.string.isRequired,
label: PropTypes.message.isRequired,
value: PropTypes.string.isRequired,
}),
).isRequired,
Expand Down
2 changes: 1 addition & 1 deletion pkg/webui/components/panel/toggle/toggle.styl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
&:hover:not(.toggle-button-active)
background: var(--c-bg-neutral-light)

@container panel (max-width: 395px)
@container panel (max-width: 485px)
.toggle
width: 100%

Expand Down
95 changes: 78 additions & 17 deletions pkg/webui/components/sidebar/section-label/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,25 @@

import React from 'react'
import classnames from 'classnames'
import { useSelector } from 'react-redux'

import { IconApplication, IconDevice, IconGateway, IconOrganization } from '@ttn-lw/components/icon'
import Button from '@ttn-lw/components/button'
import Dropdown from '@ttn-lw/components/dropdown'

import Message from '@ttn-lw/lib/components/message'

import PropTypes from '@ttn-lw/lib/prop-types'
import sharedMessages from '@ttn-lw/lib/shared-messages'

import {
checkFromState,
mayViewApplications,
mayViewGateways,
mayViewOrganizationsOfUser,
} from '@console/lib/feature-checks'

import { selectUser } from '@console/store/selectors/logout'

const SectionLabel = ({
label,
Expand All @@ -28,23 +41,71 @@ const SectionLabel = ({
onClick,
buttonDisabled,
'data-test-id': dataTestId,
}) => (
<div
className={classnames(
className,
'd-flex',
'j-between',
'al-center',
'c-text-neutral-light',
'ml-cs-s',
'fs-s',
)}
data-test-id={dataTestId}
>
<Message content={label} />
<Button naked small icon={icon} disabled={buttonDisabled} onClick={onClick} />
</div>
)
}) => {
const user = useSelector(selectUser)
const mayViewApps = useSelector(state =>
user ? checkFromState(mayViewApplications, state) : false,
)
const mayViewGtws = useSelector(state => (user ? checkFromState(mayViewGateways, state) : false))
const mayViewOrgs = useSelector(state =>
user ? checkFromState(mayViewOrganizationsOfUser, state) : false,
)

const plusDropdownItems = (
<>
{mayViewApps && (
<Dropdown.Item
title={sharedMessages.addApplication}
icon={IconApplication}
path="/applications/add"
/>
)}
{mayViewGtws && (
<Dropdown.Item title={sharedMessages.addGateway} icon={IconGateway} path="/gateways/add" />
)}
{mayViewOrgs && (
<Dropdown.Item
title={sharedMessages.addOrganization}
icon={IconOrganization}
path="/organizations/add"
/>
)}

<Dropdown.Item
title="Register end device in application"
icon={IconDevice}
path="/devices/add"
/>
</>
)

return (
<div
className={classnames(
className,
'd-flex',
'j-between',
'al-center',
'c-text-neutral-light',
'ml-cs-xs',
'fs-s',
)}
data-test-id={dataTestId}
>
<Message content={label} />
<Button
naked
small
icon={icon}
disabled={buttonDisabled}
onClick={onClick}
dropdownItems={plusDropdownItems}
dropdownPosition="below right"
noDropdownIcon
/>
</div>
)
}

SectionLabel.propTypes = {
buttonDisabled: PropTypes.bool,
Expand Down
4 changes: 4 additions & 0 deletions pkg/webui/components/spinner/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const Spinner = ({
micro = false,
small,
inline = false,
right = false,
}) => {
const [visible, setVisible] = useState(false)
const visibilityTimeout = setTimeout(() => setVisible(true), after)
Expand All @@ -52,6 +53,7 @@ const Spinner = ({
faded,
visible,
inline,
right,
}),
)

Expand Down Expand Up @@ -82,6 +84,7 @@ Spinner.propTypes = {
faded: PropTypes.bool,
inline: PropTypes.bool,
micro: PropTypes.bool,
right: PropTypes.bool,
small: PropTypes.bool,
}

Expand All @@ -94,6 +97,7 @@ Spinner.defaultProps = {
inline: false,
micro: false,
small: false,
right: false,
}

export default Spinner
4 changes: 4 additions & 0 deletions pkg/webui/components/spinner/spinner.styl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ $xs = $cs.m
justify-content: flex-start
align-items: center

&.right
&:not(.inline)
text-align: right

.spinner
width: $l
height: $l
Expand Down
2 changes: 1 addition & 1 deletion pkg/webui/components/table/row/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ Row.propTypes = {
/** A flag indicating whether the row is wrapping the head of a table. */
head: PropTypes.bool,
/** The identifier of the row. */
id: PropTypes.number,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
/** The href to be passed as `to` prop to the `<Link />` component that wraps the row. */
linkTo: PropTypes.string,
/**
Expand Down
19 changes: 14 additions & 5 deletions pkg/webui/console/containers/header/bookmarks-dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,16 @@ const m = defineMessages({
})

const Bookmark = ({ bookmark }) => {
const { title, path, icon } = useBookmark(bookmark)
const { title, ids, path, icon } = useBookmark(bookmark)

return <Dropdown.Item title={title} path={path} icon={icon} messageClassName={style.bookmark} />
return (
<Dropdown.Item
title={title === '' ? ids.id : title}
path={path}
icon={icon}
messageClassName={style.bookmark}
/>
)
}

Bookmark.propTypes = {
Expand All @@ -61,9 +68,11 @@ const BookmarksDropdown = () => {
</div>
) : (
<>
{dropdownItems.slice(0, 15).map(bookmark => (
<Bookmark key={bookmark.created_at} bookmark={bookmark} />
))}
<div className={style.bookmarkContainer}>
{dropdownItems.slice(0, 15).map((bookmark, index) => (
<Bookmark key={index} bookmark={bookmark} />
))}
</div>
{dropdownItems.length > 15 && (
<div className="p-cs-l c-text-neutral-light fs-s text-center c-bg-brand-extralight br-l">
<Message content={m.threshold} />
Expand Down
4 changes: 4 additions & 0 deletions pkg/webui/console/containers/header/header.styl
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,7 @@
.bookmark
overflow: hidden
text-overflow: ellipsis

&-container
padding: $cs.xs
border-bottom: 1px solid var(--c-border-neutral-light)
17 changes: 7 additions & 10 deletions pkg/webui/console/containers/header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import React, { useCallback } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { defineMessages } from 'react-intl'

import {
IconLogout,
Expand Down Expand Up @@ -52,12 +51,6 @@ import Logo from '../logo'
import NotificationsDropdown from './notifications-dropdown'
import BookmarksDropdown from './bookmarks-dropdown'

const m = defineMessages({
addApplication: 'Add new application',
addGateway: 'Add new gateway',
addOrganization: 'Add new organization',
})

const accountUrl = selectAccountUrl()

const Header = ({ onMenuClick }) => {
Expand All @@ -78,14 +71,18 @@ const Header = ({ onMenuClick }) => {
const plusDropdownItems = (
<>
{mayViewApps && (
<Dropdown.Item title={m.addApplication} icon={IconApplication} path="/applications/add" />
<Dropdown.Item
title={sharedMessages.addApplication}
icon={IconApplication}
path="/applications/add"
/>
)}
{mayViewGtws && (
<Dropdown.Item title={m.addGateway} icon={IconGateway} path="/gateways/add" />
<Dropdown.Item title={sharedMessages.addGateway} icon={IconGateway} path="/gateways/add" />
)}
{mayViewOrgs && (
<Dropdown.Item
title={m.addOrganization}
title={sharedMessages.addOrganization}
icon={IconOrganization}
path="/organizations/add"
/>
Expand Down
4 changes: 2 additions & 2 deletions pkg/webui/console/containers/shortcut-panel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const m = defineMessages({
shortcuts: 'Quick actions',
addApplication: 'New Application',
ryaplots marked this conversation as resolved.
Show resolved Hide resolved
addGateway: 'New Gateway',
ryaplots marked this conversation as resolved.
Show resolved Hide resolved
addOrganization: 'New Organization',
addNewOrganization: 'New Organization',
ryaplots marked this conversation as resolved.
Show resolved Hide resolved
addPersonalApiKey: 'New personal API key',
registerDevice: 'Register a device',
ryaplots marked this conversation as resolved.
Show resolved Hide resolved
})
Expand All @@ -54,7 +54,7 @@ const ShortcutPanel = () => (
/>
<ShortcutItem
icon={IconUsersGroup}
title={m.addOrganization}
title={m.addNewOrganization}
link="/organizations/add"
className="item-4"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@
// limitations under the License.

import React, { useContext } from 'react'
import { useSelector } from 'react-redux'

import { IconPlus } from '@ttn-lw/components/icon'
import SectionLabel from '@ttn-lw/components/sidebar/section-label'
import SideNavigation from '@ttn-lw/components/sidebar/side-menu'

import sharedMessages from '@ttn-lw/lib/shared-messages'
import { selectApplicationBookmarks } from '@console/store/selectors/user-preferences'
import { selectUserId } from '@console/store/selectors/logout'

import SidebarContext from '../context'

import TopEntitiesSection from './top-entities-section'

const AppListSideNavigation = () => {
const { topEntities, isMinimized } = useContext(SidebarContext)
const topEntities = useSelector(state => selectApplicationBookmarks(state))
const { isMinimized } = useContext(SidebarContext)
const userId = useSelector(selectUserId)

if (isMinimized || topEntities.length === 0) {
// Rendering an empty div to prevent the shadow of the search bar
Expand All @@ -32,16 +34,7 @@ const AppListSideNavigation = () => {
return <div />
}

return (
<div>
<SectionLabel label={sharedMessages.topApplications} icon={IconPlus} onClick={() => null} />
<SideNavigation>
{topEntities.map(({ path, entity, title }) => (
<SideNavigation.Item title={title} path={path} icon={entity} key={path} />
))}
</SideNavigation>
</div>
)
return <TopEntitiesSection topEntities={topEntities} userId={userId} />
}

export default AppListSideNavigation
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ import {
IconLayoutDashboard,
IconUserShield,
IconKey,
IconPlus,
IconInbox,
} from '@ttn-lw/components/icon'
import SideNavigation from '@ttn-lw/components/sidebar/side-menu'
import SectionLabel from '@ttn-lw/components/sidebar/section-label'

import sharedMessages from '@ttn-lw/lib/shared-messages'

Expand All @@ -38,12 +36,15 @@ import {
import getCookie from '@console/lib/table-utils'

import { selectUser, selectUserIsAdmin } from '@console/store/selectors/logout'
import { selectBookmarksList } from '@console/store/selectors/user-preferences'

import SidebarContext from '../context'

const GeneralSideNavigation = () => {
const { topEntities, isMinimized } = useContext(SidebarContext)
import TopEntitiesSection from './top-entities-section'

const GeneralSideNavigation = () => {
const { isMinimized } = useContext(SidebarContext)
const topEntities = useSelector(state => selectBookmarksList(state))
const isUserAdmin = useSelector(selectUserIsAdmin)
const user = useSelector(selectUser)
const mayViewOrgs = useSelector(state =>
Expand Down Expand Up @@ -94,13 +95,8 @@ const GeneralSideNavigation = () => {
/>
)}
</SideNavigation>
{!isMinimized && (
<SideNavigation className="mt-cs-xs">
<SectionLabel label={sharedMessages.topEntities} icon={IconPlus} onClick={() => null} />
{topEntities.map(({ path, title, entity }) => (
<SideNavigation.Item key={path} title={title} path={path} icon={entity} />
))}
</SideNavigation>
{!isMinimized && topEntities.length > 0 && (
<TopEntitiesSection topEntities={topEntities} userId={user.ids.user_id} />
)}
</>
)
Expand Down