Add new Gradebook filters button and tray
This is groundwork for subsequent filters work. Test plan: - Enable enhanced gradebook filters - "Applied Filters: None" should show above grid - Filters button should show above grid - Click button - Tray should expand - Bonus: See FilterNav in Storybook flag=enhanced_gradebook_filters Closes EVAL-1891 Change-Id: I45e44415bcd39b420a962cb79face12b7d6eef54 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/275899 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> QA-Review: Kai Bjorkman <kbjorkman@instructure.com> Product-Review: Syed Hussain <shussain@instructure.com> Reviewed-by: Spencer Olson <solson@instructure.com> Reviewed-by: Adrian Packel <apackel@instructure.com>
This commit is contained in:
parent
884495090a
commit
d02369cef3
|
@ -106,6 +106,7 @@
|
|||
<div id="gradebook-assignment-search" style="flex: 1;"></div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div id="gradebook-filter-nav"></div>
|
||||
<div id="gradebook-grid-wrapper" class="use-css-transitions-for-show-hide" style="display:none;">
|
||||
<div id="gradebook_grid"></div>
|
||||
</div>
|
||||
|
|
|
@ -27,6 +27,8 @@ const icons = {
|
|||
IconBulletListSquareLine: '',
|
||||
IconClearTextFormattingLine: '',
|
||||
IconDocumentLine: '',
|
||||
IconFilterLine: '',
|
||||
IconFilterSolid: '',
|
||||
IconFullScreenLine: '',
|
||||
IconImageLine: '',
|
||||
IconIndentLine: '',
|
||||
|
@ -36,6 +38,8 @@ const icons = {
|
|||
IconNumberedListLine: '',
|
||||
IconOutdentLine: '',
|
||||
IconRemoveLinkLine: '',
|
||||
IconSettingsLine: '',
|
||||
IconSettingsSolid: '',
|
||||
IconStrikethroughLine: '',
|
||||
IconTextCenteredLine: '',
|
||||
IconTextEndLine: '',
|
||||
|
|
|
@ -23,6 +23,7 @@ import Gradebook from './react/default_gradebook/Gradebook'
|
|||
import('@canvas/context-cards/react/StudentContextCardTrigger')
|
||||
|
||||
const mountPoint = document.querySelector('#gradebook_app')
|
||||
const filterNavNode = document.querySelector('#gradebook-filter-nav')
|
||||
const gradebookMenuNode = document.querySelector('[data-component="GradebookMenu"]')
|
||||
const settingsModalButtonContainer = document.getElementById(
|
||||
'gradebook-settings-modal-button-container'
|
||||
|
@ -34,6 +35,7 @@ const props = {
|
|||
locale: ENV.LOCALE,
|
||||
gradebookMenuNode,
|
||||
gridColorNode,
|
||||
filterNavNode,
|
||||
settingsModalButtonContainer,
|
||||
gradebookEnv: ENV.GRADEBOOK_OPTIONS
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ import PostPolicies from './PostPolicies/index'
|
|||
import GradebookMenu from '@canvas/gradebook-menu'
|
||||
import ViewOptionsMenu from './components/ViewOptionsMenu'
|
||||
import ActionMenu from './components/ActionMenu'
|
||||
import FilterNav from './components/FilterNav'
|
||||
import EnhancedActionMenu from './components/EnhancedActionMenu'
|
||||
import AssignmentGroupFilter from './components/content-filters/AssignmentGroupFilter'
|
||||
import GradingPeriodFilter from './components/content-filters/GradingPeriodFilter'
|
||||
|
@ -4330,6 +4331,11 @@ class Gradebook extends React.Component {
|
|||
<Portal node={this.props.gridColorNode}>
|
||||
<GridColor colors={this.state.gridColors} />
|
||||
</Portal>
|
||||
{this.options.enhanced_gradebook_filters && (
|
||||
<Portal node={this.props.filterNavNode}>
|
||||
<FilterNav />
|
||||
</Portal>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (C) 2021 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React, {useState} from 'react'
|
||||
import {Button, CloseButton} from '@instructure/ui-buttons'
|
||||
import {AccessibleContent} from '@instructure/ui-a11y-content'
|
||||
import I18n from 'i18n!gradebook'
|
||||
import {IconFilterSolid, IconFilterLine} from '@instructure/ui-icons'
|
||||
import {View} from '@instructure/ui-view'
|
||||
import {Flex} from '@instructure/ui-flex'
|
||||
import {Tag} from '@instructure/ui-tag'
|
||||
import {Tray} from '@instructure/ui-tray'
|
||||
import {Text} from '@instructure/ui-text'
|
||||
import {Heading} from '@instructure/ui-heading'
|
||||
|
||||
export default function FilterNav() {
|
||||
const [isTrayOpen, setIsTrayOpen] = useState(false)
|
||||
|
||||
const openTray = () => {
|
||||
setIsTrayOpen(true)
|
||||
}
|
||||
|
||||
// empty for now
|
||||
const filters = [].map(({label}) => {
|
||||
return (
|
||||
<Tag
|
||||
text={<AccessibleContent alt={I18n.t('Remove filter')}>{label}</AccessibleContent>}
|
||||
dismissible
|
||||
onClick={() => {}}
|
||||
margin="0 xx-small 0 0"
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
return (
|
||||
<Flex justifyItems="space-between" padding="0 0 small 0">
|
||||
<Flex.Item>
|
||||
<Flex>
|
||||
<Flex.Item padding="0 x-small 0 0">
|
||||
<IconFilterLine /> <Text weight="bold">{I18n.t('Applied Filters:')}</Text>
|
||||
</Flex.Item>
|
||||
<Flex.Item>
|
||||
{filters.length ? (
|
||||
filters
|
||||
) : (
|
||||
<Text color="secondary" weight="bold">
|
||||
{I18n.t('None')}
|
||||
</Text>
|
||||
)}
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
</Flex.Item>
|
||||
<Flex.Item>
|
||||
<Button
|
||||
renderIcon={IconFilterSolid}
|
||||
id="gradebook-settings-button"
|
||||
color="secondary"
|
||||
onClick={openTray}
|
||||
>
|
||||
{I18n.t('Filters')}
|
||||
</Button>
|
||||
</Flex.Item>
|
||||
<Tray
|
||||
placement="end"
|
||||
label="Tray Example"
|
||||
open={isTrayOpen}
|
||||
onDismiss={() => setIsTrayOpen(false)}
|
||||
size="small"
|
||||
>
|
||||
<View as="div" padding="medium">
|
||||
<Flex>
|
||||
<Flex.Item shouldGrow shouldShrink>
|
||||
<Heading level="h3" as="h3" margin="0 0 x-small">
|
||||
{I18n.t('Gradebook Filters')}
|
||||
</Heading>
|
||||
</Flex.Item>
|
||||
<Flex.Item>
|
||||
<CloseButton
|
||||
placement="end"
|
||||
offset="small"
|
||||
screenReaderLabel="Close"
|
||||
onClick={() => setIsTrayOpen(false)}
|
||||
/>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
<Button
|
||||
renderIcon={IconFilterLine}
|
||||
color="secondary"
|
||||
onClick={() => {}}
|
||||
margin="small 0 0 0"
|
||||
withVisualDebug
|
||||
data-testid="new-filter-button"
|
||||
>
|
||||
{I18n.t('Create New Filter')}
|
||||
</Button>
|
||||
</View>
|
||||
</Tray>
|
||||
</Flex>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2021 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React from 'react'
|
||||
import FilterNav from './FilterNav'
|
||||
|
||||
export default {
|
||||
title: 'Examples/Evaluate/Gradebook/FilterNav',
|
||||
component: FilterNav,
|
||||
args: {}
|
||||
}
|
||||
|
||||
const Template = args => <FilterNav {...args} />
|
||||
export const Default = Template.bind({})
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2021 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React from 'react'
|
||||
import {Default as FilterNav} from '../FilterNav.stories'
|
||||
import {render, fireEvent, within, cleanup, screen} from '@testing-library/react'
|
||||
import '@testing-library/jest-dom/extend-expect'
|
||||
|
||||
describe('FilterNav', () => {
|
||||
it('renders filters button', () => {
|
||||
const {getByRole} = render(<FilterNav {...FilterNav.args} />)
|
||||
expect(getByRole('button', {name: 'Filters'})).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('opens tray', () => {
|
||||
const {container} = render(<FilterNav {...FilterNav.args} />)
|
||||
fireEvent.click(within(container).getByText('Filters'))
|
||||
expect(screen.getByRole('heading')).toHaveTextContent('Gradebook Filters')
|
||||
cleanup()
|
||||
})
|
||||
|
||||
it('renders new filter button', () => {
|
||||
const {container} = render(<FilterNav {...FilterNav.args} />)
|
||||
fireEvent.click(within(container).getByText('Filters'))
|
||||
expect(screen.getByRole('button', {name: /Create New Filter/})).toBeInTheDocument()
|
||||
cleanup()
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue