Remove Dashcard Reorder Feature Flag
Closes ADMIN-257 Test Plan: * Ensure that you are able to reorder/drag-n-drop dashcards without having to enable any feature flags Change-Id: Ia09c4ee821eb6a867a9521fdff5ccda5c599bcca Reviewed-on: https://gerrit.instructure.com/166529 Tested-by: Jenkins Reviewed-by: Ed Schiebel <eschiebel@instructure.com> Reviewed-by: Carl Kibler <ckibler@instructure.com> QA-Review: Anju Reddy <areddy@instructure.com> Product-Review: Carl Kibler <ckibler@instructure.com>
This commit is contained in:
parent
07132b9f92
commit
98a4d3c419
|
@ -155,10 +155,7 @@ module DashboardHelper
|
|||
presenter.to_h
|
||||
end
|
||||
|
||||
if @domain_root_account.feature_enabled?(:dashcard_reordering)
|
||||
mapped = mapped.sort_by {|h| h[:position] || ::CanvasSort::Last}
|
||||
end
|
||||
mapped
|
||||
mapped.sort_by {|h| h[:position] || ::CanvasSort::Last}
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import DashboardCardBox from '../dashboard_card/DashboardCardBox'
|
||||
import getDroppableDashboardCardBox from '../dashboard_card/getDroppableDashboardCardBox'
|
||||
import axios from 'axios'
|
||||
|
||||
|
@ -26,17 +25,17 @@ let promiseToGetDashboardCards
|
|||
|
||||
const sessionStorageKey = `dashcards_for_user_${ENV && ENV.current_user_id}`
|
||||
|
||||
export default function loadCardDashboard () {
|
||||
const Box = ENV.DASHBOARD_REORDERING_ENABLED ? getDroppableDashboardCardBox() : DashboardCardBox
|
||||
export default function loadCardDashboard() {
|
||||
const Box = getDroppableDashboardCardBox()
|
||||
const dashboardContainer = document.getElementById('DashboardCard_Container')
|
||||
|
||||
function render(dashboardCards) {
|
||||
ReactDOM.render(
|
||||
<Box
|
||||
courseCards={dashboardCards}
|
||||
reorderingEnabled={ENV.DASHBOARD_REORDERING_ENABLED}
|
||||
hideColorOverlays={ENV.PREFERENCES.hide_dashcard_color_overlays}
|
||||
/>, dashboardContainer
|
||||
/>,
|
||||
dashboardContainer
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -47,7 +46,7 @@ export default function loadCardDashboard () {
|
|||
|
||||
if (!promiseToGetDashboardCards) {
|
||||
promiseToGetDashboardCards = axios.get('/dashboard/dashboard_cards').then(({data}) => data)
|
||||
promiseToGetDashboardCards.then((dashboardCards) =>
|
||||
promiseToGetDashboardCards.then(dashboardCards =>
|
||||
sessionStorage.setItem(sessionStorageKey, JSON.stringify(dashboardCards))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
import _ from 'underscore'
|
||||
import React, { Component } from 'react'
|
||||
import React, {Component} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import I18n from 'i18n!dashcards'
|
||||
import DashboardCardAction from './DashboardCardAction'
|
||||
|
@ -25,7 +25,6 @@ import CourseActivitySummaryStore from './CourseActivitySummaryStore'
|
|||
import DashboardCardMenu from './DashboardCardMenu'
|
||||
|
||||
export default class DashboardCard extends Component {
|
||||
|
||||
// ===============
|
||||
// CONFIG
|
||||
// ===============
|
||||
|
@ -43,7 +42,6 @@ export default class DashboardCard extends Component {
|
|||
image: PropTypes.string,
|
||||
handleColorChange: PropTypes.func,
|
||||
hideColorOverlays: PropTypes.bool,
|
||||
reorderingEnabled: PropTypes.bool,
|
||||
isDragging: PropTypes.bool,
|
||||
connectDragSource: PropTypes.func,
|
||||
connectDropTarget: PropTypes.func,
|
||||
|
@ -59,20 +57,19 @@ export default class DashboardCard extends Component {
|
|||
hideColorOverlays: false,
|
||||
handleColorChange: () => {},
|
||||
image: '',
|
||||
reorderingEnabled: false,
|
||||
isDragging: false,
|
||||
connectDragSource: () => {},
|
||||
connectDropTarget: () => {},
|
||||
connectDragSource: c => c,
|
||||
connectDropTarget: c => c,
|
||||
moveCard: () => {},
|
||||
totalCards: 0,
|
||||
position: 0
|
||||
}
|
||||
|
||||
constructor (props) {
|
||||
constructor(props) {
|
||||
super()
|
||||
|
||||
this.state = _.extend(
|
||||
{ nicknameInfo: this.nicknameInfo(props.shortName, props.originalName, props.id) },
|
||||
{nicknameInfo: this.nicknameInfo(props.shortName, props.originalName, props.id)},
|
||||
CourseActivitySummaryStore.getStateForCourse(props.id)
|
||||
)
|
||||
}
|
||||
|
@ -81,12 +78,12 @@ export default class DashboardCard extends Component {
|
|||
// LIFECYCLE
|
||||
// ===============
|
||||
|
||||
componentDidMount () {
|
||||
componentDidMount() {
|
||||
CourseActivitySummaryStore.addChangeListener(this.handleStoreChange)
|
||||
this.parentNode = this.cardDiv
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
componentWillUnmount() {
|
||||
CourseActivitySummaryStore.removeChangeListener(this.handleStoreChange)
|
||||
}
|
||||
|
||||
|
@ -94,48 +91,54 @@ export default class DashboardCard extends Component {
|
|||
// ACTIONS
|
||||
// ===============
|
||||
|
||||
settingsClick = (e) => {
|
||||
if (e) { e.preventDefault(); }
|
||||
this.toggleEditing();
|
||||
settingsClick = e => {
|
||||
if (e) {
|
||||
e.preventDefault()
|
||||
}
|
||||
this.toggleEditing()
|
||||
}
|
||||
|
||||
getCardPosition () {
|
||||
getCardPosition() {
|
||||
return typeof this.props.position === 'function' ? this.props.position() : this.props.position
|
||||
}
|
||||
|
||||
handleNicknameChange = (nickname) => {
|
||||
this.setState({ nicknameInfo: this.nicknameInfo(nickname, this.props.originalName, this.props.id) })
|
||||
handleNicknameChange = nickname => {
|
||||
this.setState({
|
||||
nicknameInfo: this.nicknameInfo(nickname, this.props.originalName, this.props.id)
|
||||
})
|
||||
}
|
||||
|
||||
handleStoreChange = () => {
|
||||
this.setState(
|
||||
CourseActivitySummaryStore.getStateForCourse(this.props.id)
|
||||
);
|
||||
this.setState(CourseActivitySummaryStore.getStateForCourse(this.props.id))
|
||||
}
|
||||
|
||||
toggleEditing = () => {
|
||||
const currentState = !!this.state.editing;
|
||||
this.setState({editing: !currentState});
|
||||
const currentState = !!this.state.editing
|
||||
this.setState({editing: !currentState})
|
||||
}
|
||||
|
||||
headerClick = (e) => {
|
||||
if (e) { e.preventDefault(); }
|
||||
window.location = this.props.href;
|
||||
headerClick = e => {
|
||||
if (e) {
|
||||
e.preventDefault()
|
||||
}
|
||||
window.location = this.props.href
|
||||
}
|
||||
|
||||
doneEditing = () => {
|
||||
this.setState({editing: false})
|
||||
this.settingsToggle.focus();
|
||||
this.settingsToggle.focus()
|
||||
}
|
||||
|
||||
handleColorChange = (color) => {
|
||||
const hexColor = `#${color}`;
|
||||
handleColorChange = color => {
|
||||
const hexColor = `#${color}`
|
||||
this.props.handleColorChange(hexColor)
|
||||
}
|
||||
|
||||
handleMove = (assetString, atIndex) => {
|
||||
if (typeof this.props.moveCard === 'function') {
|
||||
this.props.moveCard(assetString, atIndex, () => { this.settingsToggle.focus() })
|
||||
this.props.moveCard(assetString, atIndex, () => {
|
||||
this.settingsToggle.focus()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,7 +146,7 @@ export default class DashboardCard extends Component {
|
|||
// HELPERS
|
||||
// ===============
|
||||
|
||||
nicknameInfo (nickname, originalName, courseId) {
|
||||
nicknameInfo(nickname, originalName, courseId) {
|
||||
return {
|
||||
nickname,
|
||||
originalName,
|
||||
|
@ -152,28 +155,30 @@ export default class DashboardCard extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
unreadCount (icon, stream) {
|
||||
unreadCount(icon, stream) {
|
||||
const activityType = {
|
||||
'icon-announcement': 'Announcement',
|
||||
'icon-assignment': 'Message',
|
||||
'icon-discussion': 'DiscussionTopic'
|
||||
}[icon];
|
||||
}[icon]
|
||||
|
||||
const itemStream = stream || [];
|
||||
const streamItem = _.find(itemStream, item => (
|
||||
// only return 'Message' type if category is 'Due Date' (for assignments)
|
||||
item.type === activityType &&
|
||||
const itemStream = stream || []
|
||||
const streamItem = _.find(
|
||||
itemStream,
|
||||
item =>
|
||||
// only return 'Message' type if category is 'Due Date' (for assignments)
|
||||
item.type === activityType &&
|
||||
(activityType !== 'Message' || item.notification_category === I18n.t('Due Date'))
|
||||
));
|
||||
)
|
||||
|
||||
// TODO: unread count is always 0 for assignments (see CNVS-21227)
|
||||
return (streamItem) ? streamItem.unread_count : 0;
|
||||
return streamItem ? streamItem.unread_count : 0
|
||||
}
|
||||
|
||||
calculateMenuOptions () {
|
||||
calculateMenuOptions() {
|
||||
const position = this.getCardPosition()
|
||||
const isFirstCard = position === 0;
|
||||
const isLastCard = position === this.props.totalCards - 1;
|
||||
const isFirstCard = position === 0
|
||||
const isLastCard = position === this.props.totalCards - 1
|
||||
return {
|
||||
canMoveLeft: !isFirstCard,
|
||||
canMoveRight: !isLastCard,
|
||||
|
@ -186,10 +191,10 @@ export default class DashboardCard extends Component {
|
|||
// RENDERING
|
||||
// ===============
|
||||
|
||||
linksForCard () {
|
||||
return this.props.links.map((link) => {
|
||||
linksForCard() {
|
||||
return this.props.links.map(link => {
|
||||
if (!link.hidden) {
|
||||
const screenReaderLabel = `${link.label} - ${this.state.nicknameInfo.nickname}`;
|
||||
const screenReaderLabel = `${link.label} - ${this.state.nicknameInfo.nickname}`
|
||||
return (
|
||||
<DashboardCardAction
|
||||
unreadCount={this.unreadCount(link.icon, this.state.stream)}
|
||||
|
@ -199,25 +204,18 @@ export default class DashboardCard extends Component {
|
|||
screenReaderLabel={screenReaderLabel}
|
||||
key={link.path}
|
||||
/>
|
||||
);
|
||||
)
|
||||
}
|
||||
return null;
|
||||
});
|
||||
return null
|
||||
})
|
||||
}
|
||||
|
||||
renderHeaderHero () {
|
||||
const {
|
||||
image,
|
||||
backgroundColor,
|
||||
hideColorOverlays
|
||||
} = this.props;
|
||||
renderHeaderHero() {
|
||||
const {image, backgroundColor, hideColorOverlays} = this.props
|
||||
|
||||
if (image) {
|
||||
return (
|
||||
<div
|
||||
className="ic-DashboardCard__header_image"
|
||||
style={{backgroundImage: `url(${image})`}}
|
||||
>
|
||||
<div className="ic-DashboardCard__header_image" style={{backgroundImage: `url(${image})`}}>
|
||||
<div
|
||||
className="ic-DashboardCard__header_hero"
|
||||
style={{backgroundColor, opacity: hideColorOverlays ? 0 : 0.6}}
|
||||
|
@ -225,7 +223,7 @@ export default class DashboardCard extends Component {
|
|||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -235,17 +233,13 @@ export default class DashboardCard extends Component {
|
|||
onClick={this.headerClick}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
renderHeaderButton () {
|
||||
const {
|
||||
backgroundColor,
|
||||
hideColorOverlays
|
||||
} = this.props;
|
||||
renderHeaderButton() {
|
||||
const {backgroundColor, hideColorOverlays} = this.props
|
||||
|
||||
const reorderingProps = this.props.reorderingEnabled && {
|
||||
reorderingEnabled: this.props.reorderingEnabled,
|
||||
const reorderingProps = {
|
||||
handleMove: this.handleMove,
|
||||
currentPosition: this.getCardPosition(),
|
||||
lastPosition: this.props.totalCards - 1,
|
||||
|
@ -269,14 +263,15 @@ export default class DashboardCard extends Component {
|
|||
trigger={
|
||||
<button
|
||||
className="Button Button--icon-action-rev ic-DashboardCard__header-button"
|
||||
ref={(c) => { this.settingsToggle = c }}
|
||||
ref={c => {
|
||||
this.settingsToggle = c
|
||||
}}
|
||||
>
|
||||
<i className="icon-more" aria-hidden="true" />
|
||||
<span className="screenreader-only">
|
||||
{ this.props.reorderingEnabled
|
||||
? I18n.t('Choose a color or course nickname or move course card for %{course}', { course: nickname })
|
||||
: I18n.t('Choose a color or course nickname for %{course}', { course: nickname })
|
||||
}
|
||||
{I18n.t('Choose a color or course nickname or move course card for %{course}', {
|
||||
course: nickname
|
||||
})}
|
||||
</span>
|
||||
</button>
|
||||
}
|
||||
|
@ -285,26 +280,31 @@ export default class DashboardCard extends Component {
|
|||
)
|
||||
}
|
||||
|
||||
render () {
|
||||
render() {
|
||||
const dashboardCard = (
|
||||
<div
|
||||
className="ic-DashboardCard"
|
||||
ref={(c) => { this.cardDiv = c }}
|
||||
style={{ opacity: (this.props.reorderingEnabled && this.props.isDragging) ? 0 : 1 }}
|
||||
ref={c => {
|
||||
this.cardDiv = c
|
||||
}}
|
||||
style={{opacity: this.props.isDragging ? 0 : 1}}
|
||||
aria-label={this.props.originalName}
|
||||
>
|
||||
<div className="ic-DashboardCard__header">
|
||||
<span className="screenreader-only">
|
||||
{
|
||||
this.props.image ?
|
||||
I18n.t('Course image for %{course}', {course: this.state.nicknameInfo.nickname})
|
||||
: I18n.t('Course card color region for %{course}', {course: this.state.nicknameInfo.nickname})
|
||||
}
|
||||
{this.props.image
|
||||
? I18n.t('Course image for %{course}', {course: this.state.nicknameInfo.nickname})
|
||||
: I18n.t('Course card color region for %{course}', {
|
||||
course: this.state.nicknameInfo.nickname
|
||||
})}
|
||||
</span>
|
||||
{this.renderHeaderHero()}
|
||||
<a href={this.props.href} className="ic-DashboardCard__link">
|
||||
<div className="ic-DashboardCard__header_content">
|
||||
<h2 className="ic-DashboardCard__header-title ellipsis" title={this.props.originalName}>
|
||||
<h2
|
||||
className="ic-DashboardCard__header-title ellipsis"
|
||||
title={this.props.originalName}
|
||||
>
|
||||
<span style={{color: this.props.backgroundColor}}>
|
||||
{this.state.nicknameInfo.nickname}
|
||||
</span>
|
||||
|
@ -315,30 +315,23 @@ export default class DashboardCard extends Component {
|
|||
>
|
||||
{this.props.courseCode}
|
||||
</div>
|
||||
<div
|
||||
className="ic-DashboardCard__header-term ellipsis"
|
||||
title={this.props.term}
|
||||
>
|
||||
{(this.props.term) ? this.props.term : null}
|
||||
<div className="ic-DashboardCard__header-term ellipsis" title={this.props.term}>
|
||||
{this.props.term ? this.props.term : null}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{ this.renderHeaderButton() }
|
||||
{this.renderHeaderButton()}
|
||||
</div>
|
||||
<nav
|
||||
className="ic-DashboardCard__action-container"
|
||||
aria-label={I18n.t('Actions for %{course}', {course: this.state.nicknameInfo.nickname})}
|
||||
>
|
||||
{ this.linksForCard() }
|
||||
{this.linksForCard()}
|
||||
</nav>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
|
||||
if (this.props.reorderingEnabled) {
|
||||
const { connectDragSource, connectDropTarget } = this.props;
|
||||
return connectDragSource(connectDropTarget(dashboardCard));
|
||||
}
|
||||
|
||||
return dashboardCard;
|
||||
const {connectDragSource, connectDropTarget} = this.props
|
||||
return connectDragSource(connectDropTarget(dashboardCard))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,105 +20,108 @@ import _ from 'underscore'
|
|||
import createStore from '../shared/helpers/createStore'
|
||||
import ContextColorer from 'compiled/contextColorer'
|
||||
|
||||
var DEFAULT_COLOR_OPTIONS = [
|
||||
'#008400',
|
||||
'#91349B',
|
||||
'#E1185C',
|
||||
'#D41E00',
|
||||
'#0076B8',
|
||||
'#626E7B',
|
||||
'#4D3D4D',
|
||||
'#254284',
|
||||
'#9F7217',
|
||||
'#177B63',
|
||||
'#324A4D',
|
||||
'#3C4F36'
|
||||
];
|
||||
const DEFAULT_COLOR_OPTIONS = [
|
||||
'#008400',
|
||||
'#91349B',
|
||||
'#E1185C',
|
||||
'#D41E00',
|
||||
'#0076B8',
|
||||
'#626E7B',
|
||||
'#4D3D4D',
|
||||
'#254284',
|
||||
'#9F7217',
|
||||
'#177B63',
|
||||
'#324A4D',
|
||||
'#3C4F36'
|
||||
]
|
||||
|
||||
var customColorsHash = ENV.PREFERENCES && ENV.PREFERENCES.custom_colors || {};
|
||||
const customColorsHash = (ENV.PREFERENCES && ENV.PREFERENCES.custom_colors) || {}
|
||||
|
||||
var DashboardCardBackgroundStore = createStore({
|
||||
courseColors: customColorsHash,
|
||||
usedDefaults: []
|
||||
})
|
||||
const DashboardCardBackgroundStore = createStore({
|
||||
courseColors: customColorsHash,
|
||||
usedDefaults: []
|
||||
})
|
||||
|
||||
// ===============
|
||||
// GET STATE
|
||||
// ===============
|
||||
// ===============
|
||||
// GET STATE
|
||||
// ===============
|
||||
|
||||
DashboardCardBackgroundStore.colorForCourse = function(courseAssetString){
|
||||
return this.getCourseColors()[courseAssetString];
|
||||
}
|
||||
DashboardCardBackgroundStore.colorForCourse = function(courseAssetString) {
|
||||
return this.getCourseColors()[courseAssetString]
|
||||
}
|
||||
|
||||
DashboardCardBackgroundStore.getCourseColors = function(){
|
||||
return this.getState()["courseColors"];
|
||||
}
|
||||
DashboardCardBackgroundStore.getCourseColors = function() {
|
||||
return this.getState().courseColors
|
||||
}
|
||||
|
||||
DashboardCardBackgroundStore.getUsedDefaults = function(){
|
||||
return this.getState()["usedDefaults"];
|
||||
}
|
||||
DashboardCardBackgroundStore.getUsedDefaults = function() {
|
||||
return this.getState().usedDefaults
|
||||
}
|
||||
|
||||
// ===============
|
||||
// SET STATE
|
||||
// ===============
|
||||
// ===============
|
||||
// SET STATE
|
||||
// ===============
|
||||
|
||||
DashboardCardBackgroundStore.setColorForCourse = function(courseAssetString, colorCode) {
|
||||
const originalColors = this.getCourseColors()
|
||||
const tmp = {}
|
||||
tmp[courseAssetString] = colorCode
|
||||
const newColors = _.extend({}, originalColors, tmp)
|
||||
this.setState({courseColors: newColors})
|
||||
}
|
||||
|
||||
DashboardCardBackgroundStore.setColorForCourse = function(courseAssetString, colorCode){
|
||||
var originalColors = this.getCourseColors();
|
||||
var tmp = {};
|
||||
tmp[courseAssetString] = colorCode
|
||||
var newColors = _.extend({}, originalColors, tmp);
|
||||
this.setState({courseColors: newColors});
|
||||
}
|
||||
DashboardCardBackgroundStore.setDefaultColors = function(allCourseAssetStrings) {
|
||||
const customCourseAssetStrings = _.keys(this.getCourseColors())
|
||||
const nonCustomStrings = _.difference(allCourseAssetStrings, customCourseAssetStrings)
|
||||
_.each(nonCustomStrings, courseString => this.setDefaultColor(courseString))
|
||||
}
|
||||
|
||||
DashboardCardBackgroundStore.setDefaultColors = function(allCourseAssetStrings){
|
||||
var customCourseAssetStrings = _.keys(this.getCourseColors());
|
||||
var nonCustomStrings = _.difference(allCourseAssetStrings, customCourseAssetStrings)
|
||||
_.each(nonCustomStrings, (courseString) =>
|
||||
this.setDefaultColor(courseString)
|
||||
);
|
||||
}
|
||||
DashboardCardBackgroundStore.setDefaultColor = function(courseAssetString) {
|
||||
const colorForCourse = _.sample(this.leastUsedDefaults())
|
||||
this.setColorForCourse(courseAssetString, colorForCourse)
|
||||
this.markColorUsed(colorForCourse)
|
||||
this.persistNewColor(courseAssetString, colorForCourse)
|
||||
}
|
||||
|
||||
DashboardCardBackgroundStore.setDefaultColor = function(courseAssetString){
|
||||
var colorForCourse = _.sample(this.leastUsedDefaults())
|
||||
this.setColorForCourse(courseAssetString, colorForCourse)
|
||||
this.markColorUsed(colorForCourse)
|
||||
this.persistNewColor(courseAssetString, colorForCourse)
|
||||
}
|
||||
// ===============
|
||||
// HELPERS
|
||||
// ===============
|
||||
|
||||
// ===============
|
||||
// HELPERS
|
||||
// ===============
|
||||
DashboardCardBackgroundStore.leastUsedDefaults = function() {
|
||||
const usedDefaults = this.getUsedDefaults()
|
||||
|
||||
DashboardCardBackgroundStore.leastUsedDefaults = function(){
|
||||
var usedDefaults = this.getUsedDefaults();
|
||||
const usedColorsByFrequency = _.groupBy(
|
||||
usedDefaults,
|
||||
x => _.filter(usedDefaults, y => x === y).length
|
||||
)
|
||||
|
||||
var usedColorsByFrequency = _.groupBy(usedDefaults, function(x) {
|
||||
return _.filter(usedDefaults, function(y) { return x === y }).length
|
||||
})
|
||||
const mostCommonColors = _.uniq(
|
||||
usedColorsByFrequency[
|
||||
_.chain(usedColorsByFrequency)
|
||||
.keys()
|
||||
.max()
|
||||
.value()
|
||||
]
|
||||
)
|
||||
|
||||
var mostCommonColors = _.uniq(usedColorsByFrequency[
|
||||
_.chain(usedColorsByFrequency).keys().max().value()
|
||||
])
|
||||
return _.difference(DEFAULT_COLOR_OPTIONS, mostCommonColors).length === 0
|
||||
? mostCommonColors
|
||||
: _.difference(DEFAULT_COLOR_OPTIONS, mostCommonColors)
|
||||
}
|
||||
|
||||
return _.difference(DEFAULT_COLOR_OPTIONS, mostCommonColors).length === 0 ?
|
||||
mostCommonColors :
|
||||
_.difference(DEFAULT_COLOR_OPTIONS, mostCommonColors)
|
||||
}
|
||||
// ===============
|
||||
// ACTIONS
|
||||
// ===============
|
||||
|
||||
// ===============
|
||||
// ACTIONS
|
||||
// ===============
|
||||
DashboardCardBackgroundStore.markColorUsed = function(usedColor) {
|
||||
const newUsedColors = this.getUsedDefaults().concat(usedColor)
|
||||
this.setState({usedDefaults: newUsedColors})
|
||||
}
|
||||
|
||||
DashboardCardBackgroundStore.markColorUsed = function(usedColor){
|
||||
var newUsedColors = this.getUsedDefaults().concat(usedColor);
|
||||
this.setState({usedDefaults: newUsedColors})
|
||||
}
|
||||
|
||||
DashboardCardBackgroundStore.persistNewColor = function(courseAssetString, colorForCourse){
|
||||
var tmp = {};
|
||||
tmp[courseAssetString] = colorForCourse;
|
||||
ContextColorer.persistContextColors(tmp, ENV.current_user_id);
|
||||
}
|
||||
DashboardCardBackgroundStore.persistNewColor = function(courseAssetString, colorForCourse) {
|
||||
const tmp = {}
|
||||
tmp[courseAssetString] = colorForCourse
|
||||
ContextColorer.persistContextColors(tmp, ENV.current_user_id)
|
||||
}
|
||||
|
||||
export default DashboardCardBackgroundStore
|
||||
|
|
|
@ -16,26 +16,23 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import $ from 'jquery'
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import DashboardCard from './DashboardCard'
|
||||
import DraggableDashboardCard from './DraggableDashboardCard'
|
||||
import DashboardCardBackgroundStore from './DashboardCardBackgroundStore'
|
||||
import MovementUtils from './MovementUtils'
|
||||
|
||||
export default class DashboardCardBox extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
courseCards: PropTypes.array,
|
||||
reorderingEnabled: PropTypes.bool,
|
||||
courseCards: PropTypes.arrayOf(PropTypes.object),
|
||||
hideColorOverlays: PropTypes.bool,
|
||||
connectDropTarget: PropTypes.func
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
courseCards: [],
|
||||
hideColorOverlays: false
|
||||
hideColorOverlays: false,
|
||||
connectDropTarget: el => el
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
|
@ -49,10 +46,6 @@ export default class DashboardCardBox extends React.Component {
|
|||
DashboardCardBackgroundStore.setDefaultColors(this.allCourseAssetStrings())
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
DashboardCardBackgroundStore.removeChangeListener(this.colorsUpdated)
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps) {
|
||||
DashboardCardBackgroundStore.setDefaultColors(this.allCourseAssetStrings())
|
||||
|
||||
|
@ -61,6 +54,10 @@ export default class DashboardCardBox extends React.Component {
|
|||
})
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
DashboardCardBackgroundStore.removeChangeListener(this.colorsUpdated)
|
||||
}
|
||||
|
||||
colorsUpdated = () => {
|
||||
this.forceUpdate()
|
||||
}
|
||||
|
@ -99,7 +96,7 @@ export default class DashboardCardBox extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const Component = this.props.reorderingEnabled ? DraggableDashboardCard : DashboardCard
|
||||
const Component = DraggableDashboardCard
|
||||
const cards = this.state.courseCards.map((card, index) => {
|
||||
const position =
|
||||
card.position != null ? card.position : this.getOriginalIndex.bind(this, card.assetString)
|
||||
|
@ -117,7 +114,6 @@ export default class DashboardCardBox extends React.Component {
|
|||
backgroundColor={this.colorForCard(card.assetString)}
|
||||
handleColorChange={this.handleColorChange.bind(this, card.assetString)}
|
||||
image={card.image}
|
||||
reorderingEnabled={this.props.reorderingEnabled}
|
||||
hideColorOverlays={this.props.hideColorOverlays}
|
||||
position={position}
|
||||
currentIndex={index}
|
||||
|
@ -129,12 +125,7 @@ export default class DashboardCardBox extends React.Component {
|
|||
|
||||
const dashboardCardBox = <div className="ic-DashboardCard__box">{cards}</div>
|
||||
|
||||
if (this.props.reorderingEnabled) {
|
||||
const {connectDropTarget} = this.props
|
||||
return connectDropTarget(dashboardCardBox)
|
||||
}
|
||||
|
||||
return dashboardCardBox
|
||||
const {connectDropTarget} = this.props
|
||||
return connectDropTarget(dashboardCardBox)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ export default class DashboardCardMenu extends React.Component {
|
|||
}).isRequired,
|
||||
trigger: PropTypes.node.isRequired,
|
||||
assetString: PropTypes.string.isRequired,
|
||||
reorderingEnabled: PropTypes.bool,
|
||||
popoverContentRef: PropTypes.func,
|
||||
handleShow: PropTypes.func,
|
||||
handleMove: PropTypes.func,
|
||||
|
@ -56,7 +55,6 @@ export default class DashboardCardMenu extends React.Component {
|
|||
}
|
||||
|
||||
static defaultProps = {
|
||||
reorderingEnabled: false,
|
||||
popoverContentRef: () => {},
|
||||
handleShow: () => {},
|
||||
handleMove: () => {},
|
||||
|
@ -92,7 +90,6 @@ export default class DashboardCardMenu extends React.Component {
|
|||
afterUpdateColor,
|
||||
currentColor,
|
||||
nicknameInfo,
|
||||
reorderingEnabled,
|
||||
handleMove,
|
||||
handleShow,
|
||||
popoverContentRef,
|
||||
|
@ -125,7 +122,7 @@ export default class DashboardCardMenu extends React.Component {
|
|||
</div>
|
||||
)
|
||||
|
||||
const movementMenu = reorderingEnabled ? (
|
||||
const movementMenu = (
|
||||
<DashboardCardMovementMenu
|
||||
ref={c => (this._movementMenu = c)}
|
||||
cardTitle={nicknameInfo.nickname}
|
||||
|
@ -136,12 +133,12 @@ export default class DashboardCardMenu extends React.Component {
|
|||
handleMove={handleMove}
|
||||
onMenuSelect={this.handleMovementMenuSelect}
|
||||
/>
|
||||
) : null
|
||||
)
|
||||
|
||||
const menuStyles = {
|
||||
width: 190,
|
||||
height: reorderingEnabled ? 310 : 262,
|
||||
paddingTop: reorderingEnabled ? 0 : 6
|
||||
height: 310,
|
||||
paddingTop: 0
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -151,9 +148,7 @@ export default class DashboardCardMenu extends React.Component {
|
|||
onToggle={this.handleMenuToggle}
|
||||
shouldContainFocus
|
||||
shouldReturnFocus
|
||||
defaultFocusElement={() =>
|
||||
reorderingEnabled ? this._colorTab : document.getElementById('NicknameInput')
|
||||
}
|
||||
defaultFocusElement={() => this._colorTab}
|
||||
onShow={handleShow}
|
||||
contentRef={popoverContentRef}
|
||||
>
|
||||
|
@ -167,7 +162,7 @@ export default class DashboardCardMenu extends React.Component {
|
|||
{I18n.t('Close')}
|
||||
</CloseButton>
|
||||
<div style={menuStyles}>
|
||||
{reorderingEnabled ? (
|
||||
{(
|
||||
<div>
|
||||
<TabList
|
||||
ref={c => (this._tabList = c)}
|
||||
|
@ -187,8 +182,6 @@ export default class DashboardCardMenu extends React.Component {
|
|||
</TabPanel>
|
||||
</TabList>
|
||||
</div>
|
||||
) : (
|
||||
<div className="DashboardCardMenu">{colorPicker}</div>
|
||||
)}
|
||||
</div>
|
||||
</PopoverContent>
|
||||
|
|
|
@ -16,51 +16,52 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { DropTarget, DragSource } from 'react-dnd'
|
||||
import {DropTarget, DragSource} from 'react-dnd'
|
||||
import compose from '../shared/helpers/compose'
|
||||
import ItemTypes from './Types'
|
||||
import DashboardCard from './DashboardCard'
|
||||
const cardSource = {
|
||||
beginDrag(props) {
|
||||
return {
|
||||
assetString: props.assetString,
|
||||
originalIndex: props.currentIndex
|
||||
};
|
||||
},
|
||||
isDragging(props, monitor) {
|
||||
return monitor.getItem().assetString === props.assetString;
|
||||
},
|
||||
endDrag(props, monitor) {
|
||||
const { assetString: draggedAssetString } = monitor.getItem();
|
||||
if (!monitor.didDrop()) {
|
||||
props.moveCard(draggedAssetString, props.position);
|
||||
}
|
||||
// TODO: Call something to actually move things to the right positions on the server
|
||||
}
|
||||
};
|
||||
|
||||
const cardTarget = {
|
||||
canDrop() {
|
||||
return false;
|
||||
},
|
||||
hover(props, monitor) {
|
||||
const { assetString: draggedAssetString } = monitor.getItem();
|
||||
const { assetString: overAssetString } = props;
|
||||
if (draggedAssetString !== overAssetString) {
|
||||
const { currentIndex: overIndex } = props;
|
||||
props.moveCard(draggedAssetString, overIndex);
|
||||
}
|
||||
const cardSource = {
|
||||
beginDrag(props) {
|
||||
return {
|
||||
assetString: props.assetString,
|
||||
originalIndex: props.currentIndex
|
||||
}
|
||||
};
|
||||
},
|
||||
isDragging(props, monitor) {
|
||||
return monitor.getItem().assetString === props.assetString
|
||||
},
|
||||
endDrag(props, monitor) {
|
||||
const {assetString: draggedAssetString} = monitor.getItem()
|
||||
if (!monitor.didDrop()) {
|
||||
props.moveCard(draggedAssetString, props.position)
|
||||
}
|
||||
// TODO: Call something to actually move things to the right positions on the server
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable new-cap */
|
||||
const cardTarget = {
|
||||
canDrop() {
|
||||
return false
|
||||
},
|
||||
hover(props, monitor) {
|
||||
const {assetString: draggedAssetString} = monitor.getItem()
|
||||
const {assetString: overAssetString} = props
|
||||
if (draggedAssetString !== overAssetString) {
|
||||
const {currentIndex: overIndex} = props
|
||||
props.moveCard(draggedAssetString, overIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable new-cap */
|
||||
export default compose(
|
||||
DropTarget(ItemTypes.CARD, cardTarget, connect => ({
|
||||
connectDropTarget: connect.dropTarget()
|
||||
})),
|
||||
DragSource(ItemTypes.CARD, cardSource, (connect, monitor) => ({
|
||||
connectDragSource: connect.dragSource(),
|
||||
isDragging: monitor.isDragging()
|
||||
}))
|
||||
)(DashboardCard);
|
||||
/* eslint-enable new-cap */
|
||||
DropTarget(ItemTypes.CARD, cardTarget, connect => ({
|
||||
connectDropTarget: connect.dropTarget()
|
||||
})),
|
||||
DragSource(ItemTypes.CARD, cardSource, (connect, monitor) => ({
|
||||
connectDragSource: connect.dragSource(),
|
||||
isDragging: monitor.isDragging()
|
||||
}))
|
||||
)(DashboardCard)
|
||||
/* eslint-enable new-cap */
|
||||
|
|
|
@ -16,24 +16,24 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { DragDropContext, DropTarget } from 'react-dnd'
|
||||
import {DragDropContext, DropTarget} from 'react-dnd'
|
||||
import ReactDnDHTML5Backend from 'react-dnd-html5-backend'
|
||||
import compose from '../shared/helpers/compose'
|
||||
import ItemTypes from './Types'
|
||||
import DashboardCardBox from './DashboardCardBox'
|
||||
const cardTarget = {
|
||||
drop () {}
|
||||
};
|
||||
|
||||
const getDroppableDashboardCardBox = (backend = ReactDnDHTML5Backend) => (
|
||||
/* eslint-disable new-cap */
|
||||
compose(
|
||||
DragDropContext(backend),
|
||||
DropTarget(ItemTypes.CARD, cardTarget, connect => ({
|
||||
connectDropTarget: connect.dropTarget()
|
||||
}))
|
||||
)(DashboardCardBox)
|
||||
/* eslint-enable new-cap */
|
||||
);
|
||||
const cardTarget = {
|
||||
drop() {}
|
||||
}
|
||||
|
||||
const getDroppableDashboardCardBox = (backend = ReactDnDHTML5Backend) =>
|
||||
/* eslint-disable new-cap */
|
||||
compose(
|
||||
DragDropContext(backend),
|
||||
DropTarget(ItemTypes.CARD, cardTarget, connect => ({
|
||||
connectDropTarget: connect.dropTarget()
|
||||
}))
|
||||
)(DashboardCardBox)
|
||||
/* eslint-enable new-cap */
|
||||
|
||||
export default getDroppableDashboardCardBox
|
||||
|
|
|
@ -41,7 +41,7 @@ class CourseForMenuPresenter
|
|||
enrollmentType: course.primary_enrollment_type,
|
||||
id: course.id,
|
||||
image: course.feature_enabled?(:course_card_images) ? course.image : nil,
|
||||
position: @context&.feature_enabled?(:dashcard_reordering) ? @user.dashboard_positions[course.asset_string] : nil,
|
||||
position: @user.dashboard_positions[course.asset_string] || nil,
|
||||
}.tap do |hash|
|
||||
if @opts[:tabs]
|
||||
tabs = course.tabs_available(@user, {
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
|
||||
css_bundle :dashboard_card
|
||||
|
||||
js_env(:DASHBOARD_REORDERING_ENABLED => @domain_root_account.feature_enabled?(:dashcard_reordering))
|
||||
|
||||
default_number_of_fake_dashcards_to_show = 5
|
||||
|
||||
number_of_fake_cards_to_show =
|
||||
|
|
|
@ -450,16 +450,6 @@ END
|
|||
root_opt_in: true,
|
||||
beta: true
|
||||
},
|
||||
'dashcard_reordering' =>
|
||||
{
|
||||
display_name: -> { I18n.t('Allow Reorder Dashboard Cards') },
|
||||
description: -> { I18n.t('Allow dashboard cards to be reordered for each user.') },
|
||||
applies_to: 'RootAccount',
|
||||
state: 'hidden',
|
||||
beta: true,
|
||||
development: true,
|
||||
root_opt_in: false
|
||||
},
|
||||
'responsive_layout' =>
|
||||
{
|
||||
display_name: -> { I18n.t('Responsive Layout') },
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import TestUtils from 'react-dom/test-utils'
|
||||
import DashboardCardBox from 'jsx/dashboard_card/DashboardCardBox'
|
||||
import ReactDndTestBackend from 'react-dnd-test-backend'
|
||||
import getDroppableDashboardCardBox from 'jsx/dashboard_card/getDroppableDashboardCardBox'
|
||||
import CourseActivitySummaryStore from 'jsx/dashboard_card/CourseActivitySummaryStore'
|
||||
|
||||
QUnit.module('DashboardCardBox', {
|
||||
|
@ -45,7 +46,8 @@ QUnit.module('DashboardCardBox', {
|
|||
})
|
||||
|
||||
test('should render div.ic-DashboardCard per provided courseCard', function() {
|
||||
const CardBox = <DashboardCardBox courseCards={this.courseCards} />
|
||||
const Box = getDroppableDashboardCardBox(ReactDndTestBackend)
|
||||
const CardBox = <Box connectDropTarget={el => el} courseCards={this.courseCards} />
|
||||
this.component = TestUtils.renderIntoDocument(CardBox)
|
||||
const $html = $(ReactDOM.findDOMNode(this.component))
|
||||
equal($html.children('div.ic-DashboardCard').length, this.courseCards.length)
|
||||
|
|
|
@ -47,6 +47,8 @@ QUnit.module('DashboardCard', {
|
|||
id: '1',
|
||||
backgroundColor: '#EF4437',
|
||||
image: null,
|
||||
connectDragSource: c => c,
|
||||
connectDropTarget: c => c
|
||||
}
|
||||
return sandbox.stub(CourseActivitySummaryStore, 'getStateForCourse').returns({})
|
||||
},
|
||||
|
|
|
@ -74,10 +74,9 @@ describe DashboardHelper do
|
|||
end
|
||||
|
||||
describe "map_courses_for_menu" do
|
||||
context "with Dashcard Reordering feature enabled" do
|
||||
context "Dashcard Reordering" do
|
||||
before(:each) do
|
||||
@account = Account.default
|
||||
@account.enable_feature! :dashcard_reordering
|
||||
@domain_root_account = @account
|
||||
end
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ const defaultProps = () => ({
|
|||
})
|
||||
|
||||
const defaultMovementMenuProps = () => ({
|
||||
reorderingEnabled: true,
|
||||
menuOptions: {
|
||||
canMoveLeft: false,
|
||||
canMoveRight: true,
|
||||
|
@ -49,31 +48,7 @@ const getTabWithText = (text) => {
|
|||
return tabs.filter(tab => tab.textContent.trim() === text)[0]
|
||||
}
|
||||
|
||||
QUnit.module('DashboardCardMenu - reordering disabled', {
|
||||
setup () {
|
||||
this.wrapper = mount(<DashboardCardMenu {...defaultProps()} />)
|
||||
},
|
||||
|
||||
teardown () {
|
||||
this.wrapper.unmount()
|
||||
}
|
||||
})
|
||||
|
||||
test('it should render with only a color picker if reordering is not enabled', function (assert) {
|
||||
const done = assert.async()
|
||||
|
||||
const handleShow = () => {
|
||||
ok(this.wrapper.instance()._colorPicker)
|
||||
notOk(this.wrapper.instance()._tabList)
|
||||
done()
|
||||
}
|
||||
|
||||
this.wrapper.setProps({ handleShow }, () => {
|
||||
this.wrapper.find('button').simulate('click')
|
||||
})
|
||||
})
|
||||
|
||||
QUnit.module('DashboardCardMenu - reordering enabled', {
|
||||
QUnit.module('DashboardCardMenu - reordering', {
|
||||
setup () {
|
||||
this.wrapper = mount(<DashboardCardMenu {...defaultProps()} {...defaultMovementMenuProps()} />)
|
||||
},
|
||||
|
@ -83,7 +58,7 @@ QUnit.module('DashboardCardMenu - reordering enabled', {
|
|||
}
|
||||
})
|
||||
|
||||
test('it should render a tabList with colorpicker and movement menu with reordering enabled', function (assert) {
|
||||
test('it should render a tabList with colorpicker and movement menu', function (assert) {
|
||||
const done = assert.async()
|
||||
|
||||
const handleShow = () => {
|
||||
|
|
|
@ -16,98 +16,87 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import TestUtils from 'react-dom/test-utils';
|
||||
import { DragDropContext } from 'react-dnd';
|
||||
import ReactDndTestBackend from 'react-dnd-test-backend';
|
||||
import DraggableDashboardCard from 'jsx/dashboard_card/DraggableDashboardCard';
|
||||
import getDroppableDashboardCardBox from 'jsx/dashboard_card/getDroppableDashboardCardBox';
|
||||
import DashboardCardBox from 'jsx/dashboard_card/DashboardCardBox';
|
||||
import DashboardCard from 'jsx/dashboard_card/DashboardCard';
|
||||
import DashboardCardMovementMenu from 'jsx/dashboard_card/DashboardCardMovementMenu';
|
||||
import fakeENV from 'helpers/fakeENV';
|
||||
import React from 'react'
|
||||
import TestUtils from 'react-dom/test-utils'
|
||||
import ReactDndTestBackend from 'react-dnd-test-backend'
|
||||
import DraggableDashboardCard from 'jsx/dashboard_card/DraggableDashboardCard'
|
||||
import getDroppableDashboardCardBox from 'jsx/dashboard_card/getDroppableDashboardCardBox'
|
||||
import fakeENV from 'helpers/fakeENV'
|
||||
|
||||
let cards;
|
||||
let fakeServer;
|
||||
let cards
|
||||
let fakeServer
|
||||
|
||||
QUnit.module('DashboardCard Reordering', {
|
||||
setup () {
|
||||
fakeENV.setup({
|
||||
DASHBOARD_REORDERING_ENABLED: true
|
||||
});
|
||||
|
||||
cards = [{
|
||||
QUnit.module('DashboardCard Reordering', {
|
||||
setup() {
|
||||
cards = [
|
||||
{
|
||||
id: 1,
|
||||
assetString: 'course_1',
|
||||
position: 0,
|
||||
originalName: 'Intro to Dashcards 1',
|
||||
shortName: 'Dash 101'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
assetString: 'course_2',
|
||||
position: 1,
|
||||
originalName: 'Intermediate Dashcarding',
|
||||
shortName: 'Dash 201'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
assetString: 'course_3',
|
||||
originalName: 'Advanced Dashcards',
|
||||
shortName: 'Dash 301'
|
||||
}];
|
||||
}
|
||||
]
|
||||
|
||||
fakeServer = sinon.fakeServer.create();
|
||||
},
|
||||
teardown () {
|
||||
fakeENV.teardown();
|
||||
cards = null;
|
||||
fakeServer.restore();
|
||||
}
|
||||
});
|
||||
fakeServer = sinon.fakeServer.create()
|
||||
},
|
||||
teardown() {
|
||||
fakeENV.teardown()
|
||||
cards = null
|
||||
fakeServer.restore()
|
||||
}
|
||||
})
|
||||
|
||||
test('it renders', () => {
|
||||
const Box = getDroppableDashboardCardBox()
|
||||
const root = TestUtils.renderIntoDocument(
|
||||
<Box reorderingEnabled courseCards={cards} />
|
||||
);
|
||||
ok(root);
|
||||
});
|
||||
test('it renders', () => {
|
||||
const Box = getDroppableDashboardCardBox()
|
||||
const root = TestUtils.renderIntoDocument(<Box courseCards={cards} />)
|
||||
ok(root)
|
||||
})
|
||||
|
||||
test('cards have opacity of 0 while moving', () => {
|
||||
const Card = DraggableDashboardCard.DecoratedComponent;
|
||||
const card = TestUtils.renderIntoDocument(
|
||||
<Card
|
||||
{...cards[0]}
|
||||
connectDragSource={el => el}
|
||||
connectDropTarget={el => el}
|
||||
isDragging
|
||||
reorderingEnabled
|
||||
/>
|
||||
);
|
||||
const div = TestUtils.findRenderedDOMComponentWithClass(card, 'ic-DashboardCard')
|
||||
equal(div.style.opacity, 0);
|
||||
});
|
||||
test('cards have opacity of 0 while moving', () => {
|
||||
const Card = DraggableDashboardCard.DecoratedComponent
|
||||
const card = TestUtils.renderIntoDocument(
|
||||
<Card {...cards[0]} connectDragSource={el => el} connectDropTarget={el => el} isDragging />
|
||||
)
|
||||
const div = TestUtils.findRenderedDOMComponentWithClass(card, 'ic-DashboardCard')
|
||||
equal(div.style.opacity, 0)
|
||||
})
|
||||
|
||||
test('moving a card adjusts the position property', () => {
|
||||
const Box = getDroppableDashboardCardBox(ReactDndTestBackend);
|
||||
const root = TestUtils.renderIntoDocument(
|
||||
<Box
|
||||
reorderingEnabled
|
||||
courseCards={cards}
|
||||
connectDropTarget={el => el}
|
||||
/>
|
||||
);
|
||||
test('moving a card adjusts the position property', () => {
|
||||
const Box = getDroppableDashboardCardBox(ReactDndTestBackend)
|
||||
const root = TestUtils.renderIntoDocument(
|
||||
<Box courseCards={cards} connectDropTarget={el => el} />
|
||||
)
|
||||
|
||||
const backend = root.getManager().getBackend();
|
||||
const renderedCardComponents = TestUtils.scryRenderedComponentsWithType(root, DraggableDashboardCard);
|
||||
const sourceHandlerId = renderedCardComponents[0].getDecoratedComponentInstance().getHandlerId();
|
||||
const targetHandlerId = renderedCardComponents[1].getHandlerId();
|
||||
const backend = root.getManager().getBackend()
|
||||
const renderedCardComponents = TestUtils.scryRenderedComponentsWithType(
|
||||
root,
|
||||
DraggableDashboardCard
|
||||
)
|
||||
const sourceHandlerId = renderedCardComponents[0].getDecoratedComponentInstance().getHandlerId()
|
||||
const targetHandlerId = renderedCardComponents[1].getHandlerId()
|
||||
|
||||
backend.simulateBeginDrag([sourceHandlerId]);
|
||||
backend.simulateHover([targetHandlerId]);
|
||||
backend.simulateDrop();
|
||||
backend.simulateBeginDrag([sourceHandlerId])
|
||||
backend.simulateHover([targetHandlerId])
|
||||
backend.simulateDrop()
|
||||
|
||||
const renderedAfterDragNDrop = TestUtils.scryRenderedDOMComponentsWithClass(root, 'ic-DashboardCard');
|
||||
equal(renderedAfterDragNDrop[0].getAttribute('aria-label'), 'Intermediate Dashcarding');
|
||||
equal(renderedAfterDragNDrop[1].getAttribute('aria-label'), 'Intro to Dashcards 1');
|
||||
});
|
||||
const renderedAfterDragNDrop = TestUtils.scryRenderedDOMComponentsWithClass(
|
||||
root,
|
||||
'ic-DashboardCard'
|
||||
)
|
||||
equal(renderedAfterDragNDrop[0].getAttribute('aria-label'), 'Intermediate Dashcarding')
|
||||
equal(renderedAfterDragNDrop[1].getAttribute('aria-label'), 'Intro to Dashcards 1')
|
||||
})
|
||||
|
|
|
@ -71,10 +71,9 @@ describe CourseForMenuPresenter do
|
|||
expect(h[:shortName]).to eq 'nickname'
|
||||
end
|
||||
|
||||
context 'with Dashcard Reordering feature enabled' do
|
||||
context 'Dashcard Reordering' do
|
||||
before(:each) do
|
||||
@account = Account.default
|
||||
@account.enable_feature! :dashcard_reordering
|
||||
end
|
||||
|
||||
it 'returns a position if one is set' do
|
||||
|
|
Loading…
Reference in New Issue