Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into 186610168-manual-po…
Browse files Browse the repository at this point in the history
…ints
  • Loading branch information
bgoldowsky committed Mar 7, 2024
2 parents 31af0a9 + 41128d7 commit 5b0b81c
Show file tree
Hide file tree
Showing 74 changed files with 1,376 additions and 882 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-regression.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
# If we run out cypress test runs then we temporarily expand the timeout to 4hrs until cypress cloud is available
# again
# timeout-minutes: 240
container: cypress/browsers:node16.14.2-slim-chrome103-ff102
container: cypress/browsers:node-20.11.0-chrome-121.0.6167.184-1-ff-123.0-edge-121.0.2277.128-1
strategy:
# when one test fails, DO NOT cancel the other
# containers, because this will kill Cypress processes
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
cypress:
runs-on: ubuntu-latest
container: cypress/browsers:node16.14.2-slim-chrome103-ff102
container: cypress/browsers:node-20.11.0-chrome-121.0.6167.184-1-ff-123.0-edge-121.0.2277.128-1
strategy:
# when one test fails, DO NOT cancel the other
# containers, because this will kill Cypress processes
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/manual-regression.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ on:
jobs:
all-tests:
runs-on: ubuntu-latest
container: cypress/browsers:node16.14.2-slim-chrome103-ff102
container: cypress/browsers:node-20.11.0-chrome-121.0.6167.184-1-ff-123.0-edge-121.0.2277.128-1
if: ${{ github.event.inputs.test == 'all' }}
strategy:
# when one test fails, DO NOT cancel the other
Expand All @@ -84,7 +84,7 @@ jobs:
- name: Set the browser
env:
DEFAULT_BROWSER: chrome
run: |
run: |
echo "BROWSER=${{ github.event.inputs.browser || env.DEFAULT_BROWSER }}" >> $GITHUB_ENV
echo "Tests to run: ${{ github.event.inputs.test }}"
- uses: cypress-io/github-action@v4
Expand Down Expand Up @@ -122,7 +122,7 @@ jobs:

