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

DTL (Test > Levelbuilder): 5e21bf4b #32501

Merged
merged 40 commits into from
Dec 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
52b0199
add eyes test for oceans landing page
Erin007 Dec 6, 2019
d369d2b
disallow behavior editing if there is a toolbox with no categories
ajpal Dec 12, 2019
7423544
standards toggle only shows for CSF courses
Erin007 Dec 16, 2019
78b4500
fix merge conflict - currentView and showStandardsToggle both in props
Erin007 Dec 16, 2019
06ab578
don't parse columns from records
ajpal Nov 27, 2019
0c91e12
Ensure 'id' is first
ajpal Nov 28, 2019
8e793c5
add columns parameter to addMissingColumns()
ajpal Dec 10, 2019
622035b
fix update/create record
ajpal Dec 10, 2019
114a293
fix test
ajpal Dec 17, 2019
88dae1d
Revert "Remove links to last year's tutorials on /dance"
molly-moen Dec 17, 2019
4edd0c3
hoc mode: change test environment to post-hoc
breville Dec 17, 2019
7ce39ea
Include created_at in serialized workshop
islemaster Dec 17, 2019
e5b7ec3
Render created_at date at bottom of workshop dashboard
islemaster Dec 17, 2019
e266825
Merge branch 'staging' into dec11-spritelab-behavior
ajpal Dec 18, 2019
52622a6
add comment
ajpal Dec 18, 2019
bc9f0ed
decrease whitespace
molly-moen Dec 18, 2019
462da24
Merge remote-tracking branch 'origin/staging' into revert-32198-remov…
molly-moen Dec 18, 2019
8b30cdd
Merge pull request #32433 from code-dot-org/dec16-parse-columns
ajpal Dec 18, 2019
e182f3f
Merge pull request #32395 from code-dot-org/dec11-spritelab-behavior
ajpal Dec 18, 2019
a102295
Merge pull request #32474 from code-dot-org/staging
deploy-code-org Dec 18, 2019
0a42169
fix merge conflict
Erin007 Dec 18, 2019
1967ba5
clarify SectionProgressTest names
Erin007 Dec 18, 2019
94163ee
Merge pull request #32471 from code-dot-org/revert-32198-remove-dance…
molly-moen Dec 18, 2019
cdd07b5
Merge pull request #32475 from code-dot-org/staging
deploy-code-org Dec 18, 2019
7c9412d
Merge pull request #32453 from code-dot-org/workshop-created-at
islemaster Dec 18, 2019
3adda3c
Merge pull request #32333 from code-dot-org/eyes-for-oceans
Erin007 Dec 18, 2019
e433845
Deflake ProxyHelperTest
islemaster Dec 18, 2019
a771f81
Dedupe teachers listed as both scholarship and non-scholarship in PD …
bencodeorg Dec 19, 2019
94ad0a4
Merge pull request #32478 from code-dot-org/dedupe-csp-csd-teachers-t…
bencodeorg Dec 19, 2019
be4e696
Merge pull request #32479 from code-dot-org/staging
deploy-code-org Dec 19, 2019
70971c8
Fix flaky TeacherAttendanceReportControllerTest
islemaster Dec 19, 2019
5d957d0
Merge pull request #32476 from code-dot-org/flaky-proxy-helper-test
islemaster Dec 19, 2019
09166dd
Merge pull request #32481 from code-dot-org/flaky-teacher-attendance-…
islemaster Dec 19, 2019
735db95
Go Beyond announcement for teacher homepage
islemaster Dec 18, 2019
e402f4c
Remove CSForGood announcement too
islemaster Dec 18, 2019
2fc95f3
Merge pull request #32430 from code-dot-org/standards-csf-only
Erin007 Dec 19, 2019
51e7b04
Merge pull request #32455 from code-dot-org/test-hoc-mode-to-post-hoc
breville Dec 19, 2019
2caf977
Merge pull request #32483 from code-dot-org/staging
deploy-code-org Dec 19, 2019
f4a16ca
Merge pull request #32458 from code-dot-org/go-beyond-announcement
islemaster Dec 19, 2019
5e21bf4
Merge pull request #32488 from code-dot-org/staging
deploy-code-org Dec 19, 2019
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
6 changes: 2 additions & 4 deletions apps/i18n/common/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -1378,10 +1378,8 @@
"soundLibrary": "Sound Library",
"soundName": "Sound Name",
"soundSearchPlaceholder": "Search for a sound...",
"specialAnnouncementHeadingHoc2019CsForGood": "The Hour of Code is coming",
"specialAnnouncementDescriptionHoc2019CsForGood": "Try one of the 100 NEW activities for the Hour of Code (Dec 9-15)! This year, encourage your students to think about ways of using CS for good. Sign up your class today.",
"specialAnnouncementHeadingHoc2019DanceParty": "Try the NEW Dance Party",
"specialAnnouncementDescriptionHoc2019DanceParty": "Have you tried the NEW Dance Party for Hour of Code 2019? It's got new backgrounds, new coding blocks, new music, and even a brand-new Dance Party character!",
"specialAnnouncementHeadingPostHoc2019": "Go beyond an Hour of Code",
"specialAnnouncementDescriptionPostHoc2019": "An hour is just the beginning. We offer comprehensive curriculum for grades K-12, professional learning programs including local workshops, and resources to help you and your school get started.",
"sprite": "sprite",
"stage": "Stage",
"stageExtras": "Lesson Extras",
Expand Down
9 changes: 1 addition & 8 deletions apps/src/applab/applab.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ import * as utils from '../utils';
import * as dropletConfig from './dropletConfig';
import {getDatasetInfo} from '../storage/dataBrowser/dataUtils';
import {initFirebaseStorage} from '../storage/firebaseStorage';
import {
getColumnsRef,
onColumnsChange,
addMissingColumns
} from '../storage/firebaseMetadata';
import {getColumnsRef, onColumnsChange} from '../storage/firebaseMetadata';
import {getProjectDatabase, getSharedDatabase} from '../storage/firebaseUtils';
import * as apiTimeoutList from '../lib/util/timeoutList';
import designMode from './designMode';
Expand Down Expand Up @@ -1393,9 +1389,6 @@ function onDataViewChange(view, oldTableName, newTableName) {
} else {
storageRef = projectStorageRef.child(`tables/${newTableName}/records`);
}
if (newTableType === tableType.PROJECT) {
addMissingColumns(newTableName);
}
onColumnsChange(
newTableType === tableType.PROJECT
? getProjectDatabase()
Expand Down
29 changes: 28 additions & 1 deletion apps/src/code-studio/pd/workshop_dashboard/workshop.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ export class Workshop extends React.Component {
'regional_partner_name',
'regional_partner_id',
'scholarship_workshop?',
'potential_organizers'
'potential_organizers',
'created_at'
])
});
})
Expand Down Expand Up @@ -903,6 +904,7 @@ export class Workshop extends React.Component {
{this.renderEndWorkshopPanel()}
{this.renderEnrollmentsPanel()}
{this.renderDetailsPanel()}
<MetadataFooter createdAt={this.state.workshop.created_at} />
</Grid>
);
}
Expand All @@ -911,3 +913,28 @@ export class Workshop extends React.Component {
export default connect(state => ({
permission: state.workshopDashboard.permission
}))(Workshop);

/**
* A small, right-aligned section at the end of the workshop dashboard showing
* metadata we want to be able to check occasionally, like the workshop created_at date.
* @param {string} createdAt - and ISO 8601 date string
* @returns {Component}
* @constructor
*/
const MetadataFooter = ({createdAt}) => (
<Row>
<Col sm={12}>
<div style={METADATA_FOOTER_STYLE}>
Workshop created {new Date(createdAt).toLocaleDateString('en-US')}.
</div>
</Col>
</Row>
);
MetadataFooter.propTypes = {
createdAt: PropTypes.string.isRequired // An ISO 8601 date string
};
const METADATA_FOOTER_STYLE = {
textAlign: 'right',
fontSize: 'smaller',
fontStyle: 'italic'
};
11 changes: 10 additions & 1 deletion apps/src/p5lab/spritelab/blocks.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* global dashboard */
/* global appOptions */

import {SVG_NS} from '@cdo/apps/constants';
import {getStore} from '@cdo/apps/redux';
Expand Down Expand Up @@ -377,7 +378,15 @@ export default {
.appendTitle(fieldLabel, 'VAR')
.appendTitle(Blockly.Msg.VARIABLES_GET_TAIL);

if (Blockly.useModalFunctionEditor) {
let allowBehaviorEditing = Blockly.useModalFunctionEditor;

// If there is a toolbox with no categories, disallow editing the behavior,
// because renaming the behavior can break things.
if (appOptions.level.toolbox && !Blockly.hasCategories) {
allowBehaviorEditing = false;
}

if (allowBehaviorEditing) {
var editLabel = new Blockly.FieldIcon(Blockly.Msg.FUNCTION_EDIT);
Blockly.bindEvent_(
editLabel.fieldGroup_,
Expand Down
14 changes: 3 additions & 11 deletions apps/src/storage/dataBrowser/DataTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ const INITIAL_STATE = {

class DataTable extends React.Component {
static propTypes = {
getColumnNames: PropTypes.func.isRequired,
readOnly: PropTypes.bool,
rowsPerPage: PropTypes.number,
// from redux state
Expand Down Expand Up @@ -162,12 +161,8 @@ class DataTable extends React.Component {
};

getNextColumnName() {
const names = this.props.getColumnNames(
this.props.tableRecords,
this.props.tableColumns
);
let i = names.length;
while (names.includes(`column${i}`)) {
let i = this.props.tableColumns.length;
while (this.props.tableColumns.includes(`column${i}`)) {
i++;
}
return `column${i}`;
Expand Down Expand Up @@ -211,10 +206,7 @@ class DataTable extends React.Component {
}

render() {
let columnNames = this.props.getColumnNames(
this.props.tableRecords,
this.props.tableColumns
);
let columnNames = [...this.props.tableColumns];
let editingColumn = this.state.editingColumn;

let rowsPerPage = this.props.rowsPerPage || MAX_ROWS_PER_PAGE;
Expand Down
27 changes: 1 addition & 26 deletions apps/src/storage/dataBrowser/DataTableView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {changeView, showWarning, tableType} from '../redux/data';
import * as dataStyles from './dataStyles';
import color from '../../util/color';
import {connect} from 'react-redux';
import {getColumnNamesFromRecords} from '../firebaseMetadata';
import experiments from '../../util/experiments';

const MIN_TABLE_WIDTH = 600;
Expand Down Expand Up @@ -91,23 +90,6 @@ class DataTableView extends React.Component {
}
}

/**
* @param {Array} records Array of JSON-encoded records.
* @param {string} columns Array of column names.
*/
getColumnNames(records, columns) {
// Make sure 'id' is the first column.
const columnNames = getColumnNamesFromRecords(records);

columns.forEach(columnName => {
if (columnNames.indexOf(columnName) === -1) {
columnNames.push(columnName);
}
});

return columnNames;
}

importCsv = (csvData, onComplete) => {
FirebaseStorage.importCsv(
this.props.tableName,
Expand Down Expand Up @@ -160,10 +142,6 @@ class DataTableView extends React.Component {
}

render() {
let columnNames = this.getColumnNames(
this.props.tableRecords,
this.props.tableColumns
);
const visible = DataView.TABLE === this.props.view;
const containerStyle = [
styles.container,
Expand Down Expand Up @@ -204,17 +182,14 @@ class DataTableView extends React.Component {
</span>
</div>
<TableControls
columns={columnNames}
clearTable={this.clearTable}
importCsv={this.importCsv}
exportCsv={this.exportCsv}
tableName={this.props.tableName}
readOnly={readOnly}
/>
<div style={debugDataStyle}>{this.getTableJson()}</div>
{!this.state.showDebugView && (
<DataTable getColumnNames={this.getColumnNames} readOnly={readOnly} />
)}
{!this.state.showDebugView && <DataTable readOnly={readOnly} />}
</div>
);
}
Expand Down
9 changes: 1 addition & 8 deletions apps/src/storage/dataBrowser/PreviewModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {hidePreview} from '../redux/data';
import {getDatasetInfo} from './dataUtils';
import BaseDialog from '@cdo/apps/templates/BaseDialog.jsx';
import DataTable from './DataTable';
import {parseColumnsFromRecords} from '../firebaseMetadata';
import msg from '@cdo/locale';

class PreviewModal extends React.Component {
Expand All @@ -32,13 +31,7 @@ class PreviewModal extends React.Component {
<h1>{this.props.tableName}</h1>
<p>{datasetInfo.description}</p>
<div style={{overflow: 'scroll', maxHeight: '70%'}}>
<DataTable
getColumnNames={(records, columns) =>
parseColumnsFromRecords(records)
}
readOnly
rowsPerPage={100}
/>
<DataTable readOnly rowsPerPage={100} />
</div>
<button type="button" onClick={() => this.importTable(datasetInfo)}>
{msg.import()}
Expand Down
44 changes: 14 additions & 30 deletions apps/src/storage/firebaseMetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,18 @@ export function getColumnRefByName(tableName, columnName) {
});
}

// TODO: De-dupe this function with getColumnNamesFromRecords() below
export function parseColumnsFromRecords(records) {
const columnNames = [];
Object.keys(records).forEach(id => {
const record = JSON.parse(records[id]);
Object.keys(record).forEach(column => {
if (columnNames.indexOf(column) === -1) {
columnNames.push(column);
}
});
});
return columnNames;
}

export function getColumnNamesFromRecords(records) {
const columnNames = ['id'];
const columnNames = [];
Object.keys(records).forEach(id => {
const record = JSON.parse(records[id]);
Object.keys(record).forEach(columnName => {
if (columnNames.indexOf(columnName) === -1) {
columnNames.push(columnName);
if (columnName === 'id') {
// Make sure 'id' is first column
columnNames.unshift(columnName);
} else {
columnNames.push(columnName);
}
}
});
});
Expand Down Expand Up @@ -118,23 +109,16 @@ export function onColumnsChange(database, tableName, callback) {
/**
*
* @param {string} tableName
* @param {Array.<string>} existingColumnNames
* @param {Array.<string>} columns
* @returns {*}
*/
export function addMissingColumns(tableName) {
export function addMissingColumns(tableName, columns) {
return getColumnNamesSnapshot(tableName).then(existingColumnNames => {
const recordsRef = getProjectDatabase().child(
`storage/tables/${tableName}/records`
);
return recordsRef.once('value').then(snapshot => {
const recordsData = snapshot.val() || {};
getColumnNamesFromRecords(recordsData).forEach(columnName => {
if (!existingColumnNames.includes(columnName)) {
getColumnsRef(getProjectDatabase(), tableName)
.push()
.set({columnName});
}
});
let columnsRef = getColumnsRef(getProjectDatabase(), tableName);
columns.forEach(columnName => {
if (!existingColumnNames.includes(columnName)) {
columnsRef.push().set({columnName});
}
});
});
}
27 changes: 25 additions & 2 deletions apps/src/storage/firebaseStorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ import {
deleteColumnName,
renameColumnName,
addMissingColumns,
getColumnsRef
getColumnsRef,
getColumnNamesFromRecords
} from './firebaseMetadata';
import {tableType} from './redux/data';
import {WarningType} from './constants';
Expand Down Expand Up @@ -220,6 +221,12 @@ FirebaseStorage.createRecord = function(tableName, record, onSuccess, onError) {
);
return recordRef.set(JSON.stringify(record));
})
.then(() =>
addMissingColumns(
tableName,
getColumnNamesFromRecords([JSON.stringify(record)])
)
)
.then(() => onSuccess(record), onError);
};

Expand Down Expand Up @@ -377,6 +384,12 @@ FirebaseStorage.updateRecord = function(
incrementRateLimitCounters()
.then(() => updateTableCounters(tableName, 0))
.then(() => recordRef.set(recordJson))
.then(() =>
addMissingColumns(
tableName,
getColumnNamesFromRecords([recordJson])
)
)
.then(() => onComplete(record, true), onError);
}
});
Expand Down Expand Up @@ -546,7 +559,11 @@ FirebaseStorage.copyStaticTable = function(tableName, onSuccess, onError) {
})
.then(snapshot => {
getRecordsRef(tableName).set(snapshot.val());
return snapshot;
})
.then(snapshot =>
addMissingColumns(tableName, getColumnNamesFromRecords(snapshot.val()))
)
.then(onSuccess, onError);
};

Expand Down Expand Up @@ -605,6 +622,7 @@ FirebaseStorage.createTable = function(tableName, onSuccess, onError) {
return Promise.resolve();
});
})
.then(() => addColumnName(tableName, 'id'))
.then(onSuccess, onError);
};

Expand Down Expand Up @@ -1007,7 +1025,12 @@ function overwriteTableData(tableName, recordsData) {
rowCount: count
});
})
.then(() => addMissingColumns(tableName));
.then(() =>
addMissingColumns(
tableName,
getColumnNamesFromRecords(Object.values(recordsData))
)
);
}

FirebaseStorage.importCsv = function(
Expand Down