single-test:
runs-on: ubuntu-latest
container: cypress/browsers:node16.14.2-slim-chrome103-ff102
container: cypress/browsers:node-20.11.0-chrome-121.0.6167.184-1-ff-123.0-edge-121.0.2277.128-1
if: ${{ github.event.inputs.test != 'all' }}
steps:
- name: Checkout Repository
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/regression-daily.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
jobs:
all-tests:
runs-on: ubuntu-latest
container: cypress/browsers:node16.14.2-slim-chrome103-ff102
container: cypress/browsers:node-20.11.0-chrome-121.0.6167.184-1-ff-123.0-edge-121.0.2277.128-1
strategy:
# when one test fails, DO NOT cancel the other
# containers, because this will kill Cypress processes
Expand Down Expand Up @@ -63,7 +63,7 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
cleanup-tests:
runs-on: ubuntu-latest
container: cypress/browsers:node16.14.2-slim-chrome103-ff102
container: cypress/browsers:node-20.11.0-chrome-121.0.6167.184-1-ff-123.0-edge-121.0.2277.128-1
steps:
- name: Checkout Repository
uses: actions/checkout@v2
Expand Down
3 changes: 3 additions & 0 deletions cms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
"rollbarAccessToken": "fb9dd070b7344cc7a5e529d8fa25e765"
},
"scripts": {
"build": "npm-run-all lint build:webpack",
"build:webpack": "webpack --mode production",
"lint": "eslint -c \"../.eslintrc.js\" \"./src/**/*.{js,jsx,ts,tsx}\"",
"lint:fix": "eslint --fix \"./src/**/*.{js,jsx,ts,tsx}\"",
"start": "webpack-dev-server --hot",
"test": "jest"
},
"author": "Concord Consortium <> (https://concord.org)",
Expand Down
57 changes: 0 additions & 57 deletions cms/src/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,66 +16,9 @@
isAuthed = !/appMode=(dev|demo|qa|test)/.test(window.location.search),
isDemo = /appMode=demo/.test(window.location.search),
isProduction = !isLocalhost && !isBranchOrTag && isAuthed;
var _rollbarConfig = {
accessToken: "<%= rollbarAccessToken %>",
captureUncaught: true,
captureUnhandledRejections: true,
enabled: !isLocalhost && (isAuthed || (isDemo && isMasterBranch)),
payload: {
environment: isProduction ? "production" : "staging"
}
};
// Rollbar Snippet
if (_rollbarConfig.enabled) {
<%= rollbarSnippet %>
}
// End Rollbar Snippet
</script>
</head>
<body>
<svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-unshare" viewBox="0 0 32 32">
<title>unshare</title>
<path d="M22.7 7.7l-1.2 2.5c1.5 1.5 2.5 3.5 2.5 5.8 0 4.4-3.6 8-8 8-0.3 0-0.6 0-0.9-0.1l-0.9 1.9c0.6 0.1 1.2 0.1 1.8 0.1 9 0 15-8.9 15-10 0-0.7-3.2-5.6-8.3-8.2z"></path>
<path d="M16 22c0 0 0 0 0 0 3.3 0 6-2.7 6-6 0-1.5-0.5-2.8-1.4-3.8l-4.6 9.8z"></path>
<path d="M19.7 3.3l-1.4 3c-0.7-0.2-1.5-0.3-2.3-0.3-9 0-15 8.9-15 10 0 0.8 3.3 6 8.8 8.5l-1.1 2.3 2.8 1.3 11-23.5-2.8-1.3zM8 16c0-4.4 3.6-8 8-8 0.5 0 1 0 1.4 0.1l-0.9 1.9c-0.1 0-0.3 0-0.5 0-1.5 0-2.8 0.5-3.8 1.4 0.4-0.2 0.8-0.4 1.3-0.4 0.9 0 1.6 0.4 2.1 1.1l-1.8 3.9c-0.1 0-0.2 0-0.3 0-1.4 0-2.5-1.1-2.5-2.5 0-0.5 0.1-1 0.4-1.3-0.9 1-1.4 2.4-1.4 3.8 0 1.7 0.7 3.2 1.8 4.2l-0.9 1.9c-1.8-1.4-2.9-3.6-2.9-6.1z"></path>
</symbol>
<symbol id="icon-edit" viewBox="0 0 19 19">
<title>edit</title>
<path d="M15.6 6.6l-1.2 1.2c-.1.1-.3.1-.4 0L11.2 5c-.1-.1-.1-.3 0-.4l1.2-1.2c.5-.5 1.2-.5 1.7 0l1.5 1.5c.5.5.5 1.2 0 1.7zM10.2 5.5l-6.7 6.7-.5 3.1c-.1.4.3.8.7.7l3.1-.5 6.7-6.7c.1-.1.1-.3 0-.4l-2.8-2.8c-.2-.2-.4-.2-.5-.1z"/>
</symbol>
<symbol id="icon-copy-only" viewBox="0 0 19 19">
<title>copy-only</title>
<path d="M6 14c-.6 0-1-.4-1-1V7H4c-.6 0-1 .4-1 1v7c0 .6.4 1 1 1h7c.6 0 1-.4 1-1v-1H6z"/>
<path d="M15 12H8c-.6 0-1-.4-1-1V4c0-.6.4-1 1-1h7c.6 0 1 .4 1 1v7c0 .6-.4 1-1 1z"/>
</symbol>
<symbol id="icon-text-tool" viewBox="0 0 36 34">
<title>text-tool</title>
<path d="M27,8c0.5,0,1,0.5,1,1v16c0,0.5-0.5,1-1,1H9c-0.5,0-1-0.5-1-1V9c0-0.5,0.5-1,1-1H27 M27,6H9C7.3,6,6,7.3,6,9v16c0,1.6,1.3,3,3,3h18c1.6,0,3-1.4,3-3V9C30,7.3,28.6,6,27,6L27,6z"/>
<path d="M24.8,24h-2c-0.2,0-0.4-0.1-0.6-0.2c-0.1-0.1-0.3-0.3-0.3-0.4l-1-2.9h-5.8l-1,2.9c-0.1,0.1-0.2,0.3-0.3,0.4c-0.2,0.1-0.3,0.2-0.6,0.2h-2l5.5-14h2.7L24.8,24z M15.8,18.7h4.5c0,0-2.2-6-2.3-6.3C17.9,12.7,15.8,18.7,15.8,18.7z"/>
</symbol>
<symbol id="icon-publish" viewBox="0 0 40 36">
<title>publish</title>
<path d="M32 5h-8.5l4.3 5H33v18c0 .6-.4 1-1 1H8c-.6 0-1-.4-1-1V10h5.2l4.3-5H8C6.3 5 5 6.3 5 8v20c0 1.7 1.3 3 3 3h24c1.7 0 3-1.3 3-3V8c0-1.7-1.3-3-3-3z"/>
<path d="M29.1 12c.1.3.1.7.1 1h.8v13H10V13h.8c0-.3 0-.7.1-1H9v15h22V12h-1.9z"/>
<path d="M27.1 12.3L20 4l-7.1 8.3c-.3.4 0 .9.4.9h2.2v3.9c0 .3.2.5.5.5h8c.3 0 .5-.2.5-.5v-3.9h2.2c.4 0 .7-.5.4-.9z"/>
</symbol>
<symbol id="icon-star" viewBox="0 0 24 24">
<title>Star</title>
<path d="M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z"/>
</symbol>
<symbol id="icon-outline-star" viewBox="0 0 24 24">
<title>Star</title>
<path d="M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z" stroke="#88a658" stroke-width="2"/>
</symbol>
<symbol id="icon-delete-document" viewBox="0 0 36 34">
<title>Delete</title>
<path d="M24.4 12L23 10.6c-.2-.2-.5-.2-.7 0L18 14.9l-4.2-4.2c-.2-.2-.5-.2-.7 0L11.6 12c-.2.2-.2.5 0 .7l4.2 4.2-4.2 4.2c-.2.2-.2.5 0 .7l1.4 1.4c.2.2.5.2.7 0l4.2-4.2 4.2 4.2c.2.2.5.2.7 0l1.4-1.4c.2-.2.2-.5 0-.7L20.1 17l4.2-4.2c.3-.2.3-.6.1-.8z"/>
<path d="M27 6H9C7.4 6 6 7.3 6 9v16c0 1.6 1.4 3 3 3h18c1.7 0 3-1.4 3-3V9c0-1.7-1.3-3-3-3zm1 19c0 .5-.5 1-1 1H9c-.5 0-1-.5-1-1V9c0-.5.5-1 1-1h18c.5 0 1 .5 1 1v16z"/>
</symbol>
</defs>
</svg>
<script>
if (window.netlifyIdentity) {
window.netlifyIdentity.on("init", user => {
Expand Down
107 changes: 107 additions & 0 deletions cms/src/cms-collections.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { CmsConfig, CmsField, CmsFieldSelect, CmsSelectWidgetOptionObject } from "netlify-cms-core";
import { urlParams } from "../../src/utilities/url-params";

const typeField = {
label: "Type",
name: "type",
widget: "string"
} as CmsField;

const titleField = {
label: "Title",
name: "title",
widget: "string"
} as CmsField;

const tagField = {
label: "Tag",
name: "tag",
widget: "select",
options: []
} as CmsFieldSelect;

const previewLinkField = {
label: "Preview Link",
name: "preview-link",
required: false,
widget: "preview-link"
} as CmsField;

const contentField = {
label: "Content",
name: "content",
widget: "clue" as any
} as CmsField;

const legacyCurriculumSections = {
name: "sections",
label: "Curriculum Sections",
label_singular: "Curriculum Section",
identifier_field: "type",
format: "json",
folder: urlParams.unit ? `curriculum/${urlParams.unit}` : `not-supported`,
nested: { depth: 6 },
fields: [typeField, previewLinkField, contentField]
};

const curriculumSections = {
name: "sections",
label: "Curriculum Sections",
label_singular: "Curriculum Section",
identifier_field: "type",
format: "json",
folder: urlParams.unit ? `curriculum/${urlParams.unit}/sections` : `not-supported`,
nested: { depth: 6 },
fields: [typeField, previewLinkField, contentField]
};

const teacherGuides = {
name: "teacherGuides",
label: "Teacher Guides",
label_singular: "Teacher Guide",
identifier_field: "type",
format: "json",
folder: urlParams.unit ? `curriculum/${urlParams.unit}/teacher-guide/sections` : `not-supported`,
nested: { depth: 6 },
fields: [typeField, previewLinkField, contentField]
};

const exemplars = {
name: "exemplars",
label: "Exemplars",
label_singular: "Exemplar",
identifier_field: "type",
format: "json",
folder: urlParams.unit ? `curriculum/${urlParams.unit}/exemplars` : `not-supported`,
nested: { depth: 6 },
fields: [titleField, tagField, contentField]
};

function hasSectionsFolder(myJson: any) {
// TODO: use ModernUnitSnapshot | LegacyUnitSnapshot
// (some issue with importing them from the models file, so we use any for now)
const unitProblems = myJson.investigations.map((inv: any) => inv.problems).flat();
const allSections = unitProblems.map((prob: any ) => prob.sections).flat();
const sectionStrInPath = allSections.some((section: any) => section.includes("sections/"));
return sectionStrInPath;
}

export function getCmsCollections(unitJson: any): CmsConfig["collections"] {
if (unitJson.config.commentTags) {
const tags = unitJson.config.commentTags;
const options = Object.entries(tags).map(([value, label]) => ({ label, value }));
tagField.options = options as Array<CmsSelectWidgetOptionObject>;
}

if (unitJson && hasSectionsFolder(unitJson)) {
return [
teacherGuides,
curriculumSections,
exemplars
] as CmsConfig["collections"];
} else {
return [
legacyCurriculumSections
] as CmsConfig["collections"];
}
}
14 changes: 9 additions & 5 deletions cms/src/iframe-control.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,21 @@ import { defaultCurriculumBranch } from "./cms-constants";
import "./iframe-control.scss";

(window as any).DISABLE_FIREBASE_SYNC = true;

const cmsEditorBase = urlParams.cmsEditorBase ?? ".";
// the URL is relative to the current url of the CMS
// If the cmsEditorBase is an absolute url then the current url will be ignored
const cmsEditorBaseURL = new URL(cmsEditorBase, window.location.href);
const validOrigin = cmsEditorBaseURL.origin;

interface IState {
initialValue?: string;
validOrigin: string;
}
export class IframeControl extends React.Component<CmsWidgetControlProps, IState> {
constructor(props: CmsWidgetControlProps) {
super(props);
this.state = {
initialValue: this.getValue(),
validOrigin: `${window.location.protocol}//${window.location.host}`
};
}

Expand All @@ -36,7 +41,7 @@ export class IframeControl extends React.Component<CmsWidgetControlProps, IState
};

sendInitialValueToEditor() {
const { initialValue, validOrigin } = this.state;
const { initialValue } = this.state;
const iframedEditor = document.getElementById("editor") as HTMLIFrameElement;
if (iframedEditor.contentWindow) {
iframedEditor.contentWindow.postMessage(
Expand All @@ -48,7 +53,6 @@ export class IframeControl extends React.Component<CmsWidgetControlProps, IState
}

isValidMessageEvent = (event: MessageEvent) => {
const { validOrigin } = this.state;
return event.data.type === "updateContent" &&
event.data.content &&
event.origin === validOrigin;
Expand All @@ -62,7 +66,7 @@ export class IframeControl extends React.Component<CmsWidgetControlProps, IState

render() {
const curriculumBranch = urlParams.curriculumBranch ?? defaultCurriculumBranch;
const iframeBaseUrl = `./cms-editor.html?curriculumBranch=${curriculumBranch}`;
const iframeBaseUrl = `${cmsEditorBase}/cms-editor.html?curriculumBranch=${curriculumBranch}`;
const iframeUrl = urlParams.unit
? `${iframeBaseUrl}&unit=${urlParams.unit}`
: iframeBaseUrl;
Expand Down
75 changes: 26 additions & 49 deletions cms/src/init-cms.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
(window as any).CMS_MANUAL_INIT = true;

import CMS from "netlify-cms-app";
import { CmsBackendType, CmsConfig, CmsField } from "netlify-cms-core";
import { CmsBackendType, CmsConfig } from "netlify-cms-core";

import { urlParams } from "../../src/utilities/url-params";
import { IframeControl } from "./iframe-control";
import { JsonControl } from "./json-control";
import { PreviewLinkControl } from "./preview-link-control";
import { defaultCurriculumBranch } from "./cms-constants";
import { getCmsCollections } from "./cms-collections";
import { getUnitJson } from "../../src/models/curriculum/unit-utils";
import { CurriculumConfig } from "../../src/models/stores/curriculum-config";

import curriculumConfigJson from "../../src/clue/curriculum-config.json";

const curriculumConfig = CurriculumConfig.create(curriculumConfigJson, { urlParams });
const unit = urlParams.unit ?? curriculumConfig.defaultUnit;

// Local testing of the CMS without working with github directly:
// - Add the localCMSBacked parameter to the URL
Expand Down Expand Up @@ -35,56 +43,25 @@ function cmsBackend() {
}

// Config for Decap CMS
const cmsConfig: CmsConfig = {
load_config_file: false,
...cmsBackend(),
media_folder: urlParams.unit ? `curriculum/${urlParams.unit}/images` : `curriculum/images`,
// The public_folder setting doesn't apply to the top level "Media" dialog.
// It is configured here for documentation, and in case we start using
// the media api within out CLUE editor
public_folder: urlParams.unit ? `${urlParams.unit}/images` : `images`,
collections: [
{
name: "sections",
label: "Curriculum Sections",
label_singular: "Curriculum Section",
identifier_field: "type",
format: "json",
folder: urlParams.unit ? `curriculum/${urlParams.unit}` : `curriculum`,
// create: true
// adding a nested object will show the collection folder structure
nested: {
depth: 6, // max depth to show in the collection tree
},
fields: [
{
label: "Type",
name: "type",
widget: "string"
},
{
label: "Preview Link",
name: "preview-link",
required: false,
widget: "preview-link"
} as CmsField,
{
label: "Content",
name: "content",
widget: "clue" as any
}
],
// adding a meta object with a path property allows editing the path of entries
// moving an existing entry will move the entire sub tree of the entry to the new location
// However, this causes the path to be lowercased when publishing an entry.
// meta: { path: { widget: "hidden", label: "Path", index_file: "content" } }
}
]
};
function cmsConfig(unitJson: any): CmsConfig {
return {
load_config_file: false,
...cmsBackend(),
media_folder: urlParams.unit ? `curriculum/${urlParams.unit}/images` : `curriculum/images`,
// The public_folder setting doesn't apply to the top level "Media" dialog.
// It is configured here for documentation, and in case we start using
// the media api within out CLUE editor
public_folder: urlParams.unit ? `${urlParams.unit}/images` : `images`,
collections: getCmsCollections(unitJson)
};
}

export function initCMS() {
export async function initCMS() {
CMS.registerWidget("clue", IframeControl);
CMS.registerWidget("json", JsonControl);
CMS.registerWidget("preview-link", PreviewLinkControl);
CMS.init({config: cmsConfig});
const unitJson = await getUnitJson(unit, curriculumConfig);
CMS.init({config: cmsConfig(unitJson)});
}


Loading

0 comments on commit 5b0b81c

Please sign in to comment.