From fb55d6fd91c057e0e628fbd14ececa40b07323a4 Mon Sep 17 00:00:00 2001 From: Mauricio Date: Thu, 5 Aug 2021 13:29:12 -0400 Subject: [PATCH 01/25] Merged components and tests together --- .../stats/assessment-stats-controls.jsx | 233 ++++++++++++++++++ .../stats/assessment-stats-controls.scss | 126 ++++++++++ ...t.js => assessment-stats-controls.test.js} | 88 ++++++- .../assessment-stats-filter-controls.jsx | 65 ----- .../assessment-stats-filter-controls.scss | 31 --- .../assessment-stats-filter-controls.test.js | 81 ------ .../assessment-stats-search-controls.jsx | 133 ---------- .../assessment-stats-search-controls.scss | 98 -------- .../components/stats/assessment-stats.jsx | 38 ++- .../components/stats/assessment-stats.scss | 1 + yarn.lock | 5 + 11 files changed, 472 insertions(+), 427 deletions(-) create mode 100644 packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx create mode 100644 packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss rename packages/app/obojobo-repository/shared/components/stats/{assessment-stats-search-controls.test.js => assessment-stats-controls.test.js} (57%) delete mode 100644 packages/app/obojobo-repository/shared/components/stats/assessment-stats-filter-controls.jsx delete mode 100644 packages/app/obojobo-repository/shared/components/stats/assessment-stats-filter-controls.scss delete mode 100644 packages/app/obojobo-repository/shared/components/stats/assessment-stats-filter-controls.test.js delete mode 100644 packages/app/obojobo-repository/shared/components/stats/assessment-stats-search-controls.jsx delete mode 100644 packages/app/obojobo-repository/shared/components/stats/assessment-stats-search-controls.scss diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx new file mode 100644 index 0000000000..321de186ec --- /dev/null +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx @@ -0,0 +1,233 @@ +require('./assessment-stats-controls.scss') + +const { useDebouncedCallback } = require('use-debounce') +const React = require('react') +const Button = require('../button') + +const SEARCH_INPUT_DEBOUNCE_MS = 500 + +const AssessmentStatsControls = ({ controls, onChangeControls }) => { + const [param, setParam] = React.useState('') + const [textInput, setTextInput] = React.useState('') + const [startDate, setStartDate] = React.useState('') + const [endDate, setEndDate] = React.useState('') + + const debouncedOnChangeSearchContent = useDebouncedCallback(searchTerm => { + // onChangeSearchContent({ + // text: searchTerm, + // date: { start: startDate, end: endDate } + // }) + + onChangeControls(Object.assign(controls, { + searchContent: { + searchString: searchTerm, + date: { start: startDate, end: endDate } + } + })) + }, SEARCH_INPUT_DEBOUNCE_MS) + + const onChangeSearchSettings = event => { + const value = event.target.value + + setParam(value) + + // onChangeSearchSettings(value) + + onChangeControls(Object.assign(controls, { searchBy: value })) + } + + const onChangeSearchContent = event => { + const value = event.target.value + + setTextInput(value) + debouncedOnChangeSearchContent(value) + + // If the user clears out the input go ahead and update the search without a delay + if (value.length === 0) { + debouncedOnChangeSearchContent.flush() + } + } + + const onChangeStartDate = newDate => { + setStartDate(newDate) + + // onChangeSearchContent({ + // text: textInput, + // date: { start: newDate, end: endDate } + // }) + + onChangeControls(Object.assign(controls, { + searchContent: { + searchString: textInput, + date: { start: newDate, end: endDate } + } + })) + } + + const onChangeEndDate = newDate => { + setEndDate(newDate) + + // onChangeSearchContent({ + // text: textInput, + // date: { start: startDate, end: newDate } + // }) + + onChangeControls(Object.assign(controls, { + searchContent: { + searchString: textInput, + date: { start: startDate, end: newDate } + } + })) + } + + const onChangeShowIncompleteAttempts = event => { + // onChangeFilterSettings({ + // showPreviewAttempts: filterSettings.showPreviewAttempts, + // showAdvancedFields: filterSettings.showAdvancedFields, + // showIncompleteAttempts: event.target.checked + // }) + + onChangeControls(Object.assign(controls, { + showPreviewAttempts: filterSettings.showPreviewAttempts, + showAdvancedFields: filterSettings.showAdvancedFields, + showIncompleteAttempts: event.target.checked + })) + } + + const onChangeShowPreviewAttempts = event => { + // onChangeFilterSettings({ + // showIncompleteAttempts: filterSettings.showIncompleteAttempts, + // showAdvancedFields: filterSettings.showAdvancedFields, + // showPreviewAttempts: event.target.checked + // }) + + onChangeControls(Object.assign(controls, { + showIncompleteAttempts: filterSettings.showIncompleteAttempts, + showAdvancedFields: filterSettings.showAdvancedFields, + showPreviewAttempts: event.target.checked + })) + } + + const onChangeShowAdvancedFields = event => { + // onChangeFilterSettings({ + // showIncompleteAttempts: filterSettings.showIncompleteAttempts, + // showPreviewAttempts: filterSettings.showPreviewAttempts, + // showAdvancedFields: event.target.checked + // }) + + onChangeControls(Object.assign(controls, { + showIncompleteAttempts: filterSettings.showIncompleteAttempts, + showPreviewAttempts: filterSettings.showPreviewAttempts, + showAdvancedFields: event.target.checked + })) + } + + const showTextInput = param !== '' + + const textPlaceholder = param + .split('-') + .map(word => word.charAt(0).toUpperCase() + word.substring(1)) + .join(' ') + + return ( +
+
+ + +
+ +
+
+
+ +
+ + {showTextInput && ( + + )} +
+
+
+
+ Filter attempts by date range: + + + +
+
+
+ ) +} + +module.exports = AssessmentStatsControls diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss new file mode 100644 index 0000000000..cb3ce01535 --- /dev/null +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss @@ -0,0 +1,126 @@ +@import '../../../client/css/defaults'; + +.repository--assessment-stats-controls { + .search-controls { + select { + @include select-input(); + + border: 1px solid $color-shadow; + font-size: 0.8em; + width: 11em; + } + + .search-by-text { + margin-top: 1em; + margin-bottom: 1em; + display: flex; + align-items: baseline; + + label { + width: 5.5em; + } + + select { + width: 100%; + } + + .text-input { + border-radius: $dimension-rounded-radius; + padding: 0.6em 0.5em; + font-size: 0.8em; + border: 0.1em solid $color-shadow; + } + + .controls { + display: flex; + flex-direction: column; + gap: 0.5em; + flex-grow: 1; + } + } + + .search-by-date { + margin-top: 1em; + margin-bottom: 1em; + display: flex; + flex-direction: column; + gap: 0.5em; + + .label { + margin-bottom: 0.5em; + } + + label { + display: flex; + align-items: baseline; + + > span { + width: 5.5em; + } + } + + .date-range { + display: flex; + flex-direction: column; + gap: 0.1em; + flex-grow: 1; + + button { + border: none; + padding: 0; + width: 4em; + + &:disabled { + visibility: hidden; + } + } + + input[type='date'] { + border-radius: $dimension-rounded-radius; + padding: 0.5em; + font-size: 0.8em; + border: 0.1em solid $color-shadow; + + &[value=''] { + color: $color-text-minor; + } + + &:not([value='']) { + background-color: $color-action-bg; + border: 1px solid $color-action; + } + } + } + } + + input { + font-family: $font-monospace; + } + } + + .filter-controls { + display: flex; + flex-direction: column; + width: 100%; + + hr { + margin-top: 1em; + margin-bottom: 1em; + } + + input { + margin-right: 0.5em; + margin-left: 0; + } + + label { + cursor: pointer; + display: flex; + align-items: center; + + span { + white-space: nowrap; + } + } + } +} diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-search-controls.test.js b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js similarity index 57% rename from packages/app/obojobo-repository/shared/components/stats/assessment-stats-search-controls.test.js rename to packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js index 2a61334166..504d0bd87d 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-search-controls.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js @@ -1,7 +1,7 @@ import React from 'react' import renderer, { act } from 'react-test-renderer' import Button from '../button' -import AssessmentStatsSearchControls from './assessment-stats-search-controls' +import AssessmentStatsControls from './assessment-stats-controls' jest.mock('use-debounce', () => ({ useDebouncedCallback: cb => { @@ -14,15 +14,89 @@ jest.mock('use-debounce', () => ({ } })) -describe('AssessmentStatsSearchControls', () => { - test('AssessmentStatsSearchControls renders correctly', () => {}) +describe('AssessmentStatsControls', () => { + test('AssessmentStatsControls renders correctly', () => {}) + + test.each` + showIncompleteAttempts | showPreviewAttempts | showAdvancedFields + ${false} | ${false} | ${false} + ${false} | ${false} | ${true} + ${false} | ${true} | ${false} + ${false} | ${true} | ${true} + ${true} | ${false} | ${false} + ${true} | ${false} | ${true} + ${true} | ${true} | ${false} + ${true} | ${true} | ${true} + `( + ' matches snapshot', + ({ showIncompleteAttempts, showPreviewAttempts, showAdvancedFields }) => { + const component = renderer.create( + + ) + const tree = component.toJSON() + expect(tree).toMatchSnapshot() + } + ) + + test('Inputs work as expected', () => { + const onChangeFilterSettings = jest.fn() + + const component = renderer.create( + + ) + + const checkboxShowIncomplete = component.root.findByProps({ + className: 'show-incomplete-attempts' + }) + const checkboxShowPreview = component.root.findByProps({ className: 'show-preview-attempts' }) + const checkboxAdvanced = component.root.findByProps({ className: 'show-advanced-fields' }) + + expect(onChangeFilterSettings).not.toHaveBeenCalled() + + // Click on checkboxShowIncomplete + checkboxShowIncomplete.props.onChange({ target: { checked: true } }) + expect(onChangeFilterSettings).toHaveBeenCalledTimes(1) + expect(onChangeFilterSettings).toHaveBeenCalledWith({ + showIncompleteAttempts: true, + showPreviewAttempts: false, + showAdvancedFields: false + }) + + // Click on checkboxShowPreview + checkboxShowPreview.props.onChange({ target: { checked: true } }) + expect(onChangeFilterSettings).toHaveBeenCalledTimes(2) + expect(onChangeFilterSettings).toHaveBeenCalledWith({ + showIncompleteAttempts: false, + showPreviewAttempts: true, + showAdvancedFields: false + }) + + // Click on showAdvancedFields + checkboxAdvanced.props.onChange({ target: { checked: true } }) + expect(onChangeFilterSettings).toHaveBeenCalledTimes(3) + expect(onChangeFilterSettings).toHaveBeenCalledWith({ + showIncompleteAttempts: false, + showPreviewAttempts: false, + showAdvancedFields: true + }) + }) test('Inputs and select tags work as expected', () => { const onChangeSearchSettings = jest.fn() const onChangeSearchContent = jest.fn() const component = renderer.create( - { const onChangeSearchContent = jest.fn() const component = renderer.create( - { const onChangeSearchContent = jest.fn() const component = renderer.create( - { const onChangeSearchContent = jest.fn() const component = renderer.create( - { - onChangeFilterSettings({ - showPreviewAttempts: filterSettings.showPreviewAttempts, - showAdvancedFields: filterSettings.showAdvancedFields, - showIncompleteAttempts: event.target.checked - }) - } - - const onChangeShowPreviewAttempts = event => { - onChangeFilterSettings({ - showIncompleteAttempts: filterSettings.showIncompleteAttempts, - showAdvancedFields: filterSettings.showAdvancedFields, - showPreviewAttempts: event.target.checked - }) - } - - const onChangeShowAdvancedFields = event => { - onChangeFilterSettings({ - showIncompleteAttempts: filterSettings.showIncompleteAttempts, - showPreviewAttempts: filterSettings.showPreviewAttempts, - showAdvancedFields: event.target.checked - }) - } - - return ( -
-
- - -
- -
-
- ) -} - -module.exports = AssessmentStatsFilterControls diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-filter-controls.scss b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-filter-controls.scss deleted file mode 100644 index a544706c0b..0000000000 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-filter-controls.scss +++ /dev/null @@ -1,31 +0,0 @@ -@import '../../../client/css/defaults'; - -.repository--assessment-stats-filter-controls { - width: 100%; - - hr { - margin-top: 1em; - margin-bottom: 1em; - } - - .container { - display: flex; - flex-direction: column; - width: 100%; - - input { - margin-right: 0.5em; - margin-left: 0; - } - - label { - cursor: pointer; - display: flex; - align-items: center; - - span { - white-space: nowrap; - } - } - } -} diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-filter-controls.test.js b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-filter-controls.test.js deleted file mode 100644 index 4c0796c267..0000000000 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-filter-controls.test.js +++ /dev/null @@ -1,81 +0,0 @@ -import React from 'react' -import renderer from 'react-test-renderer' -import AssessmentStatsFilterControls from './assessment-stats-filter-controls' - -describe('AssessmentStatsFilterControls', () => { - test('AssessmentStatsFilterControls renders correctly', () => {}) - - test.each` - showIncompleteAttempts | showPreviewAttempts | showAdvancedFields - ${false} | ${false} | ${false} - ${false} | ${false} | ${true} - ${false} | ${true} | ${false} - ${false} | ${true} | ${true} - ${true} | ${false} | ${false} - ${true} | ${false} | ${true} - ${true} | ${true} | ${false} - ${true} | ${true} | ${true} - `( - ' matches snapshot', - ({ showIncompleteAttempts, showPreviewAttempts, showAdvancedFields }) => { - const component = renderer.create( - - ) - const tree = component.toJSON() - expect(tree).toMatchSnapshot() - } - ) - - test('Inputs work as expected', () => { - const onChangeFilterSettings = jest.fn() - - const component = renderer.create( - - ) - - const checkboxShowIncomplete = component.root.findByProps({ - className: 'show-incomplete-attempts' - }) - const checkboxShowPreview = component.root.findByProps({ className: 'show-preview-attempts' }) - const checkboxAdvanced = component.root.findByProps({ className: 'show-advanced-fields' }) - - expect(onChangeFilterSettings).not.toHaveBeenCalled() - - // Click on checkboxShowIncomplete - checkboxShowIncomplete.props.onChange({ target: { checked: true } }) - expect(onChangeFilterSettings).toHaveBeenCalledTimes(1) - expect(onChangeFilterSettings).toHaveBeenCalledWith({ - showIncompleteAttempts: true, - showPreviewAttempts: false, - showAdvancedFields: false - }) - - // Click on checkboxShowPreview - checkboxShowPreview.props.onChange({ target: { checked: true } }) - expect(onChangeFilterSettings).toHaveBeenCalledTimes(2) - expect(onChangeFilterSettings).toHaveBeenCalledWith({ - showIncompleteAttempts: false, - showPreviewAttempts: true, - showAdvancedFields: false - }) - - // Click on showAdvancedFields - checkboxAdvanced.props.onChange({ target: { checked: true } }) - expect(onChangeFilterSettings).toHaveBeenCalledTimes(3) - expect(onChangeFilterSettings).toHaveBeenCalledWith({ - showIncompleteAttempts: false, - showPreviewAttempts: false, - showAdvancedFields: true - }) - }) -}) diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-search-controls.jsx b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-search-controls.jsx deleted file mode 100644 index c70b4053b0..0000000000 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-search-controls.jsx +++ /dev/null @@ -1,133 +0,0 @@ -require('./assessment-stats-search-controls.scss') - -const { useDebouncedCallback } = require('use-debounce') -const React = require('react') -const Button = require('../button') - -const SEARCH_INPUT_DEBOUNCE_MS = 500 - -const AssessmentStatsSearchControls = ({ onChangeSearchSettings, onChangeSearchContent }) => { - const [param, setParam] = React.useState('') - const [textInput, setTextInput] = React.useState('') - const [startDate, setStartDate] = React.useState('') - const [endDate, setEndDate] = React.useState('') - - const debouncedOnChangeSearchContent = useDebouncedCallback(searchTerm => { - onChangeSearchContent({ - text: searchTerm, - date: { start: startDate, end: endDate } - }) - }, SEARCH_INPUT_DEBOUNCE_MS) - - const handleSearchSettingsChange = event => { - const value = event.target.value - - setParam(value) - onChangeSearchSettings(value) - } - - const handleSearchContentChange = event => { - const value = event.target.value - - setTextInput(value) - debouncedOnChangeSearchContent(value) - - // If the user clears out the input go ahead and update the search without a delay - if (value.length === 0) { - debouncedOnChangeSearchContent.flush() - } - } - - const onChangeStartDate = newDate => { - setStartDate(newDate) - onChangeSearchContent({ - text: textInput, - date: { start: newDate, end: endDate } - }) - } - - const onChangeEndDate = newDate => { - setEndDate(newDate) - onChangeSearchContent({ - text: textInput, - date: { start: startDate, end: newDate } - }) - } - - const showTextInput = param !== '' - - const textPlaceholder = param - .split('-') - .map(word => word.charAt(0).toUpperCase() + word.substring(1)) - .join(' ') - - return ( -
-
- -
- - {showTextInput && ( - - )} -
-
-
-
- Filter attempts by date range: - - - -
-
- ) -} - -module.exports = AssessmentStatsSearchControls diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-search-controls.scss b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-search-controls.scss deleted file mode 100644 index ab2fd77c9d..0000000000 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-search-controls.scss +++ /dev/null @@ -1,98 +0,0 @@ -@import '../../../client/css/defaults'; - -.repository--assessment-stats-search-controls { - select { - @include select-input(); - - border: 1px solid $color-shadow; - font-size: 0.8em; - width: 11em; - } - - .search-by-text { - margin-top: 1em; - margin-bottom: 1em; - display: flex; - align-items: baseline; - - label { - width: 5.5em; - } - - select { - width: 100%; - } - - .text-input { - border-radius: $dimension-rounded-radius; - padding: 0.6em 0.5em; - font-size: 0.8em; - border: 0.1em solid $color-shadow; - } - - .controls { - display: flex; - flex-direction: column; - gap: 0.5em; - flex-grow: 1; - } - } - - .search-by-date { - margin-top: 1em; - margin-bottom: 1em; - display: flex; - flex-direction: column; - gap: 0.5em; - - .label { - margin-bottom: 0.5em; - } - - label { - display: flex; - align-items: baseline; - - > span { - width: 5.5em; - } - } - - .date-range { - display: flex; - flex-direction: column; - gap: 0.1em; - flex-grow: 1; - - button { - border: none; - padding: 0; - width: 4em; - - &:disabled { - visibility: hidden; - } - } - - input[type='date'] { - border-radius: $dimension-rounded-radius; - padding: 0.5em; - font-size: 0.8em; - border: 0.1em solid $color-shadow; - - &[value=''] { - color: $color-text-minor; - } - - &:not([value='']) { - background-color: $color-action-bg; - border: 1px solid $color-action; - } - } - } - } - - input { - font-family: $font-monospace; - } -} diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx index 9dc92af7d7..a889fc330e 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx @@ -3,8 +3,7 @@ require('./assessment-stats.scss') const React = require('react') const DataGridAttempts = require('./data-grid-attempts') const DataGridAssessments = require('./data-grid-assessments') -const AssessmentStatsFilterControls = require('./assessment-stats-filter-controls') -const AssessmentStatsSearchControls = require('./assessment-stats-search-controls') +const AssessmentStatsControls = require('./assessment-stats-controls') const VIEW_MODE_FINAL_ASSESSMENT_SCORE = 'final-assessment-scores' const VIEW_MODE_ALL_ATTEMPTS = 'all-attempts' @@ -54,11 +53,26 @@ const filterAttempts = (attempts, { showIncompleteAttempts, showPreviewAttempts const AssessmentStats = ({ attempts, defaultFilterSettings = {} }) => { const [viewMode, setViewMode] = React.useState(VIEW_MODE_FINAL_ASSESSMENT_SCORE) - const [searchSettings, setSearchSettings] = React.useState('') - const [searchContent, setSearchContent] = React.useState('') - const [filterSettings, setFilterSettings] = React.useState( + // const [searchSettings, setSearchSettings] = React.useState('') + // const [searchContent, setSearchContent] = React.useState('') + // const [filterSettings, setFilterSettings] = React.useState( + // Object.assign( + // { showIncompleteAttempts: false, showPreviewAttempts: false, showAdvancedFields: false }, + // defaultFilterSettings + // ) + // ) + const [controls, setControls] = React.useState( Object.assign( - { showIncompleteAttempts: false, showPreviewAttempts: false, showAdvancedFields: false }, + { + showIncompleteAttempts: false, + showPreviewAttempts: false, + showAdvancedFields: false, + searchBy: '', + searchContent: { + searchString: '', + date: { start: '', end: '' } + } + }, defaultFilterSettings ) ) @@ -82,14 +96,14 @@ const AssessmentStats = ({ attempts, defaultFilterSettings = {} }) => {
- -
-
diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.scss b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.scss index 7f0ab549ed..34a2c9b293 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.scss +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.scss @@ -15,6 +15,7 @@ border: none; border-bottom: 1px solid $color-shadow; margin: 0; + margin-bottom: 1em; } .settings { diff --git a/yarn.lock b/yarn.lock index f5b9b1ba43..4fa6d8bd51 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14282,6 +14282,11 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" +use-debounce@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/use-debounce/-/use-debounce-7.0.0.tgz#00a67d23d4fe09905e11145a99278da06c01c880" + integrity sha512-4fvxEEs7ztdNMh+c497HAgysdq2+Ascem6EaDANGlCIap1JzqfL03Xw8xkYc2lShfXm4uO6PA6V5zcXN7gJdFA== + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" From 475a982e2ab6efb2e5dc84809d49a843cc2fa81a Mon Sep 17 00:00:00 2001 From: Mauricio Date: Mon, 16 Aug 2021 09:16:46 -0400 Subject: [PATCH 02/25] Wrapped up merging components, date range changes, and first/last name search --- .../assessment-score-data-dialog.test.js.snap | 598 ++++----- .../__snapshots__/stats.test.js.snap | 187 ++- .../assessment-stats-controls.test.js.snap | 1137 +++++++++++++++++ ...essment-stats-filter-controls.test.js.snap | 361 ------ .../assessment-stats.test.js.snap | 648 +++++++--- .../data-grid-assessments.test.js.snap | 24 +- .../data-grid-attempts.test.js.snap | 22 +- .../data-grid-scores.test.js.snap | 249 ++++ .../stats/assessment-stats-controls.jsx | 149 +-- .../stats/assessment-stats-controls.scss | 9 +- .../stats/assessment-stats-controls.test.js | 84 +- .../components/stats/assessment-stats.jsx | 71 +- .../components/stats/assessment-stats.scss | 3 +- .../components/stats/assessment-stats.test.js | 43 +- .../stats/data-grid-assessments.jsx | 16 +- .../stats/data-grid-assessments.test.js | 55 +- .../components/stats/data-grid-attempts.jsx | 16 +- .../stats/data-grid-attempts.test.js | 59 +- .../components/stats/data-grid-scores.jsx | 63 +- .../components/stats/data-grid-scores.test.js | 251 +++- ...get-assessment-stats-from-attempt-stats.js | 1 + 21 files changed, 2681 insertions(+), 1365 deletions(-) create mode 100644 packages/app/obojobo-repository/shared/components/stats/__snapshots__/assessment-stats-controls.test.js.snap delete mode 100644 packages/app/obojobo-repository/shared/components/stats/__snapshots__/assessment-stats-filter-controls.test.js.snap diff --git a/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap b/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap index c3d33bbe4e..d49f4a7ced 100644 --- a/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap @@ -62,113 +62,110 @@ exports[`AssessmentScoreDataDialog AssessmentScoreDataDialog renders correctly w
-
- -
-
-
-
- - Filter attempts by date range: - -
- - + + + + +
- - + +
-
-
-
+

-
- -
-
-
-
- - Filter attempts by date range: - -
- - + + + + +
- - + +
-
-
-
+

-
- -
-
-
-
- - Filter attempts by date range: - -
- - + + + + +
- - + +
-
-
-
+

-
- -
-
-
-
- - Filter attempts by date range: - -
- - + + + + +
- - + +
-
-
-
+
`; + +exports[`AssessmentStats AssessmentStats renders correctly 3`] = ` +
+
+ +
+
+
+
+
+ +
+ +
+
+
+
+ + Filter attempts by date range: + + + +
+
+
+
+ + +
+ +
+
+
+
+
+
+
+
+ react-data-table-component +
+
+
+
+
+`; diff --git a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-assessments.test.js.snap b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-assessments.test.js.snap index 15e7b799f9..549c8fa77d 100644 --- a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-assessments.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-assessments.test.js.snap @@ -67,14 +67,8 @@ exports[`DataGridAssessments DataGridAssessments renders correctly 1`] = ` }, Object { "advanced": false, - "name": "First Name", - "selector": "userFirstName", - "sortable": true, - }, - Object { - "advanced": false, - "name": "Last Name", - "selector": "userLastName", + "name": "Student Name", + "selector": "studentName", "sortable": true, }, Object { @@ -108,6 +102,7 @@ exports[`DataGridAssessments DataGridAssessments renders correctly 1`] = ` "moduleTitle": undefined, "resourceLinkId": undefined, "resourceLinkTitle": undefined, + "studentName": "undefined undefined", "userFirstName": undefined, "userId": undefined, "userLastName": undefined, @@ -127,6 +122,7 @@ exports[`DataGridAssessments DataGridAssessments renders correctly 1`] = ` "moduleTitle": undefined, "resourceLinkId": undefined, "resourceLinkTitle": undefined, + "studentName": "undefined undefined", "userFirstName": undefined, "userId": undefined, "userLastName": undefined, @@ -157,7 +153,7 @@ exports[`DataGridAssessments DataGridAssessments renders correctly 1`] = ` ⬇️   Download @@ -206,14 +202,8 @@ exports[`DataGridAssessments DataGridAssessments renders without attempts 1`] = }, Object { "advanced": false, - "name": "First Name", - "selector": "userFirstName", - "sortable": true, - }, - Object { - "advanced": false, - "name": "Last Name", - "selector": "userLastName", + "name": "Student Name", + "selector": "studentName", "sortable": true, }, Object { diff --git a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap index 571a2ef1d7..e3fb10dd3b 100644 --- a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap @@ -103,14 +103,8 @@ exports[`DataGridAttempts DataGridAttempts renders correctly 1`] = ` }, Object { "advanced": false, - "name": "First Name", - "selector": "userFirstName", - "sortable": true, - }, - Object { - "advanced": false, - "name": "Last Name", - "selector": "userLastName", + "name": "Student Name", + "selector": "studentName", "sortable": true, }, Object { @@ -236,7 +230,7 @@ exports[`DataGridAttempts DataGridAttempts renders correctly 1`] = ` ⬇️   Download @@ -285,14 +279,8 @@ exports[`DataGridAttempts DataGridAttempts renders with no attempts 1`] = ` }, Object { "advanced": false, - "name": "First Name", - "selector": "userFirstName", - "sortable": true, - }, - Object { - "advanced": false, - "name": "Last Name", - "selector": "userLastName", + "name": "Student Name", + "selector": "studentName", "sortable": true, }, Object { diff --git a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap index 712b991d73..e108dcd5a2 100644 --- a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap @@ -29,11 +29,17 @@ exports[`DataGridScores DataGridScores renders correctly 1`] = ` "completedAt": "2021-02-04T13:55:30.255Z", "draftId": "mock-draft-id", "exampleId": "mock-example-id", + "studentName": "mock-first-name mock-last-name", + "userFirstName": "mock-first-name", + "userLastName": "mock-last-name", }, Object { "completedAt": "2021-06-21T15:32:30.255Z", "draftId": "mock-draft-id2", "exampleId": "mock-example-id2", + "studentName": "mock-first-name mock-last-name", + "userFirstName": "mock-first-name", + "userLastName": "mock-last-name", }, ] } @@ -97,6 +103,9 @@ exports[`DataGridScores DataGridScores renders one row 1`] = ` "completedAt": "2021-02-04T13:55:30.255Z", "draftId": "mock-draft-id", "exampleId": "mock-example-id", + "studentName": "mock-first-name mock-last-name", + "userFirstName": "mock-first-name", + "userLastName": "mock-last-name", }, ] } @@ -318,11 +327,17 @@ exports[`DataGridScores DataGridScores uses search filters as expected 4`] = ` "completedAt": "2021-02-04T13:55:30.255Z", "draftId": "mock-draft-id", "exampleId": "mock-example-id", + "studentName": "mock-first-name mock-last-name", + "userFirstName": "mock-first-name", + "userLastName": "mock-last-name", }, Object { "completedAt": "2021-06-21T15:32:30.255Z", "draftId": "mock-draft-id2", "exampleId": "mock-example-id2", + "studentName": "mock-first-name mock-last-name", + "userFirstName": "mock-first-name", + "userLastName": "mock-last-name", }, ] } @@ -386,11 +401,17 @@ exports[`DataGridScores DataGridScores uses search filters as expected 5`] = ` "completedAt": "2021-02-04T13:55:30.255Z", "draftId": "mock-draft-id", "exampleId": "mock-example-id", + "studentName": "mock-first-name mock-last-name", + "userFirstName": "mock-first-name", + "userLastName": "mock-last-name", }, Object { "completedAt": "2021-06-21T15:32:30.255Z", "draftId": "mock-draft-id2", "exampleId": "mock-example-id2", + "studentName": "mock-first-name mock-last-name", + "userFirstName": "mock-first-name", + "userLastName": "mock-last-name", }, ] } @@ -454,11 +475,17 @@ exports[`DataGridScores DataGridScores uses search filters as expected 6`] = ` "completedAt": "2021-02-04T13:55:30.255Z", "draftId": "mock-draft-id", "exampleId": "mock-example-id", + "studentName": "mock-first-name mock-last-name", + "userFirstName": "mock-first-name", + "userLastName": "mock-last-name", }, Object { "completedAt": "2021-06-21T15:32:30.255Z", "draftId": "mock-draft-id2", "exampleId": "mock-example-id2", + "studentName": "mock-first-name mock-last-name", + "userFirstName": "mock-first-name", + "userLastName": "mock-last-name", }, ] } @@ -580,3 +607,225 @@ exports[`DataGridScores DataGridScores uses search filters as expected 8`] = `
`; + +exports[`DataGridScores DataGridScores uses search filters as expected 9`] = ` + +`; + +exports[`DataGridScores DataGridScores uses search filters as expected 10`] = ` + +`; + +exports[`DataGridScores DataGridScores uses search filters as expected 11`] = ` + +`; diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx index 321de186ec..82b0b448ee 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx @@ -6,19 +6,16 @@ const Button = require('../button') const SEARCH_INPUT_DEBOUNCE_MS = 500 -const AssessmentStatsControls = ({ controls, onChangeControls }) => { +const AssessmentStatsControls = ({ controls, onChangeControls, dateBounds }) => { const [param, setParam] = React.useState('') + const [endDate, setEndDate] = React.useState('') const [textInput, setTextInput] = React.useState('') const [startDate, setStartDate] = React.useState('') - const [endDate, setEndDate] = React.useState('') const debouncedOnChangeSearchContent = useDebouncedCallback(searchTerm => { - // onChangeSearchContent({ - // text: searchTerm, - // date: { start: startDate, end: endDate } - // }) + const oldControls = Object.assign({}, controls) - onChangeControls(Object.assign(controls, { + onChangeControls(Object.assign(oldControls, { searchContent: { searchString: searchTerm, date: { start: startDate, end: endDate } @@ -27,13 +24,13 @@ const AssessmentStatsControls = ({ controls, onChangeControls }) => { }, SEARCH_INPUT_DEBOUNCE_MS) const onChangeSearchSettings = event => { + const oldControls = Object.assign({}, controls) + const value = event.target.value setParam(value) - // onChangeSearchSettings(value) - - onChangeControls(Object.assign(controls, { searchBy: value })) + onChangeControls(Object.assign(oldControls, { searchBy: value })) } const onChangeSearchContent = event => { @@ -49,14 +46,11 @@ const AssessmentStatsControls = ({ controls, onChangeControls }) => { } const onChangeStartDate = newDate => { - setStartDate(newDate) + const oldControls = Object.assign({}, controls) - // onChangeSearchContent({ - // text: textInput, - // date: { start: newDate, end: endDate } - // }) + setStartDate(newDate) - onChangeControls(Object.assign(controls, { + onChangeControls(Object.assign(oldControls, { searchContent: { searchString: textInput, date: { start: newDate, end: endDate } @@ -65,14 +59,11 @@ const AssessmentStatsControls = ({ controls, onChangeControls }) => { } const onChangeEndDate = newDate => { - setEndDate(newDate) + const oldControls = Object.assign({}, controls) - // onChangeSearchContent({ - // text: textInput, - // date: { start: startDate, end: newDate } - // }) + setEndDate(newDate) - onChangeControls(Object.assign(controls, { + onChangeControls(Object.assign(oldControls, { searchContent: { searchString: textInput, date: { start: startDate, end: newDate } @@ -81,44 +72,32 @@ const AssessmentStatsControls = ({ controls, onChangeControls }) => { } const onChangeShowIncompleteAttempts = event => { - // onChangeFilterSettings({ - // showPreviewAttempts: filterSettings.showPreviewAttempts, - // showAdvancedFields: filterSettings.showAdvancedFields, - // showIncompleteAttempts: event.target.checked - // }) - - onChangeControls(Object.assign(controls, { - showPreviewAttempts: filterSettings.showPreviewAttempts, - showAdvancedFields: filterSettings.showAdvancedFields, - showIncompleteAttempts: event.target.checked + const oldControls = Object.assign({}, controls) + + onChangeControls(Object.assign(oldControls, { + showPreviewAttempts: controls.showPreviewAttempts, + showAdvancedFields: controls.showAdvancedFields, + showIncompleteAttempts: event.target.checked, })) } const onChangeShowPreviewAttempts = event => { - // onChangeFilterSettings({ - // showIncompleteAttempts: filterSettings.showIncompleteAttempts, - // showAdvancedFields: filterSettings.showAdvancedFields, - // showPreviewAttempts: event.target.checked - // }) - - onChangeControls(Object.assign(controls, { - showIncompleteAttempts: filterSettings.showIncompleteAttempts, - showAdvancedFields: filterSettings.showAdvancedFields, - showPreviewAttempts: event.target.checked + const oldControls = Object.assign({}, controls) + + onChangeControls(Object.assign(oldControls, { + showIncompleteAttempts: controls.showIncompleteAttempts, + showAdvancedFields: controls.showAdvancedFields, + showPreviewAttempts: event.target.checked, })) } const onChangeShowAdvancedFields = event => { - // onChangeFilterSettings({ - // showIncompleteAttempts: filterSettings.showIncompleteAttempts, - // showPreviewAttempts: filterSettings.showPreviewAttempts, - // showAdvancedFields: event.target.checked - // }) - - onChangeControls(Object.assign(controls, { - showIncompleteAttempts: filterSettings.showIncompleteAttempts, - showPreviewAttempts: filterSettings.showPreviewAttempts, - showAdvancedFields: event.target.checked + const oldControls = Object.assign({}, controls) + + onChangeControls(Object.assign(oldControls, { + showIncompleteAttempts: controls.showIncompleteAttempts, + showPreviewAttempts: controls.showPreviewAttempts, + showAdvancedFields: event.target.checked, })) } @@ -131,36 +110,6 @@ const AssessmentStatsControls = ({ controls, onChangeControls }) => { return (
-
- - -
- -
@@ -172,8 +121,7 @@ const AssessmentStatsControls = ({ controls, onChangeControls }) => { - - + {showTextInput && ( { value={startDate} type="date" onChange={event => onChangeStartDate(event.target.value)} + min={dateBounds.start} />
+
+
+ + +
+ +
) } diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss index cb3ce01535..91d42faa39 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss @@ -1,6 +1,10 @@ @import '../../../client/css/defaults'; .repository--assessment-stats-controls { + hr { + margin-bottom: 1em; + } + .search-controls { select { @include select-input(); @@ -46,10 +50,6 @@ flex-direction: column; gap: 0.5em; - .label { - margin-bottom: 0.5em; - } - label { display: flex; align-items: baseline; @@ -105,7 +105,6 @@ hr { margin-top: 1em; - margin-bottom: 1em; } input { diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js index 504d0bd87d..2065b8fc64 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js @@ -32,8 +32,9 @@ describe('AssessmentStatsControls', () => { ({ showIncompleteAttempts, showPreviewAttempts, showAdvancedFields }) => { const component = renderer.create( ) const tree = component.toJSON() @@ -42,16 +43,17 @@ describe('AssessmentStatsControls', () => { ) test('Inputs work as expected', () => { - const onChangeFilterSettings = jest.fn() + const onChangeControls = jest.fn() const component = renderer.create( ) @@ -61,12 +63,12 @@ describe('AssessmentStatsControls', () => { const checkboxShowPreview = component.root.findByProps({ className: 'show-preview-attempts' }) const checkboxAdvanced = component.root.findByProps({ className: 'show-advanced-fields' }) - expect(onChangeFilterSettings).not.toHaveBeenCalled() + expect(onChangeControls).not.toHaveBeenCalled() // Click on checkboxShowIncomplete checkboxShowIncomplete.props.onChange({ target: { checked: true } }) - expect(onChangeFilterSettings).toHaveBeenCalledTimes(1) - expect(onChangeFilterSettings).toHaveBeenCalledWith({ + expect(onChangeControls).toHaveBeenCalledTimes(1) + expect(onChangeControls).toHaveBeenCalledWith({ showIncompleteAttempts: true, showPreviewAttempts: false, showAdvancedFields: false @@ -74,8 +76,8 @@ describe('AssessmentStatsControls', () => { // Click on checkboxShowPreview checkboxShowPreview.props.onChange({ target: { checked: true } }) - expect(onChangeFilterSettings).toHaveBeenCalledTimes(2) - expect(onChangeFilterSettings).toHaveBeenCalledWith({ + expect(onChangeControls).toHaveBeenCalledTimes(2) + expect(onChangeControls).toHaveBeenCalledWith({ showIncompleteAttempts: false, showPreviewAttempts: true, showAdvancedFields: false @@ -83,8 +85,8 @@ describe('AssessmentStatsControls', () => { // Click on showAdvancedFields checkboxAdvanced.props.onChange({ target: { checked: true } }) - expect(onChangeFilterSettings).toHaveBeenCalledTimes(3) - expect(onChangeFilterSettings).toHaveBeenCalledWith({ + expect(onChangeControls).toHaveBeenCalledTimes(3) + expect(onChangeControls).toHaveBeenCalledWith({ showIncompleteAttempts: false, showPreviewAttempts: false, showAdvancedFields: true @@ -92,18 +94,17 @@ describe('AssessmentStatsControls', () => { }) test('Inputs and select tags work as expected', () => { - const onChangeSearchSettings = jest.fn() - const onChangeSearchContent = jest.fn() + const onChangeControls = jest.fn() const component = renderer.create( ) @@ -111,34 +112,31 @@ describe('AssessmentStatsControls', () => { id: 'repository--assessment-stats-search-controls--search-by' }) - expect(onChangeSearchSettings).not.toHaveBeenCalled() - expect(onChangeSearchContent).not.toHaveBeenCalled() + expect(onChangeControls).not.toHaveBeenCalled() // Change select option act(() => { select.props.onChange({ target: { value: 'user-first-name' } }) }) - expect(onChangeSearchSettings).toHaveBeenCalledTimes(1) - expect(onChangeSearchContent).not.toHaveBeenCalled() + expect(onChangeControls).toHaveBeenCalledTimes(1) }) test('Change input based on select option', () => { - const onChangeSearchSettings = jest.fn() - const onChangeSearchContent = jest.fn() + const onChangeControls = jest.fn() const component = renderer.create( ) - expect(onChangeSearchContent).toHaveBeenCalledTimes(0) + expect(onChangeControls).toHaveBeenCalledTimes(0) const select = component.root.findByProps({ id: 'repository--assessment-stats-search-controls--search-by' }) @@ -146,33 +144,32 @@ describe('AssessmentStatsControls', () => { act(() => { select.props.onChange({ target: { value: 'user-first-name' } }) }) + expect(onChangeControls).toHaveBeenCalledTimes(1) - expect(onChangeSearchContent).toHaveBeenCalledTimes(0) const textInput = component.root.findByProps({ type: 'text' }) act(() => { textInput.props.onChange({ target: { value: 'test' } }) }) - expect(onChangeSearchContent).toHaveBeenCalledTimes(1) + expect(onChangeControls).toHaveBeenCalledTimes(2) act(() => { textInput.props.onChange({ target: { value: '' } }) }) - expect(onChangeSearchContent).toHaveBeenCalledTimes(2) + expect(onChangeControls).toHaveBeenCalledTimes(3) }) test('Set and clear date start input', () => { - const onChangeSearchSettings = jest.fn() - const onChangeSearchContent = jest.fn() + const onChangeControls = jest.fn() const component = renderer.create( ) @@ -181,28 +178,27 @@ describe('AssessmentStatsControls', () => { .findAllByProps({ type: 'date' })[0] .props.onChange({ target: { value: new Date() } }) }) - expect(onChangeSearchContent).toHaveBeenCalledTimes(1) + expect(onChangeControls).toHaveBeenCalledTimes(1) expect(component.root.findAllByProps({ type: 'date' })[0].props.value).not.toBe('') act(() => { component.root.findAllByType(Button)[0].props.onClick() }) expect(component.root.findAllByProps({ type: 'date' })[0].props.value).toBe('') - expect(onChangeSearchContent).toHaveBeenCalledTimes(2) + expect(onChangeControls).toHaveBeenCalledTimes(2) }) test('Set and clear date end input', () => { - const onChangeSearchSettings = jest.fn() - const onChangeSearchContent = jest.fn() + const onChangeControls = jest.fn() const component = renderer.create( ) @@ -211,12 +207,12 @@ describe('AssessmentStatsControls', () => { .findAllByProps({ type: 'date' })[1] .props.onChange({ target: { value: new Date() } }) }) - expect(onChangeSearchContent).toHaveBeenCalledTimes(1) + expect(onChangeControls).toHaveBeenCalledTimes(1) expect(component.root.findAllByProps({ type: 'date' })[1].props.value).not.toBe('') act(() => { component.root.findAllByType(Button)[1].props.onClick() }) expect(component.root.findAllByProps({ type: 'date' })[1].props.value).toBe('') - expect(onChangeSearchContent).toHaveBeenCalledTimes(2) + expect(onChangeControls).toHaveBeenCalledTimes(2) }) }) diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx index a889fc330e..664cc64164 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx @@ -11,18 +11,14 @@ const VIEW_MODE_ALL_ATTEMPTS = 'all-attempts' const renderDataGrid = ( viewMode, filteredAttempts, - filterSettings, - searchSettings, - searchContent + controls ) => { switch (viewMode) { case VIEW_MODE_ALL_ATTEMPTS: return ( ) @@ -31,36 +27,56 @@ const renderDataGrid = ( return ( ) } } -const filterAttempts = (attempts, { showIncompleteAttempts, showPreviewAttempts }) => { - if (showIncompleteAttempts && showPreviewAttempts) { +const filterAttempts = (attempts, controls) => { + if (!attempts || attempts.length <= 0) return [] + + attempts = attempts.map(attempt => { + attempt.studentName = attempt.userFirstName + ' ' + attempt.userLastName + return attempt + }) + + if (controls.showIncompleteAttempts && controls.showPreviewAttempts) { return attempts } return attempts.filter( attempt => - (showIncompleteAttempts || attempt.completedAt !== null) && - (showPreviewAttempts || !attempt.isPreview) + (controls.showIncompleteAttempts || attempt.completedAt !== null) && + (controls.showPreviewAttempts || !attempt.isPreview) ) } +const convertDateForDateInput = (date) => { + // Converting to YYYY-MM-DD format (an acceptable format by ) + let day = date.getDate() + day = day < 10 ? '0' + day : day + + let month = date.getMonth() + 1 + month = month < 10 ? '0' + month : month + + const year = date.getFullYear() + + return `${year}-${month}-${day}` +} + +const getLowerAndUpperDateBounds = (attempts) => { + if (attempts.length <= 0) return { start: null, end: null } + + const dates = attempts.map(attempt => new Date(attempt.completedAt)) + let end = convertDateForDateInput(new Date(Math.max.apply(Math, dates))) + let start = convertDateForDateInput(new Date(Math.min.apply(Math, dates))) + + return { start, end } +} + const AssessmentStats = ({ attempts, defaultFilterSettings = {} }) => { const [viewMode, setViewMode] = React.useState(VIEW_MODE_FINAL_ASSESSMENT_SCORE) - // const [searchSettings, setSearchSettings] = React.useState('') - // const [searchContent, setSearchContent] = React.useState('') - // const [filterSettings, setFilterSettings] = React.useState( - // Object.assign( - // { showIncompleteAttempts: false, showPreviewAttempts: false, showAdvancedFields: false }, - // defaultFilterSettings - // ) - // ) const [controls, setControls] = React.useState( Object.assign( { @@ -81,7 +97,8 @@ const AssessmentStats = ({ attempts, defaultFilterSettings = {} }) => { setViewMode(event.target.value) } - const filteredAttempts = filterAttempts(attempts, filterSettings) + const filteredAttempts = filterAttempts(attempts, controls) + const dateBounds = getLowerAndUpperDateBounds(filteredAttempts) return (
@@ -95,20 +112,16 @@ const AssessmentStats = ({ attempts, defaultFilterSettings = {} }) => {
-
+
- {renderDataGrid(viewMode, filteredAttempts, filterSettings, searchSettings, searchContent)} + {renderDataGrid(viewMode, filteredAttempts, controls)}
) } diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.scss b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.scss index 34a2c9b293..5565c02e8f 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.scss +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.scss @@ -15,7 +15,6 @@ border: none; border-bottom: 1px solid $color-shadow; margin: 0; - margin-bottom: 1em; } .settings { @@ -43,7 +42,7 @@ } } - .filters { + .controls { > span { display: inline-block; width: 6em; diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.test.js b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.test.js index 30cbee65ec..3e21a5f2d0 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.test.js @@ -20,8 +20,10 @@ describe('AssessmentStats', () => { assessmentId: 'Assessment-1', userId: 'User-Alpha', assessmentScore: null, - completedAt: 'mock-date', - isPreview: false + completedAt: '2021-08-20T13:42:37.462Z', + isPreview: false, + userFirstName: 'mock-first-name', + userLastName: 'mock-last-name' }, { draftId: 'Draft-A', @@ -31,7 +33,9 @@ describe('AssessmentStats', () => { userId: 'User-Alpha', assessmentScore: 10, completedAt: 'mock-date', - isPreview: true + isPreview: true, + userFirstName: 'mock-first-name', + userLastName: 'mock-last-name' }, { draftId: 'Draft-A', @@ -40,8 +44,10 @@ describe('AssessmentStats', () => { assessmentId: 'Assessment-1', userId: 'User-Alpha', assessmentScore: 0, - completedAt: 'mock-date', - isPreview: false + completedAt: '2021-08-09T13:42:37.462Z', + isPreview: false, + userFirstName: 'mock-first-name', + userLastName: 'mock-last-name' }, { draftId: 'Draft-A', @@ -51,15 +57,17 @@ describe('AssessmentStats', () => { userId: 'User-Alpha', assessmentScore: 100, completedAt: null, - isPreview: false + isPreview: false, + userFirstName: 'mock-first-name', + userLastName: 'mock-last-name' } ] }) test('AssessmentStats renders correctly', () => { - const component = create() + let component = create() - const tree = component.toJSON() + let tree = component.toJSON() expect(tree).toMatchSnapshot() // Change the select to view attempts instead of final assessment score: @@ -73,6 +81,13 @@ describe('AssessmentStats', () => { expect(tree2).toMatchSnapshot() expect(tree).not.toEqual(tree2) + + // AssessmentStats renders with no attempts + component = create() + tree = component.toJSON() + + expect(tree).toMatchSnapshot() + expect(tree).not.toEqual(tree2) }) test('AssessmentStats renders expected number of rows', () => { @@ -154,16 +169,11 @@ describe('AssessmentStats', () => { .findByProps({ className: 'show-incomplete-attempts' }) .props.onChange({ target: { checked: true } }) }) - act(() => { - component.root - .findByProps({ className: 'show-preview-attempts' }) - .props.onChange({ target: { checked: false } }) - }) DataGrid = component.root.findByProps({ className: 'react-data-table-component' }) - expect(DataGrid.props.data.length).toEqual(3) + + expect(DataGrid.props.data.length).toEqual(2) expect(DataGrid.props.data[0].assessmentScore).toEqual(null) expect(DataGrid.props.data[1].assessmentScore).toEqual(0) - expect(DataGrid.props.data[2].assessmentScore).toEqual(100) // Remove incomplete attempts but enable preview attempts act(() => { @@ -194,10 +204,9 @@ describe('AssessmentStats', () => { .props.onChange({ target: { checked: true } }) }) DataGrid = component.root.findByProps({ className: 'react-data-table-component' }) - expect(DataGrid.props.data.length).toEqual(4) + expect(DataGrid.props.data.length).toEqual(3) expect(DataGrid.props.data[0].assessmentScore).toEqual(null) expect(DataGrid.props.data[1].assessmentScore).toEqual(10) expect(DataGrid.props.data[2].assessmentScore).toEqual(0) - expect(DataGrid.props.data[3].assessmentScore).toEqual(100) }) }) diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx index 9ba55e94a5..6a0978aef3 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx @@ -78,14 +78,8 @@ const columns = [ advanced: true }, { - name: 'First Name', - selector: 'userFirstName', - sortable: true, - advanced: false - }, - { - name: 'Last Name', - selector: 'userLastName', + name: 'Student Name', + selector: 'studentName', sortable: true, advanced: false }, @@ -111,7 +105,7 @@ const columns = [ } ] -function DataGridAssessments({ attempts = [], filterSettings, searchSettings, searchContent }) { +function DataGridAssessments({ attempts = [], controls }) { const assessmentScores = getAssessmentStatsFromAttemptStats(attempts) return ( @@ -121,9 +115,7 @@ function DataGridAssessments({ attempts = [], filterSettings, searchSettings, se csvFileName="final-assessment-scores" columns={columns} rows={assessmentScores} - filterSettings={filterSettings} - searchSettings={searchSettings} - searchContent={searchContent} + controls={controls} />
) diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.test.js b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.test.js index 7b42b266c8..1e0ae2fa94 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.test.js @@ -28,15 +28,15 @@ describe('DataGridAssessments', () => { isPreview: true } ], - filterSettings: { + controls: { showIncompleteAttempts: false, showPreviewAttempts: false, - showAdvancedFields: false - }, - searchSettings: 'draft-id', - searchContent: { - text: 'mock', - date: null + showAdvancedFields: false, + searchBy: 'draft-id', + searchContent: { + searchString: 'mock', + date: null + } } }) @@ -50,11 +50,15 @@ describe('DataGridAssessments', () => { test('DataGridAssessments renders without attempts', () => { const component = renderer.create( ) @@ -64,17 +68,24 @@ describe('DataGridAssessments', () => { }) test('DataGridAssessments columns with cell components render as expected', () => { - const component = renderer.create( - - ) - const columns = component.root.findByProps({ className: 'react-data-table-component' }).props + } + } + } + + const component = renderer.create() + const columns = component.root + .findByProps({ className: 'react-data-table-component' }) + .props .columns columns.forEach(col => { diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx index 791accd12f..50e8ee2fbb 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx @@ -77,14 +77,8 @@ const columns = [ advanced: true }, { - name: 'First Name', - selector: 'userFirstName', - sortable: true, - advanced: false - }, - { - name: 'Last Name', - selector: 'userLastName', + name: 'Student Name', + selector: 'studentName', sortable: true, advanced: false }, @@ -194,7 +188,7 @@ const columns = [ } ] -function DataGridAttempts({ attempts = [], filterSettings, searchSettings, searchContent }) { +function DataGridAttempts({ attempts = [], controls }) { return (
) diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.test.js b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.test.js index 322e45bc14..d47b18ae93 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.test.js @@ -36,15 +36,15 @@ describe('DataGridAttempts', () => { isPreview: false } ], - filterSettings: { + controls: { showIncompleteAttempts: false, showPreviewAttempts: false, - showAdvancedFields: false - }, - searchSettings: 'draft-id', - searchContent: { - text: 'mock', - date: null + showAdvancedFields: false, + searchBy: 'draft-id', + searchContent: { + searchString: 'mock', + date: null + } } }) @@ -58,11 +58,15 @@ describe('DataGridAttempts', () => { test('DataGridAttempts renders with no attempts', () => { const component = renderer.create( ) @@ -72,21 +76,24 @@ describe('DataGridAttempts', () => { }) test('DataGridAttempts columns with cell components render as expected', () => { - const component = renderer.create( - - ) - const columns = component.root.findByProps({ className: 'react-data-table-component' }).props + } + } + } + + const component = renderer.create() + const columns = component.root + .findByProps({ className: 'react-data-table-component' }) + .props .columns columns.forEach(col => { diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx index 8186a25e2e..e92715ccd0 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx @@ -15,19 +15,15 @@ const toCSV = (columns, attempts) => { return `${cols}\n${rows.join('\n')}` } -const getFileName = ( - csvFileName, - attempts, - { showIncompleteAttempts, showPreviewAttempts, showAdvancedFields } -) => { +const getFileName = (csvFileName, attempts, controls) => { const drafts = [...new Set(attempts.map(row => row.draftId))] return ( [ csvFileName, - showIncompleteAttempts ? 'with-incomplete-attempts' : '', - showPreviewAttempts ? 'with-preview-attempts' : '', - showAdvancedFields ? 'with-advanced-fields' : '' + controls.showIncompleteAttempts ? 'with-incomplete-attempts' : '', + controls.showPreviewAttempts ? 'with-preview-attempts' : '', + controls.showAdvancedFields ? 'with-advanced-fields' : '' ] .filter(s => s) .join('-') + @@ -36,20 +32,22 @@ const getFileName = ( ) } -const getTableName = (tableName, { showIncompleteAttempts, showPreviewAttempts }) => { - if (showIncompleteAttempts && showPreviewAttempts) { +const getTableName = (tableName, controls) => { + if (controls.showIncompleteAttempts && controls.showPreviewAttempts) { return tableName + ' (including incomplete and preview attempts)' - } else if (showIncompleteAttempts) { + } else if (controls.showIncompleteAttempts) { return tableName + ' (including incomplete attempts)' - } else if (showPreviewAttempts) { + } else if (controls.showPreviewAttempts) { return tableName + ' (including preview attempts)' } return tableName } -const searchDataBasedOnParams = (rows, searchSettings, searchContent) => { - const text = searchContent.text +const searchDataBasedOnParams = (rows, controls) => { + const searchContent = controls.searchContent + + const text = searchContent.searchString const dates = searchContent.date if (rows && rows.length > 0) { @@ -70,16 +68,28 @@ const searchDataBasedOnParams = (rows, searchSettings, searchContent) => { } if (text) { - let param = searchSettings + let param = controls.searchBy .split('-') .map(word => word.charAt(0).toUpperCase() + word.substring(1)) .join('') param = param.charAt(0).toLowerCase() + param.substring(1) - // Filtering according to search params (course title, user's first name, etc) - rows = rows.filter(row => { - return row[param] && row[param].toLowerCase().match(text.toLowerCase()) - }) + // Filtering according to search params (course title, student name, etc) + const processedText = text.toLowerCase().trim() + + if (param === 'studentName') { + rows = rows.filter(row => { + return row[param].toLowerCase().trim() && ( + row.userFirstName.toLowerCase().match(processedText) || + row.userLastName.toLowerCase().match(processedText) || + row.studentName.toLowerCase().match(processedText) + ) + }) + }else { + rows = rows.filter(row => { + return row[param] && row[param].toLowerCase().match(processedText) + }) + } } } return rows @@ -90,17 +100,16 @@ function DataGridScores({ rows = [], tableName, csvFileName, - filterSettings, - searchSettings, - searchContent + controls }) { - const filteredColumns = getColumns(columns, filterSettings.showAdvancedFields) - rows = searchDataBasedOnParams(rows, searchSettings, searchContent) + const filteredColumns = getColumns(columns, controls.showAdvancedFields) + rows = searchDataBasedOnParams(rows, controls) + return (
0 ? ( - ⬇️   Download {filterSettings.showAdvancedFields ? 'Advanced' : ''} Table + ⬇️   Download {controls.showAdvancedFields ? 'Advanced' : ''} Table as CSV File ({rows.length} row {rows.length === 1 ? '' : 's'}) diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js index 8b06a1d13c..f875533876 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js @@ -30,25 +30,31 @@ describe('DataGridScores', () => { { draftId: 'mock-draft-id', exampleId: 'mock-example-id', - completedAt: '2021-02-04T13:55:30.255Z' + completedAt: '2021-02-04T13:55:30.255Z', + userFirstName: 'mock-first-name', + userLastName: 'mock-last-name', + studentName: 'mock-first-name mock-last-name' }, { draftId: 'mock-draft-id2', exampleId: 'mock-example-id2', - completedAt: '2021-06-21T15:32:30.255Z' + completedAt: '2021-06-21T15:32:30.255Z', + userFirstName: 'mock-first-name', + userLastName: 'mock-last-name', + studentName: 'mock-first-name mock-last-name' } ], tableName: 'Mock Table Name', csvFileName: 'mock-csv-file-name', - filterSettings: { + controls: { showIncompleteAttempts: false, showPreviewAttempts: false, - showAdvancedFields: false - }, - searchSettings: 'draft-id', - searchContent: { - text: 'mock', - date: null + showAdvancedFields: false, + searchBy: 'draft-id', + searchContent: { + searchString: 'mock', + date: null + } } }) @@ -76,7 +82,16 @@ describe('DataGridScores', () => { ) expect(component.root.findByType('a').props.download).toBe(expectedCSVFileName) @@ -95,10 +110,15 @@ describe('DataGridScores', () => { const component = renderer.create( ) @@ -113,10 +133,15 @@ describe('DataGridScores', () => { const component1 = renderer.create( ) @@ -135,10 +160,15 @@ describe('DataGridScores', () => { const component2 = renderer.create( ) @@ -165,10 +195,15 @@ describe('DataGridScores', () => { const component1 = renderer.create( ) @@ -178,10 +213,15 @@ describe('DataGridScores', () => { const component2 = renderer.create( ) @@ -193,15 +233,15 @@ describe('DataGridScores', () => { const component = renderer.create( ) @@ -229,10 +269,15 @@ describe('DataGridScores', () => { let component = renderer.create( ) @@ -245,10 +290,15 @@ describe('DataGridScores', () => { component = renderer.create( ) @@ -258,10 +308,15 @@ describe('DataGridScores', () => { component = renderer.create( ) @@ -271,10 +326,15 @@ describe('DataGridScores', () => { component = renderer.create( ) @@ -284,10 +344,15 @@ describe('DataGridScores', () => { component = renderer.create( ) @@ -297,10 +362,15 @@ describe('DataGridScores', () => { component = renderer.create( ) @@ -310,10 +380,15 @@ describe('DataGridScores', () => { component = renderer.create( ) @@ -327,10 +402,68 @@ describe('DataGridScores', () => { component = renderer.create( + ) + expect(component.toJSON()).toMatchSnapshot() + + // Three edge cases where, if the user wants to search by student name, + // obo will look for first and last name matches. + component = renderer.create( + + ) + expect(component.toJSON()).toMatchSnapshot() + + component = renderer.create( + + ) + expect(component.toJSON()).toMatchSnapshot() + + component = renderer.create( + ) diff --git a/packages/app/obojobo-repository/shared/util/get-assessment-stats-from-attempt-stats.js b/packages/app/obojobo-repository/shared/util/get-assessment-stats-from-attempt-stats.js index aa293956bd..8fdd6aa13b 100644 --- a/packages/app/obojobo-repository/shared/util/get-assessment-stats-from-attempt-stats.js +++ b/packages/app/obojobo-repository/shared/util/get-assessment-stats-from-attempt-stats.js @@ -17,6 +17,7 @@ const getAssessmentStatsFromAttemptStats = attempts => { username: attemptRow.userUsername, userFirstName: attemptRow.userFirstName, userLastName: attemptRow.userLastName, + studentName: `${attemptRow.userFirstName} ${attemptRow.userLastName}`, userRoles: attemptRow.userRoles, isPreview: attemptRow.isPreview, contextId: attemptRow.contextId, From df5827f312c6873efddef6a8d1a51ebe86e917e1 Mon Sep 17 00:00:00 2001 From: Mauricio Date: Mon, 16 Aug 2021 09:26:47 -0400 Subject: [PATCH 03/25] Ran prettier on all files --- .../stats/assessment-stats-controls.jsx | 82 +++++++++++-------- .../components/stats/assessment-stats.jsx | 24 ++---- .../components/stats/assessment-stats.test.js | 2 +- .../stats/data-grid-assessments.test.js | 4 +- .../stats/data-grid-attempts.test.js | 4 +- .../components/stats/data-grid-scores.jsx | 23 ++---- 6 files changed, 65 insertions(+), 74 deletions(-) diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx index 82b0b448ee..d6de1fe7c5 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx @@ -15,12 +15,14 @@ const AssessmentStatsControls = ({ controls, onChangeControls, dateBounds }) => const debouncedOnChangeSearchContent = useDebouncedCallback(searchTerm => { const oldControls = Object.assign({}, controls) - onChangeControls(Object.assign(oldControls, { - searchContent: { - searchString: searchTerm, - date: { start: startDate, end: endDate } - } - })) + onChangeControls( + Object.assign(oldControls, { + searchContent: { + searchString: searchTerm, + date: { start: startDate, end: endDate } + } + }) + ) }, SEARCH_INPUT_DEBOUNCE_MS) const onChangeSearchSettings = event => { @@ -50,12 +52,14 @@ const AssessmentStatsControls = ({ controls, onChangeControls, dateBounds }) => setStartDate(newDate) - onChangeControls(Object.assign(oldControls, { - searchContent: { - searchString: textInput, - date: { start: newDate, end: endDate } - } - })) + onChangeControls( + Object.assign(oldControls, { + searchContent: { + searchString: textInput, + date: { start: newDate, end: endDate } + } + }) + ) } const onChangeEndDate = newDate => { @@ -63,42 +67,50 @@ const AssessmentStatsControls = ({ controls, onChangeControls, dateBounds }) => setEndDate(newDate) - onChangeControls(Object.assign(oldControls, { - searchContent: { - searchString: textInput, - date: { start: startDate, end: newDate } - } - })) + onChangeControls( + Object.assign(oldControls, { + searchContent: { + searchString: textInput, + date: { start: startDate, end: newDate } + } + }) + ) } const onChangeShowIncompleteAttempts = event => { const oldControls = Object.assign({}, controls) - onChangeControls(Object.assign(oldControls, { - showPreviewAttempts: controls.showPreviewAttempts, - showAdvancedFields: controls.showAdvancedFields, - showIncompleteAttempts: event.target.checked, - })) + onChangeControls( + Object.assign(oldControls, { + showPreviewAttempts: controls.showPreviewAttempts, + showAdvancedFields: controls.showAdvancedFields, + showIncompleteAttempts: event.target.checked + }) + ) } const onChangeShowPreviewAttempts = event => { const oldControls = Object.assign({}, controls) - onChangeControls(Object.assign(oldControls, { - showIncompleteAttempts: controls.showIncompleteAttempts, - showAdvancedFields: controls.showAdvancedFields, - showPreviewAttempts: event.target.checked, - })) + onChangeControls( + Object.assign(oldControls, { + showIncompleteAttempts: controls.showIncompleteAttempts, + showAdvancedFields: controls.showAdvancedFields, + showPreviewAttempts: event.target.checked + }) + ) } const onChangeShowAdvancedFields = event => { const oldControls = Object.assign({}, controls) - onChangeControls(Object.assign(oldControls, { - showIncompleteAttempts: controls.showIncompleteAttempts, - showPreviewAttempts: controls.showPreviewAttempts, - showAdvancedFields: event.target.checked, - })) + onChangeControls( + Object.assign(oldControls, { + showIncompleteAttempts: controls.showIncompleteAttempts, + showPreviewAttempts: controls.showPreviewAttempts, + showAdvancedFields: event.target.checked + }) + ) } const showTextInput = param !== '' @@ -112,7 +124,9 @@ const AssessmentStatsControls = ({ controls, onChangeControls, dateBounds }) =>
- +
) let day = date.getDate() day = day < 10 ? '0' + day : day @@ -65,7 +51,7 @@ const convertDateForDateInput = (date) => { return `${year}-${month}-${day}` } -const getLowerAndUpperDateBounds = (attempts) => { +const getLowerAndUpperDateBounds = attempts => { if (attempts.length <= 0) return { start: null, end: null } const dates = attempts.map(attempt => new Date(attempt.completedAt)) diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.test.js b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.test.js index 3e21a5f2d0..fabfe74ac8 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.test.js @@ -85,7 +85,7 @@ describe('AssessmentStats', () => { // AssessmentStats renders with no attempts component = create() tree = component.toJSON() - + expect(tree).toMatchSnapshot() expect(tree).not.toEqual(tree2) }) diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.test.js b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.test.js index 1e0ae2fa94..77be1ee75f 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.test.js @@ -83,9 +83,7 @@ describe('DataGridAssessments', () => { } const component = renderer.create() - const columns = component.root - .findByProps({ className: 'react-data-table-component' }) - .props + const columns = component.root.findByProps({ className: 'react-data-table-component' }).props .columns columns.forEach(col => { diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.test.js b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.test.js index d47b18ae93..b1721e5a13 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.test.js @@ -91,9 +91,7 @@ describe('DataGridAttempts', () => { } const component = renderer.create() - const columns = component.root - .findByProps({ className: 'react-data-table-component' }) - .props + const columns = component.root.findByProps({ className: 'react-data-table-component' }).props .columns columns.forEach(col => { diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx index e92715ccd0..b574f604ab 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx @@ -79,13 +79,14 @@ const searchDataBasedOnParams = (rows, controls) => { if (param === 'studentName') { rows = rows.filter(row => { - return row[param].toLowerCase().trim() && ( - row.userFirstName.toLowerCase().match(processedText) || - row.userLastName.toLowerCase().match(processedText) || - row.studentName.toLowerCase().match(processedText) + return ( + row[param].toLowerCase().trim() && + (row.userFirstName.toLowerCase().match(processedText) || + row.userLastName.toLowerCase().match(processedText) || + row.studentName.toLowerCase().match(processedText)) ) }) - }else { + } else { rows = rows.filter(row => { return row[param] && row[param].toLowerCase().match(processedText) }) @@ -95,13 +96,7 @@ const searchDataBasedOnParams = (rows, controls) => { return rows } -function DataGridScores({ - columns, - rows = [], - tableName, - csvFileName, - controls -}) { +function DataGridScores({ columns, rows = [], tableName, csvFileName, controls }) { const filteredColumns = getColumns(columns, controls.showAdvancedFields) rows = searchDataBasedOnParams(rows, controls) @@ -125,8 +120,8 @@ function DataGridScores({ url={`data:text/csv;charset=utf-8,${escape(toCSV(filteredColumns, rows))}`} download={getFileName(csvFileName, rows, controls)} > - ⬇️   Download {controls.showAdvancedFields ? 'Advanced' : ''} Table - as CSV File ({rows.length} row + ⬇️   Download {controls.showAdvancedFields ? 'Advanced' : ''} Table as CSV + File ({rows.length} row {rows.length === 1 ? '' : 's'}) ) : null} From cefa869ba12cbb1251f1b9ee4de8db6a623bdd16 Mon Sep 17 00:00:00 2001 From: Mauricio Date: Mon, 16 Aug 2021 10:09:23 -0400 Subject: [PATCH 04/25] Updated snapshots due to recent UI changes --- .../assessment-score-data-dialog.test.js.snap | 9 ++++--- .../__snapshots__/stats.test.js.snap | 3 ++- .../assessment-stats-controls.test.js.snap | 24 ++++++++++++------- .../assessment-stats.test.js.snap | 9 ++++--- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap b/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap index d49f4a7ced..689d32f482 100644 --- a/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap @@ -76,7 +76,8 @@ exports[`AssessmentScoreDataDialog AssessmentScoreDataDialog renders correctly w
- Search by: + Search by: +
- Search by: + Search by: +
- Search by: + Search by: +
- Search by: + Search by: +
- Search by: + Search by: +
- Search by: + Search by: +
- Search by: + Search by: +
- Search by: + Search by: +
- Search by: + Search by: +
- Search by: + Search by: +
- Search by: + Search by: +
- Search by: + Search by: +
- Search by: + Search by: +
- Search by: + Search by: +
Date: Wed, 18 Aug 2021 11:18:13 -0400 Subject: [PATCH 05/25] Implemented hybrid input and wrapped up most unit tests --- .../hybrid-input-select.test.js.snap | 70 +++++++++ .../shared/components/hybrid-input-select.jsx | 59 ++++++++ .../components/hybrid-input-select.scss | 60 ++++++++ .../components/hybrid-input-select.test.js | 86 +++++++++++ .../stats/assessment-stats-controls.jsx | 19 +-- .../stats/assessment-stats-controls.scss | 7 - .../components/stats/assessment-stats.jsx | 27 +++- .../stats/data-grid-assessments.jsx | 4 +- .../components/stats/data-grid-attempts.jsx | 4 +- .../components/stats/data-grid-scores.jsx | 18 ++- .../shared/util/misc-stats-util.js | 16 +++ .../shared/util/misc-stats-util.test.js | 134 ++++++++++++++++++ 12 files changed, 477 insertions(+), 27 deletions(-) create mode 100644 packages/app/obojobo-repository/shared/components/__snapshots__/hybrid-input-select.test.js.snap create mode 100644 packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx create mode 100644 packages/app/obojobo-repository/shared/components/hybrid-input-select.scss create mode 100644 packages/app/obojobo-repository/shared/components/hybrid-input-select.test.js create mode 100644 packages/app/obojobo-repository/shared/util/misc-stats-util.js create mode 100644 packages/app/obojobo-repository/shared/util/misc-stats-util.test.js diff --git a/packages/app/obojobo-repository/shared/components/__snapshots__/hybrid-input-select.test.js.snap b/packages/app/obojobo-repository/shared/components/__snapshots__/hybrid-input-select.test.js.snap new file mode 100644 index 0000000000..e4f0c141fc --- /dev/null +++ b/packages/app/obojobo-repository/shared/components/__snapshots__/hybrid-input-select.test.js.snap @@ -0,0 +1,70 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`HybridInputSelect renders with a given list and placeholder 1`] = ` +
+ +
+
+ mock-student-one +
+
+ mock-student-two +
+
+ mock-student-three +
+
+ mock-short +
+
+ mock-very-long-student-name... +
+
+ mock-extremely-long-student-name... +
+
+
+`; + +exports[`HybridInputSelect renders with default props 1`] = ` +
+ +
+
+`; diff --git a/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx b/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx new file mode 100644 index 0000000000..ba34df4285 --- /dev/null +++ b/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx @@ -0,0 +1,59 @@ +require('./hybrid-input-select.scss') + +const React = require('react') +const { useState } = require('react') + +const HybridInputSelect = ({ placeholder = 'Enter text', list = [], onChange }) => { + const [text, setText] = useState('') + const [filteredList, setFilteredList] = useState(list) + const [dropdownOpen, setDropdownOpen] = useState(false) + + const handleInputChange = (event) => { + const value = event.target.value + setText(value) + setDropdownOpen(true) + + if (onChange) onChange({ target: { value } }) + + // Filters a given list based on the input text + const newList = list.filter(el => el.toLowerCase().match(value.toLowerCase())) + setFilteredList(newList) + } + + const handleElementClick = (el) => { + setText(el) + setDropdownOpen(false) + } + + const formatElement = (el) => { + if (el && el.length > 18) { + el += '...' + } + return el + } + + let elementsClassName = 'elements ' + elementsClassName += (text && dropdownOpen) ? 'open' : 'closed' + + const elements = filteredList.map((el, ix) => +
handleElementClick(el)}> + {formatElement(el)} +
+ ) + + return ( +
+ +
+ {elements} +
+
+ ) +} + +module.exports = HybridInputSelect diff --git a/packages/app/obojobo-repository/shared/components/hybrid-input-select.scss b/packages/app/obojobo-repository/shared/components/hybrid-input-select.scss new file mode 100644 index 0000000000..fe7f22641d --- /dev/null +++ b/packages/app/obojobo-repository/shared/components/hybrid-input-select.scss @@ -0,0 +1,60 @@ +@import '../../client/css/defaults'; + +.hybrid-input-select { + position: relative; + + input { + @include text-input(); + + width: 100%; + font-size: 0.8em; + padding: 0.6em 0.5em; + border: 0.1em solid $color-shadow; + border-radius: $dimension-rounded-radius; + } + + .elements { + position: absolute; + transition: 0.1s; + overflow-x: hidden; + top: 2.5em; + border-radius: $dimension-rounded-radius; + box-shadow: 0 1em 0.5em $color-shadow; + border: 0.0001em solid $color-banner-bg; + + &.open { + max-height: 5em; + overflow-y: auto; + width: 100%; + opacity: 1; + transition: 0.2s; + } + + &.closed { + height: 0; + line-height: 0; + overflow: hidden; + opacity: 0; + transition: 0.2s; + } + + .element { + width: 100%; + font-size: 0.8em; + transition: 0.1s; + background-color: $color-bg; + padding-left: 0.65em; + overflow-x: hidden; + + &:hover { + cursor: pointer; + transition: 0.1s; + background-color: desaturate(lighten($color-action, 45%), 40%) + } + + &:not(:first-child) { + border-top: 0.0001em solid $color-banner-bg; + } + } + } +} diff --git a/packages/app/obojobo-repository/shared/components/hybrid-input-select.test.js b/packages/app/obojobo-repository/shared/components/hybrid-input-select.test.js new file mode 100644 index 0000000000..8d552b789b --- /dev/null +++ b/packages/app/obojobo-repository/shared/components/hybrid-input-select.test.js @@ -0,0 +1,86 @@ +import React from 'react' +import HybridInputSelect from './hybrid-input-select' +import { create, act } from 'react-test-renderer' + +describe('HybridInputSelect', () => { + test('renders with default props', () => { + const component = create() + + const tree = component.toJSON() + expect(tree).toMatchSnapshot() + }) + + test('renders with a given list and placeholder', () => { + const mockProps = { + placeholder: 'Mock placeholder', + list: [ + 'mock-student-one', + 'mock-student-two', + 'mock-student-three', + 'mock-short', + 'mock-very-long-student-name', + 'mock-extremely-long-student-name' + ] + } + const component = create() + + const tree = component.toJSON() + expect(tree).toMatchSnapshot() + }) + + test('input is updated and list is filtered as expected', () => { + // Without onChange prop + let mockProps = { + placeholder: 'Mock placeholder', + list: [ + 'mock-student-one', + 'mock-student-two', + 'mock-student-three' + ] + } + let component = create() + + let input = component.root.findByProps({ type: 'text' }) + act(() => { + input.props.onChange({ target: { value: 'mock-search-string' }}) + }) + expect(input.props.value).toBe('mock-search-string') + + // With onChange prop + mockProps = { ...mockProps, onChange: jest.fn() } + component = create() + + input = component.root.findByProps({ type: 'text' }) + act(() => { + input.props.onChange({ target: { value: 'mock-search-string' }}) + }) + expect(input.props.value).toBe('mock-search-string') + }) + + test('clicking on an element sets input value to element\'s text', () => { + const mockProps = { + placeholder: 'Mock placeholder', + list: [ + 'mock-student-one', + 'mock-student-two', + 'mock-student-three' + ], + onChange: jest.fn() + } + const component = create() + + // Populating input so that the dropdown opens + const input = component.root.findByProps({ type: 'text' }) + act(() => { + input.props.onChange({ target: { value: 'mock' }}) + }) + + // Selecting an element from the dropdown + const element = component.root.findAllByProps({ className: 'element' })[0] + act(() => { + element.props.onClick('mock-student-one') + }) + + expect(input.props.value).toBe('mock-student-one') + }) +}) diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx index d6de1fe7c5..620ac84f6b 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx @@ -3,10 +3,12 @@ require('./assessment-stats-controls.scss') const { useDebouncedCallback } = require('use-debounce') const React = require('react') const Button = require('../button') +const HybridInputSelect = require('../hybrid-input-select') +const { convertHyphenBasedStringToCamelCase } = require('../../util/misc-stats-util') const SEARCH_INPUT_DEBOUNCE_MS = 500 -const AssessmentStatsControls = ({ controls, onChangeControls, dateBounds }) => { +const AssessmentStatsControls = ({ controls, onChangeControls, dateBounds, allPossibleValues }) => { const [param, setParam] = React.useState('') const [endDate, setEndDate] = React.useState('') const [textInput, setTextInput] = React.useState('') @@ -113,7 +115,10 @@ const AssessmentStatsControls = ({ controls, onChangeControls, dateBounds }) => ) } - const showTextInput = param !== '' + const valuesForHybridInput = allPossibleValues.map(row => + row[convertHyphenBasedStringToCamelCase(param)]) + + const showHybridInput = param !== '' const textPlaceholder = param .split('-') @@ -137,13 +142,11 @@ const AssessmentStatsControls = ({ controls, onChangeControls, dateBounds }) => - {showTextInput && ( - )}
diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss index 91d42faa39..07858890f7 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss @@ -28,13 +28,6 @@ width: 100%; } - .text-input { - border-radius: $dimension-rounded-radius; - padding: 0.6em 0.5em; - font-size: 0.8em; - border: 0.1em solid $color-shadow; - } - .controls { display: flex; flex-direction: column; diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx index 2745a74f30..634004e9ee 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx @@ -8,14 +8,28 @@ const AssessmentStatsControls = require('./assessment-stats-controls') const VIEW_MODE_FINAL_ASSESSMENT_SCORE = 'final-assessment-scores' const VIEW_MODE_ALL_ATTEMPTS = 'all-attempts' -const renderDataGrid = (viewMode, filteredAttempts, controls) => { +const renderDataGrid = (viewMode, filteredAttempts, controls, filteredRows, setFilteredRows) => { switch (viewMode) { case VIEW_MODE_ALL_ATTEMPTS: - return + return ( + + ) case VIEW_MODE_FINAL_ASSESSMENT_SCORE: default: - return + return ( + + ) } } @@ -79,6 +93,10 @@ const AssessmentStats = ({ attempts, defaultFilterSettings = {} }) => { ) ) + // Used in order to display all possible values based on parameter search in + // obo's hybrid text-input/select component. + const [filteredRows, setFilteredRows] = React.useState([]) + const onChangeViewMode = event => { setViewMode(event.target.value) } @@ -103,11 +121,12 @@ const AssessmentStats = ({ attempts, defaultFilterSettings = {} }) => { controls={controls} dateBounds={dateBounds} onChangeControls={setControls} + allPossibleValues={filteredRows} />
- {renderDataGrid(viewMode, filteredAttempts, controls)} + {renderDataGrid(viewMode, filteredAttempts, controls, filteredRows, setFilteredRows)}
) } diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx index 6a0978aef3..f5b28795a2 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx @@ -105,7 +105,7 @@ const columns = [ } ] -function DataGridAssessments({ attempts = [], controls }) { +function DataGridAssessments({ attempts = [], controls, filteredRows, setFilteredRows }) { const assessmentScores = getAssessmentStatsFromAttemptStats(attempts) return ( @@ -116,6 +116,8 @@ function DataGridAssessments({ attempts = [], controls }) { columns={columns} rows={assessmentScores} controls={controls} + filteredRows={filteredRows} + setFilteredRows={setFilteredRows} />
) diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx index 50e8ee2fbb..ccd47ce828 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx @@ -188,7 +188,7 @@ const columns = [ } ] -function DataGridAttempts({ attempts = [], controls }) { +function DataGridAttempts({ attempts = [], controls, filteredRows, setFilteredRows }) { return (
) diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx index b574f604ab..3ffb9f8dbf 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx @@ -1,6 +1,7 @@ const React = require('react') const DataTable = require('react-data-table-component').default const ButtonLink = require('../button-link') +const { convertHyphenBasedStringToCamelCase, equals } = require('../../util/misc-stats-util') const getColumns = (columns, showAdvancedFields) => showAdvancedFields ? columns : columns.filter(col => !col.advanced) @@ -68,11 +69,7 @@ const searchDataBasedOnParams = (rows, controls) => { } if (text) { - let param = controls.searchBy - .split('-') - .map(word => word.charAt(0).toUpperCase() + word.substring(1)) - .join('') - param = param.charAt(0).toLowerCase() + param.substring(1) + let param = convertHyphenBasedStringToCamelCase(controls.searchBy) // Filtering according to search params (course title, student name, etc) const processedText = text.toLowerCase().trim() @@ -96,9 +93,18 @@ const searchDataBasedOnParams = (rows, controls) => { return rows } -function DataGridScores({ columns, rows = [], tableName, csvFileName, controls }) { +function DataGridScores({ + columns, + rows = [], + tableName, + csvFileName, + controls, + filteredRows, + setFilteredRows +}) { const filteredColumns = getColumns(columns, controls.showAdvancedFields) rows = searchDataBasedOnParams(rows, controls) + if (rows && rows.length > 0 && !equals(rows, filteredRows)) setFilteredRows(rows) return (
diff --git a/packages/app/obojobo-repository/shared/util/misc-stats-util.js b/packages/app/obojobo-repository/shared/util/misc-stats-util.js new file mode 100644 index 0000000000..624036e1cd --- /dev/null +++ b/packages/app/obojobo-repository/shared/util/misc-stats-util.js @@ -0,0 +1,16 @@ +const convertHyphenBasedStringToCamelCase = (s) => { + // E.g. camel-case ---> camelCase + let camel = s + .split('-') + .map(word => word.charAt(0).toUpperCase() + word.substring(1)) + .join('') + camel = camel.charAt(0).toLowerCase() + camel.substring(1) + return camel +} + +const equals = (arr1, arr2) => JSON.stringify(arr1) === JSON.stringify(arr2) + +module.exports = { + convertHyphenBasedStringToCamelCase, + equals +} diff --git a/packages/app/obojobo-repository/shared/util/misc-stats-util.test.js b/packages/app/obojobo-repository/shared/util/misc-stats-util.test.js new file mode 100644 index 0000000000..94423774ee --- /dev/null +++ b/packages/app/obojobo-repository/shared/util/misc-stats-util.test.js @@ -0,0 +1,134 @@ +const { + equals, + convertHyphenBasedStringToCamelCase +} = require('./misc-stats-util') + +describe('miscStatsUtil', () => { + test('equals returns expected values', () => { + let arr1 = [ + { + assessmentId: "my-assessment", + courseTitle: null, + draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", + draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", + isPreview: true, + moduleTitle: "My Obojobo Module Title", + resourceLinkId: "preview", + userFirstName: "Test", + userLastName: "Instructor1" + }, + { + assessmentId: "my-assessment", + courseTitle: null, + draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", + draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", + isPreview: true, + moduleTitle: "My Obojobo Module Title", + resourceLinkId: "preview", + userFirstName: "Test", + userLastName: "Instructor1" + } + ] + + let arr2 = [ + { + assessmentId: "my-assessment", + courseTitle: null, + draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", + draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", + isPreview: true, + moduleTitle: "My Obojobo Module Title", + userFirstName: "Test", + userLastName: "Instructor1", + resourceLinkId: "preview" + }, + { + assessmentId: "my-assessment", + courseTitle: null, + draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", + draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", + isPreview: true, + moduleTitle: "My Obojobo Module Title", + resourceLinkId: "preview", + userFirstName: "Test", + userLastName: "Instructor1" + } + ] + + expect(equals(arr1, arr2)).toBe(false) + + arr1 = [ + { + assessmentId: "my-assessment", + courseTitle: null, + draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", + draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", + isPreview: true, + moduleTitle: "My Obojobo Module Title", + resourceLinkId: "preview", + userFirstName: "Test", + userLastName: "Instructor1" + } + ] + + arr2 = [ + { + assessmentId: "my-assessment-two", + courseTitle: null, + draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", + draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", + isPreview: true, + moduleTitle: "My Obojobo Module Title", + resourceLinkId: "preview", + userFirstName: "Test", + userLastName: "Instructor1" + } + ] + + expect(equals(arr1, arr2)).toBe(false) + + arr1 = [ + { + assessmentId: "my-assessment", + courseTitle: null, + draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", + draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", + isPreview: true, + moduleTitle: "My Obojobo Module Title", + resourceLinkId: "preview", + userFirstName: "Test", + userLastName: "Instructor1" + } + ] + + arr2 = [ + { + assessmentId: "my-assessment", + courseTitle: null, + draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", + draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", + isPreview: true, + moduleTitle: "My Obojobo Module Title", + resourceLinkId: "preview", + userFirstName: "Test", + userLastName: "Instructor1" + } + ] + + expect(equals(arr1, arr2)).toBe(true) + }) + + test('convertHyphenBasedStringToCamelCase converts strings as expected', () => { + let str = convertHyphenBasedStringToCamelCase('mock-student-name') + expect(str).toBe('mockStudentName') + + str = convertHyphenBasedStringToCamelCase('o-b-o') + expect(str).toBe('oBO') + + str = convertHyphenBasedStringToCamelCase('123') + expect(str).toBe('123') + + str = convertHyphenBasedStringToCamelCase('1-2-3') + expect(str).toBe('123') + }) +}) From 91ad846b18e5cc6662b6d7adee90af2f862409bf Mon Sep 17 00:00:00 2001 From: Mauricio Date: Tue, 24 Aug 2021 13:13:40 -0400 Subject: [PATCH 06/25] Implemented hybrid input component --- .../shared/components/hybrid-input-select.jsx | 12 +++++++----- .../shared/components/hybrid-input-select.scss | 4 ++++ .../components/stats/assessment-stats-controls.jsx | 4 ++-- .../stats/assessment-stats-controls.test.js | 5 +++++ .../shared/components/stats/assessment-stats.jsx | 2 +- .../shared/components/stats/assessment-stats.test.js | 3 ++- .../components/stats/data-grid-assessments.test.js | 3 ++- .../components/stats/data-grid-attempts.test.js | 3 ++- .../shared/components/stats/data-grid-scores.jsx | 5 ++++- .../shared/components/stats/data-grid-scores.test.js | 3 ++- 10 files changed, 31 insertions(+), 13 deletions(-) diff --git a/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx b/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx index ba34df4285..dbbcc66468 100644 --- a/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx +++ b/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx @@ -16,7 +16,7 @@ const HybridInputSelect = ({ placeholder = 'Enter text', list = [], onChange }) if (onChange) onChange({ target: { value } }) // Filters a given list based on the input text - const newList = list.filter(el => el.toLowerCase().match(value.toLowerCase())) + const newList = list.filter(el => el && el.toLowerCase().match(value.toLowerCase())) setFilteredList(newList) } @@ -26,21 +26,23 @@ const HybridInputSelect = ({ placeholder = 'Enter text', list = [], onChange }) } const formatElement = (el) => { - if (el && el.length > 18) { - el += '...' - } + if (el && el.length > 18) el += '...' return el } let elementsClassName = 'elements ' elementsClassName += (text && dropdownOpen) ? 'open' : 'closed' - const elements = filteredList.map((el, ix) => + let elements = filteredList.map((el, ix) =>
handleElementClick(el)}> {formatElement(el)}
) + if (elements.length === 0) elements = [ +
No matches found
+ ] + return (
{ +const AssessmentStatsControls = ({ controls, onChangeControls, dateBounds, dropdownValues = [] }) => { const [param, setParam] = React.useState('') const [endDate, setEndDate] = React.useState('') const [textInput, setTextInput] = React.useState('') @@ -115,7 +115,7 @@ const AssessmentStatsControls = ({ controls, onChangeControls, dateBounds, allPo ) } - const valuesForHybridInput = allPossibleValues.map(row => + const valuesForHybridInput = dropdownValues.map(row => row[convertHyphenBasedStringToCamelCase(param)]) const showHybridInput = param !== '' diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js index 2065b8fc64..d5e759ac59 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js @@ -35,6 +35,7 @@ describe('AssessmentStatsControls', () => { onChangeControls={jest.fn()} controls={{ showIncompleteAttempts, showPreviewAttempts, showAdvancedFields }} dateBounds={{ start: null, end: null }} + dropdownValues={['mock-student-one', 'mock-student-two']} /> ) const tree = component.toJSON() @@ -54,6 +55,7 @@ describe('AssessmentStatsControls', () => { showAdvancedFields: false }} dateBounds={{ start: null, end: null }} + dropdownValues={['mock-student-one', 'mock-student-two']} /> ) @@ -133,6 +135,7 @@ describe('AssessmentStatsControls', () => { }} dateBounds={{ start: null, end: null }} onChangeControls={onChangeControls} + dropdownValues={['mock-student-one', 'mock-student-two']} /> ) @@ -170,6 +173,7 @@ describe('AssessmentStatsControls', () => { }} dateBounds={{ start: null, end: null }} onChangeControls={onChangeControls} + dropdownValues={['mock-student-one', 'mock-student-two']} /> ) @@ -199,6 +203,7 @@ describe('AssessmentStatsControls', () => { }} dateBounds={{ start: null, end: null }} onChangeControls={onChangeControls} + dropdownValues={['mock-student-one', 'mock-student-two']} /> ) diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx index 634004e9ee..87d676d4e8 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx @@ -121,7 +121,7 @@ const AssessmentStats = ({ attempts, defaultFilterSettings = {} }) => { controls={controls} dateBounds={dateBounds} onChangeControls={setControls} - allPossibleValues={filteredRows} + dropdownValues={filteredRows} />
diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.test.js b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.test.js index fabfe74ac8..7a28eb9ce3 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.test.js @@ -61,7 +61,8 @@ describe('AssessmentStats', () => { userFirstName: 'mock-first-name', userLastName: 'mock-last-name' } - ] + ], + filteredRows: [] }) test('AssessmentStats renders correctly', () => { diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.test.js b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.test.js index 77be1ee75f..45171537d7 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.test.js @@ -37,7 +37,8 @@ describe('DataGridAssessments', () => { searchString: 'mock', date: null } - } + }, + setFilteredRows: () => {} }) test('DataGridAssessments renders correctly', () => { diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.test.js b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.test.js index b1721e5a13..085f62e0bd 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.test.js @@ -45,7 +45,8 @@ describe('DataGridAttempts', () => { searchString: 'mock', date: null } - } + }, + setFilteredRows: () => {} }) test('DataGridAttempts renders correctly', () => { diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx index 3ffb9f8dbf..68fe1e33e8 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx @@ -104,7 +104,10 @@ function DataGridScores({ }) { const filteredColumns = getColumns(columns, controls.showAdvancedFields) rows = searchDataBasedOnParams(rows, controls) - if (rows && rows.length > 0 && !equals(rows, filteredRows)) setFilteredRows(rows) + + React.useEffect(() => { + if (rows && rows.length > 0 && !equals(rows, filteredRows)) setFilteredRows(rows) + }, [rows]) return (
diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js index f875533876..e9b4dfca6e 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js @@ -55,7 +55,8 @@ describe('DataGridScores', () => { searchString: 'mock', date: null } - } + }, + setFilteredRows: () => {} }) test('DataGridScores renders correctly', () => { From 9635eb6ffc678f51ab0b59c8f732e2eb0b01f4d4 Mon Sep 17 00:00:00 2001 From: Mauricio Date: Thu, 26 Aug 2021 13:33:12 -0400 Subject: [PATCH 07/25] Wrapped up debounce indicator and its unit tests --- .../assessment-score-data-dialog.test.js.snap | 30 +++- .../hybrid-input-select.test.js.snap | 8 +- .../__snapshots__/spinner.test.js.snap | 30 ++++ .../__snapshots__/stats.test.js.snap | 10 +- .../components/hybrid-input-select.scss | 2 +- .../shared/components/spinner.jsx | 30 ++++ .../shared/components/spinner.scss | 40 +++++ .../shared/components/spinner.test.js | 16 ++ .../assessment-stats.test.js.snap | 30 +++- .../data-grid-assessments.test.js.snap | 20 ++- .../data-grid-attempts.test.js.snap | 20 ++- .../data-grid-scores.test.js.snap | 137 ++++++++++++++++-- .../stats/assessment-stats-controls.jsx | 10 +- .../stats/assessment-stats-controls.test.js | 10 ++ .../components/stats/assessment-stats.jsx | 15 +- .../components/stats/assessment-stats.scss | 8 + .../stats/data-grid-assessments.jsx | 3 +- .../components/stats/data-grid-attempts.jsx | 3 +- .../components/stats/data-grid-scores.jsx | 18 ++- 19 files changed, 406 insertions(+), 34 deletions(-) create mode 100644 packages/app/obojobo-repository/shared/components/__snapshots__/spinner.test.js.snap create mode 100644 packages/app/obojobo-repository/shared/components/spinner.jsx create mode 100644 packages/app/obojobo-repository/shared/components/spinner.scss create mode 100644 packages/app/obojobo-repository/shared/components/spinner.test.js diff --git a/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap b/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap index 689d32f482..99d2980bf1 100644 --- a/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap @@ -275,7 +275,15 @@ exports[`AssessmentScoreDataDialog AssessmentScoreDataDialog renders correctly w ] } striped={true} - title="Final Assessment Scores" + title={ +
+

+ Final Assessment Scores +

+
+ } > react-data-table-component
@@ -562,7 +570,15 @@ exports[`AssessmentScoreDataDialog AssessmentScoreDataDialog renders correctly w ] } striped={true} - title="Final Assessment Scores" + title={ +
+

+ Final Assessment Scores +

+
+ } > react-data-table-component
@@ -849,7 +865,15 @@ exports[`AssessmentScoreDataDialog AssessmentScoreDataDialog renders correctly w ] } striped={true} - title="Final Assessment Scores" + title={ +
+

+ Final Assessment Scores +

+
+ } > react-data-table-component
diff --git a/packages/app/obojobo-repository/shared/components/__snapshots__/hybrid-input-select.test.js.snap b/packages/app/obojobo-repository/shared/components/__snapshots__/hybrid-input-select.test.js.snap index e4f0c141fc..7bdfa69bbb 100644 --- a/packages/app/obojobo-repository/shared/components/__snapshots__/hybrid-input-select.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/__snapshots__/hybrid-input-select.test.js.snap @@ -65,6 +65,12 @@ exports[`HybridInputSelect renders with default props 1`] = ` />
+ > +
+ No matches found +
+
`; diff --git a/packages/app/obojobo-repository/shared/components/__snapshots__/spinner.test.js.snap b/packages/app/obojobo-repository/shared/components/__snapshots__/spinner.test.js.snap new file mode 100644 index 0000000000..5f988a34e6 --- /dev/null +++ b/packages/app/obojobo-repository/shared/components/__snapshots__/spinner.test.js.snap @@ -0,0 +1,30 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Spinner Spinner component 1`] = ` +
+
+ + + +
+
+`; diff --git a/packages/app/obojobo-repository/shared/components/__snapshots__/stats.test.js.snap b/packages/app/obojobo-repository/shared/components/__snapshots__/stats.test.js.snap index 21890192b5..1171d28fbd 100644 --- a/packages/app/obojobo-repository/shared/components/__snapshots__/stats.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/__snapshots__/stats.test.js.snap @@ -492,7 +492,15 @@ exports[`Stats Renders loaded state correctly 1`] = ` ] } striped={true} - title="Final Assessment Scores" + title={ +
+

+ Final Assessment Scores +

+
+ } > react-data-table-component
diff --git a/packages/app/obojobo-repository/shared/components/hybrid-input-select.scss b/packages/app/obojobo-repository/shared/components/hybrid-input-select.scss index 5847937cf4..5824a833eb 100644 --- a/packages/app/obojobo-repository/shared/components/hybrid-input-select.scss +++ b/packages/app/obojobo-repository/shared/components/hybrid-input-select.scss @@ -19,7 +19,7 @@ overflow-x: hidden; top: 2.5em; border-radius: $dimension-rounded-radius; - box-shadow: 0 1em 0.5em $color-shadow; + box-shadow: 0 0.3em 0.2em $color-shadow; border: 0.0001em solid $color-banner-bg; &.open { diff --git a/packages/app/obojobo-repository/shared/components/spinner.jsx b/packages/app/obojobo-repository/shared/components/spinner.jsx new file mode 100644 index 0000000000..e9f497deb3 --- /dev/null +++ b/packages/app/obojobo-repository/shared/components/spinner.jsx @@ -0,0 +1,30 @@ +require('./spinner.scss') + +const React = require('react') + +function Spinner({ color = 'black' }) { + return ( +
+
+ + + +
+
+ ) +} + +module.exports = Spinner diff --git a/packages/app/obojobo-repository/shared/components/spinner.scss b/packages/app/obojobo-repository/shared/components/spinner.scss new file mode 100644 index 0000000000..2391ad97f4 --- /dev/null +++ b/packages/app/obojobo-repository/shared/components/spinner.scss @@ -0,0 +1,40 @@ +@import '../../client/css/defaults'; + +.obojobo-draft--components--spinner { + position: absolute; + width: 1em; + height: 1em; + top: 1em; + right: 0.5em; + display: inline-block; + background-color: $color-bg; + + > .spinner { + @keyframes obojobo-draft--components--spinner--rotate { + from { + transform: translate(-50%, -50%) rotate(0deg); + } + + to { + transform: translate(-50%, -50%) rotate(360deg); + } + } + + width: 100%; + height: 100%; + display: inline-block; + position: absolute; + left: 50%; + top: 50%; + animation: obojobo-draft--components--spinner--rotate 1.5s linear infinite; + + > svg { + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + background: none; + } + } +} diff --git a/packages/app/obojobo-repository/shared/components/spinner.test.js b/packages/app/obojobo-repository/shared/components/spinner.test.js new file mode 100644 index 0000000000..4c3e1f4346 --- /dev/null +++ b/packages/app/obojobo-repository/shared/components/spinner.test.js @@ -0,0 +1,16 @@ +import React from 'react' +import Spinner from './spinner' +import { create, act } from 'react-test-renderer' + +describe('Spinner', () => { + test('Spinner component', async () => { + let component + await act(async () => { + component = create() + }) + + const tree = component.toJSON() + + expect(tree).toMatchSnapshot() + }) +}) diff --git a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/assessment-stats.test.js.snap b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/assessment-stats.test.js.snap index aa56f72fbf..b71c1d76e7 100644 --- a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/assessment-stats.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/assessment-stats.test.js.snap @@ -267,7 +267,15 @@ exports[`AssessmentStats AssessmentStats renders correctly 1`] = ` ] } striped={true} - title="Final Assessment Scores" + title={ +
+

+ Final Assessment Scores +

+
+ } > react-data-table-component
@@ -622,7 +630,15 @@ exports[`AssessmentStats AssessmentStats renders correctly 2`] = ` ] } striped={true} - title="Attempt Scores" + title={ +
+

+ Attempt Scores +

+
+ } > react-data-table-component
@@ -889,7 +905,15 @@ exports[`AssessmentStats AssessmentStats renders correctly 3`] = ` ] } striped={true} - title="Final Assessment Scores" + title={ +
+

+ Final Assessment Scores +

+
+ } > react-data-table-component
diff --git a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-assessments.test.js.snap b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-assessments.test.js.snap index 549c8fa77d..8ec093465c 100644 --- a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-assessments.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-assessments.test.js.snap @@ -145,7 +145,15 @@ exports[`DataGridAssessments DataGridAssessments renders correctly 1`] = ` ] } striped={true} - title="Final Assessment Scores" + title={ +
+

+ Final Assessment Scores +

+
+ } > react-data-table-component
@@ -237,7 +245,15 @@ exports[`DataGridAssessments DataGridAssessments renders without attempts 1`] = ] } striped={true} - title="Final Assessment Scores" + title={ +
+

+ Final Assessment Scores +

+
+ } > react-data-table-component
diff --git a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap index e3fb10dd3b..c6bbf1ac56 100644 --- a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap @@ -222,7 +222,15 @@ exports[`DataGridAttempts DataGridAttempts renders correctly 1`] = ` ] } striped={true} - title="Attempt Scores" + title={ +
+

+ Attempt Scores +

+
+ } > react-data-table-component
@@ -373,7 +381,15 @@ exports[`DataGridAttempts DataGridAttempts renders with no attempts 1`] = ` ] } striped={true} - title="Attempt Scores" + title={ +
+

+ Attempt Scores +

+
+ } > react-data-table-component
diff --git a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap index e108dcd5a2..d17fd94100 100644 --- a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap @@ -57,7 +57,15 @@ exports[`DataGridScores DataGridScores renders correctly 1`] = ` ] } striped={true} - title="Mock Table Name" + title={ +
+

+ Mock Table Name +

+
+ } > react-data-table-component
@@ -123,7 +131,15 @@ exports[`DataGridScores DataGridScores renders one row 1`] = ` ] } striped={true} - title="Mock Table Name" + title={ +
+

+ Mock Table Name +

+
+ } > react-data-table-component
@@ -169,6 +185,13 @@ exports[`DataGridScores DataGridScores renders when no rows given 1`] = ` ] } striped={true} + title={ +
+

+

+ } > react-data-table-component
@@ -210,7 +233,15 @@ exports[`DataGridScores DataGridScores uses search filters as expected 1`] = ` ] } striped={true} - title="Mock Table Name" + title={ +
+

+ Mock Table Name +

+
+ } > react-data-table-component
@@ -252,7 +283,15 @@ exports[`DataGridScores DataGridScores uses search filters as expected 2`] = ` ] } striped={true} - title="Mock Table Name" + title={ +
+

+ Mock Table Name +

+
+ } > react-data-table-component
@@ -294,7 +333,15 @@ exports[`DataGridScores DataGridScores uses search filters as expected 3`] = ` ] } striped={true} - title="Mock Table Name" + title={ +
+

+ Mock Table Name +

+
+ } > react-data-table-component
@@ -355,7 +402,15 @@ exports[`DataGridScores DataGridScores uses search filters as expected 4`] = ` ] } striped={true} - title="Mock Table Name" + title={ +
+

+ Mock Table Name +

+
+ } > react-data-table-component
@@ -429,7 +484,15 @@ exports[`DataGridScores DataGridScores uses search filters as expected 5`] = ` ] } striped={true} - title="Mock Table Name" + title={ +
+

+ Mock Table Name +

+
+ } > react-data-table-component
@@ -503,7 +566,15 @@ exports[`DataGridScores DataGridScores uses search filters as expected 6`] = ` ] } striped={true} - title="Mock Table Name" + title={ +
+

+ Mock Table Name +

+
+ } > react-data-table-component
@@ -558,7 +629,15 @@ exports[`DataGridScores DataGridScores uses search filters as expected 7`] = ` ] } striped={true} - title="Mock Table Name" + title={ +
+

+ Mock Table Name +

+
+ } > react-data-table-component @@ -600,7 +679,15 @@ exports[`DataGridScores DataGridScores uses search filters as expected 8`] = ` ] } striped={true} - title="Mock Table Name" + title={ +
+

+ Mock Table Name +

+
+ } > react-data-table-component @@ -661,7 +748,15 @@ exports[`DataGridScores DataGridScores uses search filters as expected 9`] = ` ] } striped={true} - title="Mock Table Name" + title={ +
+

+ Mock Table Name +

+
+ } > react-data-table-component @@ -735,7 +830,15 @@ exports[`DataGridScores DataGridScores uses search filters as expected 10`] = ` ] } striped={true} - title="Mock Table Name" + title={ +
+

+ Mock Table Name +

+
+ } > react-data-table-component @@ -809,7 +912,15 @@ exports[`DataGridScores DataGridScores uses search filters as expected 11`] = ` ] } striped={true} - title="Mock Table Name" + title={ +
+

+ Mock Table Name +

+
+ } > react-data-table-component diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx index 72e028c510..1e957a44b7 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx @@ -8,13 +8,20 @@ const { convertHyphenBasedStringToCamelCase } = require('../../util/misc-stats-u const SEARCH_INPUT_DEBOUNCE_MS = 500 -const AssessmentStatsControls = ({ controls, onChangeControls, dateBounds, dropdownValues = [] }) => { +const AssessmentStatsControls = ({ + controls, + onChangeControls, + dateBounds, + dropdownValues = [], + setIsDebouncing +}) => { const [param, setParam] = React.useState('') const [endDate, setEndDate] = React.useState('') const [textInput, setTextInput] = React.useState('') const [startDate, setStartDate] = React.useState('') const debouncedOnChangeSearchContent = useDebouncedCallback(searchTerm => { + setIsDebouncing(false) const oldControls = Object.assign({}, controls) onChangeControls( @@ -42,6 +49,7 @@ const AssessmentStatsControls = ({ controls, onChangeControls, dateBounds, dropd setTextInput(value) debouncedOnChangeSearchContent(value) + setIsDebouncing(true) // If the user clears out the input go ahead and update the search without a delay if (value.length === 0) { diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js index d5e759ac59..62f427c4c7 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.test.js @@ -45,6 +45,7 @@ describe('AssessmentStatsControls', () => { test('Inputs work as expected', () => { const onChangeControls = jest.fn() + const setIsDebouncing = jest.fn() const component = renderer.create( { }} dateBounds={{ start: null, end: null }} dropdownValues={['mock-student-one', 'mock-student-two']} + setIsDebouncing={setIsDebouncing} /> ) @@ -97,6 +99,7 @@ describe('AssessmentStatsControls', () => { test('Inputs and select tags work as expected', () => { const onChangeControls = jest.fn() + const setIsDebouncing = jest.fn() const component = renderer.create( { }} dateBounds={{ start: null, end: null }} onChangeControls={onChangeControls} + setIsDebouncing={setIsDebouncing} /> ) @@ -125,6 +129,7 @@ describe('AssessmentStatsControls', () => { test('Change input based on select option', () => { const onChangeControls = jest.fn() + const setIsDebouncing = jest.fn() const component = renderer.create( { dateBounds={{ start: null, end: null }} onChangeControls={onChangeControls} dropdownValues={['mock-student-one', 'mock-student-two']} + setIsDebouncing={setIsDebouncing} /> ) @@ -163,6 +169,7 @@ describe('AssessmentStatsControls', () => { test('Set and clear date start input', () => { const onChangeControls = jest.fn() + const setIsDebouncing = jest.fn() const component = renderer.create( { dateBounds={{ start: null, end: null }} onChangeControls={onChangeControls} dropdownValues={['mock-student-one', 'mock-student-two']} + setIsDebouncing={setIsDebouncing} /> ) @@ -193,6 +201,7 @@ describe('AssessmentStatsControls', () => { test('Set and clear date end input', () => { const onChangeControls = jest.fn() + const setIsDebouncing = jest.fn() const component = renderer.create( { dateBounds={{ start: null, end: null }} onChangeControls={onChangeControls} dropdownValues={['mock-student-one', 'mock-student-two']} + setIsDebouncing={setIsDebouncing} /> ) diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx index 87d676d4e8..e716f9df27 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx @@ -8,7 +8,14 @@ const AssessmentStatsControls = require('./assessment-stats-controls') const VIEW_MODE_FINAL_ASSESSMENT_SCORE = 'final-assessment-scores' const VIEW_MODE_ALL_ATTEMPTS = 'all-attempts' -const renderDataGrid = (viewMode, filteredAttempts, controls, filteredRows, setFilteredRows) => { +const renderDataGrid = ( + viewMode, + filteredAttempts, + controls, + filteredRows, + setFilteredRows, + isDebouncing +) => { switch (viewMode) { case VIEW_MODE_ALL_ATTEMPTS: return ( @@ -17,6 +24,7 @@ const renderDataGrid = (viewMode, filteredAttempts, controls, filteredRows, setF controls={controls} filteredRows={filteredRows} setFilteredRows={setFilteredRows} + isDebouncing={isDebouncing} /> ) @@ -28,6 +36,7 @@ const renderDataGrid = (viewMode, filteredAttempts, controls, filteredRows, setF controls={controls} filteredRows={filteredRows} setFilteredRows={setFilteredRows} + isDebouncing={isDebouncing} /> ) } @@ -96,6 +105,7 @@ const AssessmentStats = ({ attempts, defaultFilterSettings = {} }) => { // Used in order to display all possible values based on parameter search in // obo's hybrid text-input/select component. const [filteredRows, setFilteredRows] = React.useState([]) + const [isDebouncing, setIsDebouncing] = React.useState(false) const onChangeViewMode = event => { setViewMode(event.target.value) @@ -122,11 +132,12 @@ const AssessmentStats = ({ attempts, defaultFilterSettings = {} }) => { dateBounds={dateBounds} onChangeControls={setControls} dropdownValues={filteredRows} + setIsDebouncing={setIsDebouncing} /> - {renderDataGrid(viewMode, filteredAttempts, controls, filteredRows, setFilteredRows)} + {renderDataGrid(viewMode, filteredAttempts, controls, filteredRows, setFilteredRows, isDebouncing)} ) } diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.scss b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.scss index 5565c02e8f..6044486d98 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.scss +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.scss @@ -62,6 +62,7 @@ height: calc(100% - 2px); border: 1px solid $color-shadow; border-radius: $dimension-rounded-radius; + position: relative; .repository--button { display: inline-block; @@ -100,4 +101,11 @@ display: inline-block; margin-top: 1em; } + + .data-table-header { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + } } diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx index f5b28795a2..43c564057d 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx @@ -105,7 +105,7 @@ const columns = [ } ] -function DataGridAssessments({ attempts = [], controls, filteredRows, setFilteredRows }) { +function DataGridAssessments({ attempts = [], controls, filteredRows, setFilteredRows, isDebouncing }) { const assessmentScores = getAssessmentStatsFromAttemptStats(attempts) return ( @@ -118,6 +118,7 @@ function DataGridAssessments({ attempts = [], controls, filteredRows, setFiltere controls={controls} filteredRows={filteredRows} setFilteredRows={setFilteredRows} + isDebouncing={isDebouncing} /> ) diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx index ccd47ce828..e68053ee5f 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx @@ -188,7 +188,7 @@ const columns = [ } ] -function DataGridAttempts({ attempts = [], controls, filteredRows, setFilteredRows }) { +function DataGridAttempts({ attempts = [], controls, filteredRows, setFilteredRows, isDebouncing }) { return (
) diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx index 68fe1e33e8..ba453b2bcc 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx @@ -1,6 +1,7 @@ const React = require('react') -const DataTable = require('react-data-table-component').default +const Spinner = require('../spinner') const ButtonLink = require('../button-link') +const DataTable = require('react-data-table-component').default const { convertHyphenBasedStringToCamelCase, equals } = require('../../util/misc-stats-util') const getColumns = (columns, showAdvancedFields) => @@ -100,7 +101,8 @@ function DataGridScores({ csvFileName, controls, filteredRows, - setFilteredRows + setFilteredRows, + isDebouncing }) { const filteredColumns = getColumns(columns, controls.showAdvancedFields) rows = searchDataBasedOnParams(rows, controls) @@ -109,11 +111,21 @@ function DataGridScores({ if (rows && rows.length > 0 && !equals(rows, filteredRows)) setFilteredRows(rows) }, [rows]) + const tn = getTableName(tableName, controls) + + const tableHeader = ( +
+

{getTableName(tableName, controls)}

+ {/* $color-action */} + {isDebouncing && } +
+ ) + return (
Date: Thu, 26 Aug 2021 13:39:13 -0400 Subject: [PATCH 08/25] Ran prettier on all files --- .../shared/components/hybrid-input-select.jsx | 100 ++++---- .../components/hybrid-input-select.scss | 102 ++++---- .../components/hybrid-input-select.test.js | 120 +++++---- .../stats/assessment-stats-controls.jsx | 5 +- .../components/stats/assessment-stats.jsx | 9 +- .../stats/data-grid-assessments.jsx | 8 +- .../components/stats/data-grid-attempts.jsx | 8 +- .../components/stats/data-grid-scores.jsx | 4 +- .../shared/util/misc-stats-util.js | 20 +- .../shared/util/misc-stats-util.test.js | 235 +++++++++--------- 10 files changed, 308 insertions(+), 303 deletions(-) diff --git a/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx b/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx index dbbcc66468..07fa3939e7 100644 --- a/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx +++ b/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx @@ -4,58 +4,54 @@ const React = require('react') const { useState } = require('react') const HybridInputSelect = ({ placeholder = 'Enter text', list = [], onChange }) => { - const [text, setText] = useState('') - const [filteredList, setFilteredList] = useState(list) - const [dropdownOpen, setDropdownOpen] = useState(false) - - const handleInputChange = (event) => { - const value = event.target.value - setText(value) - setDropdownOpen(true) - - if (onChange) onChange({ target: { value } }) - - // Filters a given list based on the input text - const newList = list.filter(el => el && el.toLowerCase().match(value.toLowerCase())) - setFilteredList(newList) - } - - const handleElementClick = (el) => { - setText(el) - setDropdownOpen(false) - } - - const formatElement = (el) => { - if (el && el.length > 18) el += '...' - return el - } - - let elementsClassName = 'elements ' - elementsClassName += (text && dropdownOpen) ? 'open' : 'closed' - - let elements = filteredList.map((el, ix) => -
handleElementClick(el)}> - {formatElement(el)} -
- ) - - if (elements.length === 0) elements = [ -
No matches found
- ] - - return ( -
- -
- {elements} -
-
- ) + const [text, setText] = useState('') + const [filteredList, setFilteredList] = useState(list) + const [dropdownOpen, setDropdownOpen] = useState(false) + + const handleInputChange = event => { + const value = event.target.value + setText(value) + setDropdownOpen(true) + + if (onChange) onChange({ target: { value } }) + + // Filters a given list based on the input text + const newList = list.filter(el => el && el.toLowerCase().match(value.toLowerCase())) + setFilteredList(newList) + } + + const handleElementClick = el => { + setText(el) + setDropdownOpen(false) + } + + const formatElement = el => { + if (el && el.length > 18) el += '...' + return el + } + + let elementsClassName = 'elements ' + elementsClassName += text && dropdownOpen ? 'open' : 'closed' + + let elements = filteredList.map((el, ix) => ( +
handleElementClick(el)}> + {formatElement(el)} +
+ )) + + if (elements.length === 0) + elements = [ +
+ No matches found +
+ ] + + return ( +
+ +
{elements}
+
+ ) } module.exports = HybridInputSelect diff --git a/packages/app/obojobo-repository/shared/components/hybrid-input-select.scss b/packages/app/obojobo-repository/shared/components/hybrid-input-select.scss index 5824a833eb..cd6c682d49 100644 --- a/packages/app/obojobo-repository/shared/components/hybrid-input-select.scss +++ b/packages/app/obojobo-repository/shared/components/hybrid-input-select.scss @@ -1,64 +1,64 @@ @import '../../client/css/defaults'; .hybrid-input-select { - position: relative; + position: relative; - input { - @include text-input(); + input { + @include text-input(); - width: 100%; - font-size: 0.8em; - padding: 0.6em 0.5em; - border: 0.1em solid $color-shadow; - border-radius: $dimension-rounded-radius; - } + width: 100%; + font-size: 0.8em; + padding: 0.6em 0.5em; + border: 0.1em solid $color-shadow; + border-radius: $dimension-rounded-radius; + } - .elements { - position: absolute; - transition: 0.1s; - overflow-x: hidden; - top: 2.5em; - border-radius: $dimension-rounded-radius; - box-shadow: 0 0.3em 0.2em $color-shadow; - border: 0.0001em solid $color-banner-bg; + .elements { + position: absolute; + transition: 0.1s; + overflow-x: hidden; + top: 2.5em; + border-radius: $dimension-rounded-radius; + box-shadow: 0 0.3em 0.2em $color-shadow; + border: 0.0001em solid $color-banner-bg; - &.open { - max-height: 5em; - overflow-y: auto; - width: 100%; - opacity: 1; - transition: 0.2s; - } + &.open { + max-height: 5em; + overflow-y: auto; + width: 100%; + opacity: 1; + transition: 0.2s; + } - &.closed { - height: 0; - line-height: 0; - overflow: hidden; - opacity: 0; - transition: 0.2s; - } + &.closed { + height: 0; + line-height: 0; + overflow: hidden; + opacity: 0; + transition: 0.2s; + } - .element { - width: 100%; - font-size: 0.8em; - transition: 0.1s; - background-color: $color-bg; - padding-left: 0.65em; - overflow-x: hidden; + .element { + width: 100%; + font-size: 0.8em; + transition: 0.1s; + background-color: $color-bg; + padding-left: 0.65em; + overflow-x: hidden; - &:hover { - cursor: pointer; - transition: 0.1s; - background-color: desaturate(lighten($color-action, 45%), 40%) - } + &:hover { + cursor: pointer; + transition: 0.1s; + background-color: desaturate(lighten($color-action, 45%), 40%); + } - &:not(:first-child) { - border-top: 0.0001em solid $color-banner-bg; - } + &:not(:first-child) { + border-top: 0.0001em solid $color-banner-bg; + } - &.no-matches { - cursor: default; - } - } - } + &.no-matches { + cursor: default; + } + } + } } diff --git a/packages/app/obojobo-repository/shared/components/hybrid-input-select.test.js b/packages/app/obojobo-repository/shared/components/hybrid-input-select.test.js index 8d552b789b..d4324fdd18 100644 --- a/packages/app/obojobo-repository/shared/components/hybrid-input-select.test.js +++ b/packages/app/obojobo-repository/shared/components/hybrid-input-select.test.js @@ -4,83 +4,75 @@ import { create, act } from 'react-test-renderer' describe('HybridInputSelect', () => { test('renders with default props', () => { - const component = create() + const component = create() const tree = component.toJSON() expect(tree).toMatchSnapshot() - }) + }) - test('renders with a given list and placeholder', () => { - const mockProps = { - placeholder: 'Mock placeholder', - list: [ - 'mock-student-one', - 'mock-student-two', - 'mock-student-three', - 'mock-short', - 'mock-very-long-student-name', - 'mock-extremely-long-student-name' - ] - } - const component = create() + test('renders with a given list and placeholder', () => { + const mockProps = { + placeholder: 'Mock placeholder', + list: [ + 'mock-student-one', + 'mock-student-two', + 'mock-student-three', + 'mock-short', + 'mock-very-long-student-name', + 'mock-extremely-long-student-name' + ] + } + const component = create() const tree = component.toJSON() expect(tree).toMatchSnapshot() - }) + }) - test('input is updated and list is filtered as expected', () => { - // Without onChange prop - let mockProps = { - placeholder: 'Mock placeholder', - list: [ - 'mock-student-one', - 'mock-student-two', - 'mock-student-three' - ] - } - let component = create() + test('input is updated and list is filtered as expected', () => { + // Without onChange prop + let mockProps = { + placeholder: 'Mock placeholder', + list: ['mock-student-one', 'mock-student-two', 'mock-student-three'] + } + let component = create() - let input = component.root.findByProps({ type: 'text' }) - act(() => { - input.props.onChange({ target: { value: 'mock-search-string' }}) - }) - expect(input.props.value).toBe('mock-search-string') + let input = component.root.findByProps({ type: 'text' }) + act(() => { + input.props.onChange({ target: { value: 'mock-search-string' } }) + }) + expect(input.props.value).toBe('mock-search-string') - // With onChange prop - mockProps = { ...mockProps, onChange: jest.fn() } - component = create() + // With onChange prop + mockProps = { ...mockProps, onChange: jest.fn() } + component = create() - input = component.root.findByProps({ type: 'text' }) - act(() => { - input.props.onChange({ target: { value: 'mock-search-string' }}) - }) - expect(input.props.value).toBe('mock-search-string') - }) + input = component.root.findByProps({ type: 'text' }) + act(() => { + input.props.onChange({ target: { value: 'mock-search-string' } }) + }) + expect(input.props.value).toBe('mock-search-string') + }) - test('clicking on an element sets input value to element\'s text', () => { - const mockProps = { - placeholder: 'Mock placeholder', - list: [ - 'mock-student-one', - 'mock-student-two', - 'mock-student-three' - ], - onChange: jest.fn() - } - const component = create() + test("clicking on an element sets input value to element's text", () => { + const mockProps = { + placeholder: 'Mock placeholder', + list: ['mock-student-one', 'mock-student-two', 'mock-student-three'], + onChange: jest.fn() + } + const component = create() - // Populating input so that the dropdown opens - const input = component.root.findByProps({ type: 'text' }) - act(() => { - input.props.onChange({ target: { value: 'mock' }}) - }) + // Populating input so that the dropdown opens + const input = component.root.findByProps({ type: 'text' }) + act(() => { + input.props.onChange({ target: { value: 'mock' } }) + }) - // Selecting an element from the dropdown - const element = component.root.findAllByProps({ className: 'element' })[0] - act(() => { - element.props.onClick('mock-student-one') - }) + // Selecting an element from the dropdown + const element = component.root.findAllByProps({ className: 'element' })[0] + act(() => { + element.props.onClick('mock-student-one') + }) - expect(input.props.value).toBe('mock-student-one') - }) + expect(input.props.value).toBe('mock-student-one') + }) }) diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx index 1e957a44b7..6e35fdf06f 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.jsx @@ -123,8 +123,9 @@ const AssessmentStatsControls = ({ ) } - const valuesForHybridInput = dropdownValues.map(row => - row[convertHyphenBasedStringToCamelCase(param)]) + const valuesForHybridInput = dropdownValues.map( + row => row[convertHyphenBasedStringToCamelCase(param)] + ) const showHybridInput = param !== '' diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx index e716f9df27..67066989f2 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats.jsx @@ -137,7 +137,14 @@ const AssessmentStats = ({ attempts, defaultFilterSettings = {} }) => {
- {renderDataGrid(viewMode, filteredAttempts, controls, filteredRows, setFilteredRows, isDebouncing)} + {renderDataGrid( + viewMode, + filteredAttempts, + controls, + filteredRows, + setFilteredRows, + isDebouncing + )} ) } diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx index 43c564057d..5e840a266d 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-assessments.jsx @@ -105,7 +105,13 @@ const columns = [ } ] -function DataGridAssessments({ attempts = [], controls, filteredRows, setFilteredRows, isDebouncing }) { +function DataGridAssessments({ + attempts = [], + controls, + filteredRows, + setFilteredRows, + isDebouncing +}) { const assessmentScores = getAssessmentStatsFromAttemptStats(attempts) return ( diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx index e68053ee5f..abf245c016 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-attempts.jsx @@ -188,7 +188,13 @@ const columns = [ } ] -function DataGridAttempts({ attempts = [], controls, filteredRows, setFilteredRows, isDebouncing }) { +function DataGridAttempts({ + attempts = [], + controls, + filteredRows, + setFilteredRows, + isDebouncing +}) { return (
+

{getTableName(tableName, controls)}

{/* $color-action */} - {isDebouncing && } + {isDebouncing && }
) diff --git a/packages/app/obojobo-repository/shared/util/misc-stats-util.js b/packages/app/obojobo-repository/shared/util/misc-stats-util.js index 624036e1cd..94af37e34c 100644 --- a/packages/app/obojobo-repository/shared/util/misc-stats-util.js +++ b/packages/app/obojobo-repository/shared/util/misc-stats-util.js @@ -1,16 +1,16 @@ -const convertHyphenBasedStringToCamelCase = (s) => { - // E.g. camel-case ---> camelCase - let camel = s - .split('-') - .map(word => word.charAt(0).toUpperCase() + word.substring(1)) - .join('') - camel = camel.charAt(0).toLowerCase() + camel.substring(1) - return camel +const convertHyphenBasedStringToCamelCase = s => { + // E.g. camel-case ---> camelCase + let camel = s + .split('-') + .map(word => word.charAt(0).toUpperCase() + word.substring(1)) + .join('') + camel = camel.charAt(0).toLowerCase() + camel.substring(1) + return camel } const equals = (arr1, arr2) => JSON.stringify(arr1) === JSON.stringify(arr2) module.exports = { - convertHyphenBasedStringToCamelCase, - equals + convertHyphenBasedStringToCamelCase, + equals } diff --git a/packages/app/obojobo-repository/shared/util/misc-stats-util.test.js b/packages/app/obojobo-repository/shared/util/misc-stats-util.test.js index 94423774ee..c9955711de 100644 --- a/packages/app/obojobo-repository/shared/util/misc-stats-util.test.js +++ b/packages/app/obojobo-repository/shared/util/misc-stats-util.test.js @@ -1,134 +1,131 @@ -const { - equals, - convertHyphenBasedStringToCamelCase -} = require('./misc-stats-util') +const { equals, convertHyphenBasedStringToCamelCase } = require('./misc-stats-util') describe('miscStatsUtil', () => { - test('equals returns expected values', () => { - let arr1 = [ - { - assessmentId: "my-assessment", - courseTitle: null, - draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", - draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", - isPreview: true, - moduleTitle: "My Obojobo Module Title", - resourceLinkId: "preview", - userFirstName: "Test", - userLastName: "Instructor1" - }, - { - assessmentId: "my-assessment", - courseTitle: null, - draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", - draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", - isPreview: true, - moduleTitle: "My Obojobo Module Title", - resourceLinkId: "preview", - userFirstName: "Test", - userLastName: "Instructor1" - } - ] + test('equals returns expected values', () => { + let arr1 = [ + { + assessmentId: 'my-assessment', + courseTitle: null, + draftContentId: '32e82b43-b6d0-4221-ae86-f2d95dd5561e', + draftId: 'bc94db0f-845b-4f77-9286-fe13d41f72d1', + isPreview: true, + moduleTitle: 'My Obojobo Module Title', + resourceLinkId: 'preview', + userFirstName: 'Test', + userLastName: 'Instructor1' + }, + { + assessmentId: 'my-assessment', + courseTitle: null, + draftContentId: '32e82b43-b6d0-4221-ae86-f2d95dd5561e', + draftId: 'bc94db0f-845b-4f77-9286-fe13d41f72d1', + isPreview: true, + moduleTitle: 'My Obojobo Module Title', + resourceLinkId: 'preview', + userFirstName: 'Test', + userLastName: 'Instructor1' + } + ] - let arr2 = [ - { - assessmentId: "my-assessment", - courseTitle: null, - draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", - draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", - isPreview: true, - moduleTitle: "My Obojobo Module Title", - userFirstName: "Test", - userLastName: "Instructor1", - resourceLinkId: "preview" - }, - { - assessmentId: "my-assessment", - courseTitle: null, - draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", - draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", - isPreview: true, - moduleTitle: "My Obojobo Module Title", - resourceLinkId: "preview", - userFirstName: "Test", - userLastName: "Instructor1" - } - ] + let arr2 = [ + { + assessmentId: 'my-assessment', + courseTitle: null, + draftContentId: '32e82b43-b6d0-4221-ae86-f2d95dd5561e', + draftId: 'bc94db0f-845b-4f77-9286-fe13d41f72d1', + isPreview: true, + moduleTitle: 'My Obojobo Module Title', + userFirstName: 'Test', + userLastName: 'Instructor1', + resourceLinkId: 'preview' + }, + { + assessmentId: 'my-assessment', + courseTitle: null, + draftContentId: '32e82b43-b6d0-4221-ae86-f2d95dd5561e', + draftId: 'bc94db0f-845b-4f77-9286-fe13d41f72d1', + isPreview: true, + moduleTitle: 'My Obojobo Module Title', + resourceLinkId: 'preview', + userFirstName: 'Test', + userLastName: 'Instructor1' + } + ] - expect(equals(arr1, arr2)).toBe(false) + expect(equals(arr1, arr2)).toBe(false) - arr1 = [ - { - assessmentId: "my-assessment", - courseTitle: null, - draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", - draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", - isPreview: true, - moduleTitle: "My Obojobo Module Title", - resourceLinkId: "preview", - userFirstName: "Test", - userLastName: "Instructor1" - } - ] + arr1 = [ + { + assessmentId: 'my-assessment', + courseTitle: null, + draftContentId: '32e82b43-b6d0-4221-ae86-f2d95dd5561e', + draftId: 'bc94db0f-845b-4f77-9286-fe13d41f72d1', + isPreview: true, + moduleTitle: 'My Obojobo Module Title', + resourceLinkId: 'preview', + userFirstName: 'Test', + userLastName: 'Instructor1' + } + ] - arr2 = [ - { - assessmentId: "my-assessment-two", - courseTitle: null, - draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", - draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", - isPreview: true, - moduleTitle: "My Obojobo Module Title", - resourceLinkId: "preview", - userFirstName: "Test", - userLastName: "Instructor1" - } - ] + arr2 = [ + { + assessmentId: 'my-assessment-two', + courseTitle: null, + draftContentId: '32e82b43-b6d0-4221-ae86-f2d95dd5561e', + draftId: 'bc94db0f-845b-4f77-9286-fe13d41f72d1', + isPreview: true, + moduleTitle: 'My Obojobo Module Title', + resourceLinkId: 'preview', + userFirstName: 'Test', + userLastName: 'Instructor1' + } + ] - expect(equals(arr1, arr2)).toBe(false) + expect(equals(arr1, arr2)).toBe(false) - arr1 = [ - { - assessmentId: "my-assessment", - courseTitle: null, - draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", - draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", - isPreview: true, - moduleTitle: "My Obojobo Module Title", - resourceLinkId: "preview", - userFirstName: "Test", - userLastName: "Instructor1" - } - ] + arr1 = [ + { + assessmentId: 'my-assessment', + courseTitle: null, + draftContentId: '32e82b43-b6d0-4221-ae86-f2d95dd5561e', + draftId: 'bc94db0f-845b-4f77-9286-fe13d41f72d1', + isPreview: true, + moduleTitle: 'My Obojobo Module Title', + resourceLinkId: 'preview', + userFirstName: 'Test', + userLastName: 'Instructor1' + } + ] - arr2 = [ - { - assessmentId: "my-assessment", - courseTitle: null, - draftContentId: "32e82b43-b6d0-4221-ae86-f2d95dd5561e", - draftId: "bc94db0f-845b-4f77-9286-fe13d41f72d1", - isPreview: true, - moduleTitle: "My Obojobo Module Title", - resourceLinkId: "preview", - userFirstName: "Test", - userLastName: "Instructor1" - } - ] + arr2 = [ + { + assessmentId: 'my-assessment', + courseTitle: null, + draftContentId: '32e82b43-b6d0-4221-ae86-f2d95dd5561e', + draftId: 'bc94db0f-845b-4f77-9286-fe13d41f72d1', + isPreview: true, + moduleTitle: 'My Obojobo Module Title', + resourceLinkId: 'preview', + userFirstName: 'Test', + userLastName: 'Instructor1' + } + ] - expect(equals(arr1, arr2)).toBe(true) - }) + expect(equals(arr1, arr2)).toBe(true) + }) - test('convertHyphenBasedStringToCamelCase converts strings as expected', () => { - let str = convertHyphenBasedStringToCamelCase('mock-student-name') - expect(str).toBe('mockStudentName') + test('convertHyphenBasedStringToCamelCase converts strings as expected', () => { + let str = convertHyphenBasedStringToCamelCase('mock-student-name') + expect(str).toBe('mockStudentName') - str = convertHyphenBasedStringToCamelCase('o-b-o') - expect(str).toBe('oBO') + str = convertHyphenBasedStringToCamelCase('o-b-o') + expect(str).toBe('oBO') - str = convertHyphenBasedStringToCamelCase('123') - expect(str).toBe('123') + str = convertHyphenBasedStringToCamelCase('123') + expect(str).toBe('123') - str = convertHyphenBasedStringToCamelCase('1-2-3') - expect(str).toBe('123') - }) + str = convertHyphenBasedStringToCamelCase('1-2-3') + expect(str).toBe('123') + }) }) From e789f5d483ebc9d688cc8fcdf34ae25210c92457 Mon Sep 17 00:00:00 2001 From: Mauricio Date: Mon, 30 Aug 2021 10:59:47 -0400 Subject: [PATCH 09/25] Updated snapshots after merging dev/25 --- .../assessment-score-data-dialog.test.js.snap | 57 ++++++++--------- .../__snapshots__/stats.test.js.snap | 2 +- .../assessment-stats.test.js.snap | 64 ++++++++++++------- .../data-grid-assessments.test.js.snap | 34 ++++++---- .../data-grid-attempts.test.js.snap | 34 ++++++---- 5 files changed, 114 insertions(+), 77 deletions(-) diff --git a/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap b/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap index 3801d2d441..d7602a2ecc 100644 --- a/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap @@ -77,7 +77,7 @@ exports[`AssessmentScoreDataDialog AssessmentScoreDataDialog renders correctly w htmlFor="repository--assessment-stats-search-controls--search-by" > Search by: - +
Search by: - +
>>>>>> c19263db705d5b097e5746cd482e2e36dc38ca97 + "sortable": true, + }, + Object { + "advanced": false, + "name": "Student Name", + "selector": "studentName", "sortable": true, }, Object { @@ -677,7 +691,7 @@ exports[`AssessmentScoreDataDialog AssessmentScoreDataDialog renders correctly w htmlFor="repository--assessment-stats-search-controls--search-by" > Search by: - +
>>>>>> c19263db705d5b097e5746cd482e2e36dc38ca97 + "sortable": true, + }, + Object { + "advanced": false, + "name": "Student Name", + "selector": "studentName", "sortable": true, }, Object { @@ -899,22 +914,6 @@ exports[`AssessmentScoreDataDialog AssessmentScoreDataDialog renders correctly w react-data-table-component
-<<<<<<< HEAD -======= - - ⬇️   Download - - Table as CSV File ( - 1 - row - - ) - ->>>>>>> c19263db705d5b097e5746cd482e2e36dc38ca97
diff --git a/packages/app/obojobo-repository/shared/components/__snapshots__/stats.test.js.snap b/packages/app/obojobo-repository/shared/components/__snapshots__/stats.test.js.snap index c765e5553c..42eb536739 100644 --- a/packages/app/obojobo-repository/shared/components/__snapshots__/stats.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/__snapshots__/stats.test.js.snap @@ -246,7 +246,7 @@ exports[`Stats Renders loaded state correctly 1`] = ` htmlFor="repository--assessment-stats-search-controls--search-by" > Search by: - +
Search by: - +
>>>>>> c19263db705d5b097e5746cd482e2e36dc38ca97 + href="data:text/csv;charset=utf-8,%22First%20Name%22%2C%22Last%20Name%22%2C%22Course%20Title%22%2C%22Resource%20Link%20Title%22%2C%22URL%22%2C%22Student%20Name%22%2C%22Final%20Assessment%20Score%22%2C%22Preview%20Mode%22%0A%22mock-first-name%22%2C%22mock-last-name%22%2C%22%22%2C%22%22%2C%22%22%2C%22mock-first-name%20mock-last-name%22%2C%220%22%2C%22false%22" > - ⬇️   Download - + ⬇️   Download + Table as CSV File ( 1 row - + )
@@ -347,7 +356,7 @@ exports[`AssessmentStats AssessmentStats renders correctly 2`] = ` htmlFor="repository--assessment-stats-search-controls--search-by" > Search by: - +
>>>>>> c19263db705d5b097e5746cd482e2e36dc38ca97 + "sortable": true, + }, + Object { + "advanced": false, + "name": "Student Name", + "selector": "studentName", "sortable": true, }, Object { @@ -660,14 +670,10 @@ exports[`AssessmentStats AssessmentStats renders correctly 2`] = ` >>>>>> c19263db705d5b097e5746cd482e2e36dc38ca97 + href="data:text/csv;charset=utf-8,%22First%20Name%22%2C%22Last%20Name%22%2C%22Course%20Title%22%2C%22Resource%20Link%20Title%22%2C%22URL%22%2C%22Student%20Name%22%2C%22Attempt%20ID%22%2C%22Imported%20Attempt%20ID%22%2C%22Attempt%20%23%22%2C%22Attempt%20Score%22%2C%22Assessment%20Status%22%2C%22Un-modded%20Assessment%20Score%22%2C%22Mod%20Reward%20Total%22%2C%22Assessment%20Score%22%2C%22Started%20Time%22%2C%22Submitted%20Time%22%2C%22Preview%20Mode%22%0A%22mock-first-name%22%2C%22mock-last-name%22%2C%22%22%2C%22%22%2C%22%22%2C%22mock-first-name%20mock-last-name%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%22null%22%2C%22%22%2C%222021-08-20T13%3A42%3A37.462Z%22%2C%22false%22%0A%22mock-first-name%22%2C%22mock-last-name%22%2C%22%22%2C%22%22%2C%22%22%2C%22mock-first-name%20mock-last-name%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%220%22%2C%22%22%2C%222021-08-09T13%3A42%3A37.462Z%22%2C%22false%22" > - ⬇️   Download - + ⬇️   Download + Table as CSV File ( 2 row @@ -725,7 +731,7 @@ exports[`AssessmentStats AssessmentStats renders correctly 3`] = ` htmlFor="repository--assessment-stats-search-controls--search-by" > Search by: - +
>>>>>> c19263db705d5b097e5746cd482e2e36dc38ca97 + href="data:text/csv;charset=utf-8,%22First%20Name%22%2C%22Last%20Name%22%2C%22Course%20Title%22%2C%22Resource%20Link%20Title%22%2C%22URL%22%2C%22Student%20Name%22%2C%22Final%20Assessment%20Score%22%2C%22Preview%20Mode%22%0A%22%22%2C%22%22%2C%22%22%2C%22%22%2C%22mock-url%22%2C%22undefined%20undefined%22%2C%22%22%2C%22false%22%0A%22%22%2C%22%22%2C%22%22%2C%22%22%2C%22mock-url%22%2C%22undefined%20undefined%22%2C%22%22%2C%22true%22" > - ⬇️   Download - + ⬇️   Download + Table as CSV File ( 2 row @@ -212,10 +221,6 @@ exports[`DataGridAssessments DataGridAssessments renders without attempts 1`] = }, Object { "advanced": false, -<<<<<<< HEAD - "name": "Student Name", - "selector": "studentName", -======= "name": "Resource Link Title", "selector": "resourceLinkTitle", "sortable": true, @@ -225,7 +230,12 @@ exports[`DataGridAssessments DataGridAssessments renders without attempts 1`] = "cell": [Function], "name": "URL", "selector": "launchPresentationReturnUrl", ->>>>>>> c19263db705d5b097e5746cd482e2e36dc38ca97 + "sortable": true, + }, + Object { + "advanced": false, + "name": "Student Name", + "selector": "studentName", "sortable": true, }, Object { diff --git a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap index adc78d646b..6b334cae15 100644 --- a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap @@ -100,6 +100,19 @@ exports[`DataGridAttempts DataGridAttempts renders correctly 1`] = ` "selector": "courseTitle", "sortable": true, }, + Object { + "advanced": false, + "name": "Resource Link Title", + "selector": "resourceLinkTitle", + "sortable": true, + }, + Object { + "advanced": false, + "cell": [Function], + "name": "URL", + "selector": "launchPresentationReturnUrl", + "sortable": true, + }, Object { "advanced": false, "name": "Student Name", @@ -237,14 +250,10 @@ exports[`DataGridAttempts DataGridAttempts renders correctly 1`] = ` >>>>>> c19263db705d5b097e5746cd482e2e36dc38ca97 + href="data:text/csv;charset=utf-8,%22First%20Name%22%2C%22Last%20Name%22%2C%22Course%20Title%22%2C%22Resource%20Link%20Title%22%2C%22URL%22%2C%22Student%20Name%22%2C%22Attempt%20ID%22%2C%22Imported%20Attempt%20ID%22%2C%22Attempt%20%23%22%2C%22Attempt%20Score%22%2C%22Assessment%20Status%22%2C%22Un-modded%20Assessment%20Score%22%2C%22Mod%20Reward%20Total%22%2C%22Assessment%20Score%22%2C%22Started%20Time%22%2C%22Submitted%20Time%22%2C%22Preview%20Mode%22%0A%22%22%2C%22%22%2C%22%22%2C%22%22%2C%22mock-url%22%2C%22%22%2C%22%22%2C%22mock-imported-attempt-id%22%2C%22%22%2C%22mock-attempt-score%22%2C%22mock-assessment-status%22%2C%22mock-assessment-status%22%2C%22mock-reward%22%2C%22%22%2C%22%22%2C%22%22%2C%22true%22%0A%22%22%2C%22%22%2C%22%22%2C%22%22%2C%22mock-url%22%2C%22%22%2C%22%22%2C%22mock-imported-attempt-id%22%2C%22%22%2C%22mock-attempt-score%22%2C%22mock-assessment-status%22%2C%22mock-assessment-status%22%2C%22mock-reward%22%2C%22%22%2C%22%22%2C%22%22%2C%22false%22" > - ⬇️   Download - + ⬇️   Download + Table as CSV File ( 2 row @@ -289,10 +298,6 @@ exports[`DataGridAttempts DataGridAttempts renders with no attempts 1`] = ` }, Object { "advanced": false, -<<<<<<< HEAD - "name": "Student Name", - "selector": "studentName", -======= "name": "Resource Link Title", "selector": "resourceLinkTitle", "sortable": true, @@ -302,7 +307,12 @@ exports[`DataGridAttempts DataGridAttempts renders with no attempts 1`] = ` "cell": [Function], "name": "URL", "selector": "launchPresentationReturnUrl", ->>>>>>> c19263db705d5b097e5746cd482e2e36dc38ca97 + "sortable": true, + }, + Object { + "advanced": false, + "name": "Student Name", + "selector": "studentName", "sortable": true, }, Object { From 10c8214692e7c763042b717f03469d316822dbea Mon Sep 17 00:00:00 2001 From: Mauricio Date: Tue, 31 Aug 2021 12:52:13 -0400 Subject: [PATCH 10/25] Fixed failing tests due to recent datatable header changes --- .../assessment-score-data-dialog.test.js.snap | 6 ++-- .../__snapshots__/stats.test.js.snap | 2 +- .../shared/components/spinner.test.js | 7 ++--- .../assessment-stats.test.js.snap | 6 ++-- .../data-grid-assessments.test.js.snap | 4 +-- .../data-grid-attempts.test.js.snap | 4 +-- .../data-grid-scores.test.js.snap | 28 +++++++++---------- .../components/stats/data-grid-scores.jsx | 5 ++-- .../components/stats/data-grid-scores.test.js | 5 +++- 9 files changed, 34 insertions(+), 33 deletions(-) diff --git a/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap b/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap index d7602a2ecc..b21639614e 100644 --- a/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/__snapshots__/assessment-score-data-dialog.test.js.snap @@ -289,7 +289,7 @@ exports[`AssessmentScoreDataDialog AssessmentScoreDataDialog renders correctly w striped={true} title={

Final Assessment Scores @@ -596,7 +596,7 @@ exports[`AssessmentScoreDataDialog AssessmentScoreDataDialog renders correctly w striped={true} title={

Final Assessment Scores @@ -903,7 +903,7 @@ exports[`AssessmentScoreDataDialog AssessmentScoreDataDialog renders correctly w striped={true} title={

Final Assessment Scores diff --git a/packages/app/obojobo-repository/shared/components/__snapshots__/stats.test.js.snap b/packages/app/obojobo-repository/shared/components/__snapshots__/stats.test.js.snap index 42eb536739..50092c0fc2 100644 --- a/packages/app/obojobo-repository/shared/components/__snapshots__/stats.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/__snapshots__/stats.test.js.snap @@ -512,7 +512,7 @@ exports[`Stats Renders loaded state correctly 1`] = ` striped={true} title={

Final Assessment Scores diff --git a/packages/app/obojobo-repository/shared/components/spinner.test.js b/packages/app/obojobo-repository/shared/components/spinner.test.js index 4c3e1f4346..9158f40fb0 100644 --- a/packages/app/obojobo-repository/shared/components/spinner.test.js +++ b/packages/app/obojobo-repository/shared/components/spinner.test.js @@ -1,13 +1,10 @@ import React from 'react' import Spinner from './spinner' -import { create, act } from 'react-test-renderer' +import { create } from 'react-test-renderer' describe('Spinner', () => { test('Spinner component', async () => { - let component - await act(async () => { - component = create() - }) + const component = create() const tree = component.toJSON() diff --git a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/assessment-stats.test.js.snap b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/assessment-stats.test.js.snap index 37377ecd07..6104b69180 100644 --- a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/assessment-stats.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/assessment-stats.test.js.snap @@ -281,7 +281,7 @@ exports[`AssessmentStats AssessmentStats renders correctly 1`] = ` striped={true} title={

Final Assessment Scores @@ -656,7 +656,7 @@ exports[`AssessmentStats AssessmentStats renders correctly 2`] = ` striped={true} title={

Attempt Scores @@ -943,7 +943,7 @@ exports[`AssessmentStats AssessmentStats renders correctly 3`] = ` striped={true} title={

Final Assessment Scores diff --git a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-assessments.test.js.snap b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-assessments.test.js.snap index 8b6643440f..57cd001cda 100644 --- a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-assessments.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-assessments.test.js.snap @@ -159,7 +159,7 @@ exports[`DataGridAssessments DataGridAssessments renders correctly 1`] = ` striped={true} title={

Final Assessment Scores @@ -271,7 +271,7 @@ exports[`DataGridAssessments DataGridAssessments renders without attempts 1`] = striped={true} title={

Final Assessment Scores diff --git a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap index 6b334cae15..2384251ae2 100644 --- a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-attempts.test.js.snap @@ -236,7 +236,7 @@ exports[`DataGridAttempts DataGridAttempts renders correctly 1`] = ` striped={true} title={

Attempt Scores @@ -407,7 +407,7 @@ exports[`DataGridAttempts DataGridAttempts renders with no attempts 1`] = ` striped={true} title={

Attempt Scores diff --git a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap index d17fd94100..b51bf3490c 100644 --- a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap @@ -59,7 +59,7 @@ exports[`DataGridScores DataGridScores renders correctly 1`] = ` striped={true} title={

Mock Table Name @@ -133,7 +133,7 @@ exports[`DataGridScores DataGridScores renders one row 1`] = ` striped={true} title={

Mock Table Name @@ -187,7 +187,7 @@ exports[`DataGridScores DataGridScores renders when no rows given 1`] = ` striped={true} title={

@@ -235,7 +235,7 @@ exports[`DataGridScores DataGridScores uses search filters as expected 1`] = ` striped={true} title={

Mock Table Name @@ -285,7 +285,7 @@ exports[`DataGridScores DataGridScores uses search filters as expected 2`] = ` striped={true} title={

Mock Table Name @@ -335,7 +335,7 @@ exports[`DataGridScores DataGridScores uses search filters as expected 3`] = ` striped={true} title={

Mock Table Name @@ -404,7 +404,7 @@ exports[`DataGridScores DataGridScores uses search filters as expected 4`] = ` striped={true} title={

Mock Table Name @@ -486,7 +486,7 @@ exports[`DataGridScores DataGridScores uses search filters as expected 5`] = ` striped={true} title={

Mock Table Name @@ -568,7 +568,7 @@ exports[`DataGridScores DataGridScores uses search filters as expected 6`] = ` striped={true} title={

Mock Table Name @@ -631,7 +631,7 @@ exports[`DataGridScores DataGridScores uses search filters as expected 7`] = ` striped={true} title={

Mock Table Name @@ -681,7 +681,7 @@ exports[`DataGridScores DataGridScores uses search filters as expected 8`] = ` striped={true} title={

Mock Table Name @@ -750,7 +750,7 @@ exports[`DataGridScores DataGridScores uses search filters as expected 9`] = ` striped={true} title={

Mock Table Name @@ -832,7 +832,7 @@ exports[`DataGridScores DataGridScores uses search filters as expected 10`] = ` striped={true} title={

Mock Table Name @@ -914,7 +914,7 @@ exports[`DataGridScores DataGridScores uses search filters as expected 11`] = ` striped={true} title={

Mock Table Name diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx index bb1f51bf6d..ae74c0e9bd 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx @@ -112,10 +112,11 @@ function DataGridScores({ }, [rows]) const tn = getTableName(tableName, controls) + const tableHeaderClassName = "data-table-header " + tn const tableHeader = ( -

-

{getTableName(tableName, controls)}

+
+

{tn}

{/* $color-action */} {isDebouncing && }
diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js index e9b4dfca6e..934ec3a935 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js @@ -125,7 +125,10 @@ describe('DataGridScores', () => { ) expect( - component.root.findByProps({ className: 'react-data-table-component' }).props.title + component + .root + .findByProps({ className: 'react-data-table-component' }) + .props.title.props.className.split("data-table-header")[1].trim() ).toBe(expectedTableName) } ) From 1c568d6723ebf2b924cde9093811398eca100eae Mon Sep 17 00:00:00 2001 From: Mauricio Date: Tue, 31 Aug 2021 12:55:45 -0400 Subject: [PATCH 11/25] Ran prettier on all files --- .../shared/components/stats/data-grid-scores.jsx | 2 +- .../shared/components/stats/data-grid-scores.test.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx index ae74c0e9bd..62551a34f2 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.jsx @@ -112,7 +112,7 @@ function DataGridScores({ }, [rows]) const tn = getTableName(tableName, controls) - const tableHeaderClassName = "data-table-header " + tn + const tableHeaderClassName = 'data-table-header ' + tn const tableHeader = (
diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js index 934ec3a935..ca305a7184 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js @@ -125,10 +125,10 @@ describe('DataGridScores', () => { ) expect( - component - .root - .findByProps({ className: 'react-data-table-component' }) - .props.title.props.className.split("data-table-header")[1].trim() + component.root + .findByProps({ className: 'react-data-table-component' }) + .props.title.props.className.split('data-table-header')[1] + .trim() ).toBe(expectedTableName) } ) From efb16af9ebcc9ee0334d8c402887099c916663a8 Mon Sep 17 00:00:00 2001 From: Mauricio Date: Thu, 2 Sep 2021 11:10:35 -0400 Subject: [PATCH 12/25] Fixed a couple of failing unit tests and brought coverage back to 100% --- .../stats/__snapshots__/data-grid-scores.test.js.snap | 3 +++ .../shared/components/stats/data-grid-scores.test.js | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap index b51bf3490c..037754e179 100644 --- a/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/stats/__snapshots__/data-grid-scores.test.js.snap @@ -190,6 +190,9 @@ exports[`DataGridScores DataGridScores renders when no rows given 1`] = ` className="data-table-header undefined" >

+

} > diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js index ca305a7184..d8a1dce0b8 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js @@ -56,7 +56,8 @@ describe('DataGridScores', () => { date: null } }, - setFilteredRows: () => {} + setFilteredRows: () => {}, + isDebouncing: false }) test('DataGridScores renders correctly', () => { @@ -237,6 +238,7 @@ describe('DataGridScores', () => { const component = renderer.create( Date: Mon, 20 Feb 2023 10:20:52 -0500 Subject: [PATCH 13/25] #1869 Modernized from current dev branch. Added filter string sanitation to remove regex reserved characters. Corrected post-merge unit tests to remove tests that are no longer relevant. --- .../shared/components/hybrid-input-select.jsx | 6 +- .../components/stats/data-grid-scores.test.js | 92 ------------------- 2 files changed, 5 insertions(+), 93 deletions(-) diff --git a/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx b/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx index 07fa3939e7..da6feb6906 100644 --- a/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx +++ b/packages/app/obojobo-repository/shared/components/hybrid-input-select.jsx @@ -9,10 +9,14 @@ const HybridInputSelect = ({ placeholder = 'Enter text', list = [], onChange }) const [dropdownOpen, setDropdownOpen] = useState(false) const handleInputChange = event => { - const value = event.target.value + let value = event.target.value setText(value) setDropdownOpen(true) + // sanitize text to remove regex reserved characters + // ., + , *, ?, ^, $, (, ), [, ], {, }, |, \ + value = value.replace(/[.+*,^$(){}|[\]\\]+/g, '') + if (onChange) onChange({ target: { value } }) // Filters a given list based on the input text diff --git a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js index 51bf5a8941..d8a1dce0b8 100644 --- a/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js +++ b/packages/app/obojobo-repository/shared/components/stats/data-grid-scores.test.js @@ -2,8 +2,6 @@ import React from 'react' import renderer from 'react-test-renderer' import DataGridScores from './data-grid-scores' -const ButtonLink = require('../button-link') - jest.mock('react-data-table-component', () => ({ default: props => (
@@ -477,94 +475,4 @@ describe('DataGridScores', () => { ) expect(component.toJSON()).toMatchSnapshot() }) - - test('DataGridScores renders "null" in CSV exports where applicable', () => { - const props = getTestProps() - props.filterSettings.showAdvancedFields = true - props.rows.pop() - // Null the field we're not 'searching' by in the only row - props.rows[0].exampleId = null - - const escapedRowString = escape(`"Draft ID","Example ID"\n"${props.rows[0].draftId}","null"`) - const expectedUrlString = `data:text/csv;charset=utf-8,${escapedRowString}` - - const component = renderer.create() - expect(component.root.findByType(ButtonLink).props.url).toEqual(expectedUrlString) - }) - - test('DataGridScores filters rows correctly based on start/end dates', () => { - // Shortcut function to get the filtered rows by checking the 'data' prop of the DataTable child - // This is admittedly a bit of a hack, but it's far easier than any alternatives - const getFilteredRows = component => { - return component.root.findByProps({ className: 'data-grid' }).children[0].props.data - } - - const mockStartDate = new Date() - mockStartDate.setDate(mockStartDate.getDate() - 2) - const mockEndDate = new Date() - mockEndDate.setDate(mockEndDate.getDate() + 2) - - const firstDate = new Date() - firstDate.setDate(firstDate.getDate() - 1) - const secondDate = new Date() - secondDate.setDate(secondDate.getDate() + 1) - - const props = getTestProps() - props.rows = [ - { - draftId: 'mock-draft-id', - exampleId: 'mock-example-id', - completedAt: firstDate - }, - { - draftId: 'mock-draft-id2', - exampleId: 'mock-example-id2', - completedAt: secondDate - } - ] - let component - - // First case - no dates - component = renderer.create() - - expect(getFilteredRows(component)).toEqual(props.rows) - - // Second case - both rows between start and end dates - component = renderer.create( - - ) - - expect(getFilteredRows(component)).toEqual(props.rows) - - // Third case - start date, no end date - component = renderer.create( - - ) - - // Only the second row has a date after the start date - expect(getFilteredRows(component)).toEqual([props.rows[1]]) - - // Fourth case - end date, no start date - component = renderer.create( - - ) - - // Only the first row has a date before the end date - expect(getFilteredRows(component)).toEqual([props.rows[0]]) - }) }) From 3677b6a0971d01a268b91ab7c24bf5b684ebdfa6 Mon Sep 17 00:00:00 2001 From: Brandon Stull Date: Thu, 6 Apr 2023 10:07:01 -0400 Subject: [PATCH 14/25] #2005 Adds additional functionality to check a user's permissions before rendering copy/preview buttons in a module's public page. Adds 'normal' and 'read-only' copy options to a module's public page. Replaces 'edit' button with 'synchronize' button in module dashboard for read-only modules. Adds a new dialog and relevant backend logic to automatically synchronize a read-only copied module with its original if any changes have been made. --- .../express_current_document.test.js | 57 ++++ .../__tests__/express_validators.test.js | 31 ++ .../__tests__/routes/editor.test.js | 3 + .../server/express_current_document.js | 36 ++- .../server/express_validators.js | 11 + .../obojobo-express/server/routes/editor.js | 11 +- .../server/models/draft_permissions.js | 20 +- .../server/models/draft_permissions.test.js | 100 +++++- .../server/models/draft_summary.js | 26 +- .../server/models/draft_summary.test.js | 58 ++++ .../server/models/drafts_metadata.js | 60 ++++ .../server/models/drafts_metadata.test.js | 187 ++++++++++- .../obojobo-repository/server/routes/api.js | 79 ++++- .../server/routes/api.test.js | 209 +++++++++++- .../server/routes/library.js | 8 +- .../server/routes/library.test.js | 4 +- .../shared/actions/dashboard-actions.js | 46 +++ .../shared/actions/dashboard-actions.test.js | 105 ++++-- .../app/obojobo-repository/shared/api-util.js | 4 +- .../shared/api-util.test.js | 6 +- .../__snapshots__/module-menu.test.js.snap | 206 +++++++++++- .../module-sync-dialog.test.js.snap | 204 ++++++++++++ .../shared/components/dashboard-hoc.js | 6 +- .../shared/components/dashboard-hoc.test.js | 3 +- .../shared/components/dashboard.jsx | 17 + .../shared/components/dashboard.test.js | 59 ++++ .../shared/components/module-menu-hoc.js | 5 +- .../shared/components/module-menu-hoc.test.js | 3 +- .../shared/components/module-menu.jsx | 10 +- .../shared/components/module-menu.test.js | 167 +++++++++- .../components/module-options-dialog.jsx | 4 +- .../shared/components/module-sync-dialog.jsx | 70 ++++ .../shared/components/module-sync-dialog.scss | 94 ++++++ .../components/module-sync-dialog.test.js | 91 ++++++ .../shared/components/module.jsx | 1 + .../__snapshots__/page-module.test.js.snap | 302 +++++++++++++++++- .../shared/components/pages/page-library.scss | 6 +- .../shared/components/pages/page-module.jsx | 296 ++++++++++------- .../shared/components/pages/page-module.scss | 14 +- .../components/pages/page-module.test.js | 183 ++++++++++- .../shared/reducers/dashboard-reducer.js | 23 +- .../shared/reducers/dashboard-reducer.test.js | 58 +++- 42 files changed, 2656 insertions(+), 227 deletions(-) create mode 100644 packages/app/obojobo-repository/shared/components/__snapshots__/module-sync-dialog.test.js.snap create mode 100644 packages/app/obojobo-repository/shared/components/module-sync-dialog.jsx create mode 100644 packages/app/obojobo-repository/shared/components/module-sync-dialog.scss create mode 100644 packages/app/obojobo-repository/shared/components/module-sync-dialog.test.js diff --git a/packages/app/obojobo-express/__tests__/express_current_document.test.js b/packages/app/obojobo-express/__tests__/express_current_document.test.js index 11c07818a5..d6e0e4ab5b 100644 --- a/packages/app/obojobo-express/__tests__/express_current_document.test.js +++ b/packages/app/obojobo-express/__tests__/express_current_document.test.js @@ -3,8 +3,10 @@ const documentFunctions = ['setCurrentDocument', 'requireCurrentDocument', 'rese jest.mock('test_node') jest.mock('../server/models/draft') +jest.mock('obojobo-repository/server/models/drafts_metadata') const DraftDocument = oboRequire('server/models/draft') +const DraftsMetadata = require('obojobo-repository/server/models/drafts_metadata') describe('current document middleware', () => { beforeAll(() => {}) @@ -32,6 +34,7 @@ describe('current document middleware', () => { mockNext.mockClear() mockStatus.mockClear() mockJson.mockClear() + DraftsMetadata.getByDraftIdAndKey.mockClear() }) test('calls next', () => { @@ -168,4 +171,58 @@ describe('current document middleware', () => { done() }) }) + + test('requireDraftWritable rejects when no draftId is available', done => { + expect.assertions(1) + + return mockArgs.req + .requireDraftWritable() + .then(() => { + expect(false).toBe('never_called') + done() + }) + .catch(err => { + expect(err.message).toBe('DraftDocument Required') + done() + }) + }) + + test('requireDraftWritable rejects when corresponding draft is read-only', done => { + expect.assertions(3) + DraftsMetadata.getByDraftIdAndKey.mockResolvedValue(true) + + const { req } = mockArgs + req.params = { + draftId: 1 + } + + return req + .requireDraftWritable() + .then(() => { + expect(false).toBe('never_called') + done() + }) + .catch(err => { + expect(DraftsMetadata.getByDraftIdAndKey).toHaveBeenCalledTimes(1) + expect(DraftsMetadata.getByDraftIdAndKey).toHaveBeenCalledWith(1, 'read_only') + expect(err.message).toBe('Requested document is read-only') + done() + }) + }) + + test('requireDraftWritable resolves when corresponding draft is not read-only', done => { + expect.assertions(2) + DraftsMetadata.getByDraftIdAndKey.mockResolvedValue(false) + + const { req } = mockArgs + req.params = { + draftId: 1 + } + + return req.requireDraftWritable().then(() => { + expect(DraftsMetadata.getByDraftIdAndKey).toHaveBeenCalledTimes(1) + expect(DraftsMetadata.getByDraftIdAndKey).toHaveBeenCalledWith(1, 'read_only') + done() + }) + }) }) diff --git a/packages/app/obojobo-express/__tests__/express_validators.test.js b/packages/app/obojobo-express/__tests__/express_validators.test.js index 1bed32b95a..5f4900b71c 100644 --- a/packages/app/obojobo-express/__tests__/express_validators.test.js +++ b/packages/app/obojobo-express/__tests__/express_validators.test.js @@ -2,6 +2,7 @@ jest.mock('test_node') jest.mock('../server/models/user') +jest.mock('../server/logger') let mockRes let mockReq @@ -10,11 +11,14 @@ let mockUser let mockDocument const Validators = oboRequire('server/express_validators') +const logger = oboRequire('server/logger') describe('current user middleware', () => { beforeAll(() => {}) afterAll(() => {}) beforeEach(() => { + logger.error.mockClear() + mockUser = { id: 1, username: 'mock-user', @@ -163,6 +167,33 @@ describe('current user middleware', () => { }) }) + // requireDraftWritable tests + + test('requireDraftWritable resolves', () => { + mockReq.requireDraftWritable = jest.fn().mockResolvedValue() + + return expect( + Validators.requireDraftWritable(mockReq, mockRes, mockNext) + ).resolves.toBeUndefined() + }) + + test('requireDraftWritable calls next when valid', () => { + mockReq.requireDraftWritable = jest.fn().mockResolvedValue() + + return Validators.requireDraftWritable(mockReq, mockRes, mockNext).then(() => { + expect(mockNext).toHaveBeenCalled() + }) + }) + + test('requireDraftWritable calls missing when invalid', () => { + mockReq.requireDraftWritable = jest.fn().mockRejectedValue() + + return Validators.requireDraftWritable(mockReq, mockRes, mockNext).then(() => { + expect(logger.error).toHaveBeenCalledWith('User tried editing read-only module') + expect(mockRes.missing).toHaveBeenCalled() + }) + }) + // requireDraftId tests test('requireDraftId resolves in body', () => { diff --git a/packages/app/obojobo-express/__tests__/routes/editor.test.js b/packages/app/obojobo-express/__tests__/routes/editor.test.js index 337da50c03..2a62a8bd10 100644 --- a/packages/app/obojobo-express/__tests__/routes/editor.test.js +++ b/packages/app/obojobo-express/__tests__/routes/editor.test.js @@ -32,6 +32,9 @@ jest.mock('../../server/express_current_document', () => (req, res, next) => { req.currentDocument = mockCurrentDocument return Promise.resolve(mockCurrentDocument) } + req.requireDraftWritable = () => { + return Promise.resolve(true) + } next() }) diff --git a/packages/app/obojobo-express/server/express_current_document.js b/packages/app/obojobo-express/server/express_current_document.js index 1a9c7e558b..0048c11ad6 100644 --- a/packages/app/obojobo-express/server/express_current_document.js +++ b/packages/app/obojobo-express/server/express_current_document.js @@ -1,6 +1,19 @@ const DraftDocument = oboRequire('server/models/draft') +const DraftsMetadata = require('obojobo-repository/server/models/drafts_metadata') const logger = oboRequire('server/logger') +const _getDraftId = req => { + // Figure out where the draftId is in this request + if (req.params && req.params.draftId) { + return req.params.draftId + } else if (req.body && req.body.draftId) { + return req.body.draftId + } else if (req.body && req.body.event && req.body.event.draft_id) { + return req.body.event.draft_id + } + return null +} + const setCurrentDocument = (req, draftDocument) => { if (!(draftDocument instanceof DraftDocument)) { throw new Error('Invalid DraftDocument for Current draftDocument') @@ -12,20 +25,26 @@ const resetCurrentDocument = req => { req.currentDocument = null } +const requireDraftWritable = req => { + const draftId = _getDraftId(req) + if (draftId === null) { + logger.warn('No Session or Current DraftDocument?', req.currentDocument) + return Promise.reject(new Error('DraftDocument Required')) + } + + return DraftsMetadata.getByDraftIdAndKey(draftId, 'read_only').then(readOnly => { + if (readOnly) return Promise.reject(new Error('Requested document is read-only')) + return Promise.resolve() + }) +} + const requireCurrentDocument = req => { if (req.currentDocument) { return Promise.resolve(req.currentDocument) } // Figure out where the draftId is in this request - let draftId = null - if (req.params && req.params.draftId) { - draftId = req.params.draftId - } else if (req.body && req.body.draftId) { - draftId = req.body.draftId - } else if (req.body && req.body.event && req.body.event.draft_id) { - draftId = req.body.event.draft_id - } + const draftId = _getDraftId(req) if (draftId === null) { logger.warn('No Session or Current DraftDocument?', req.currentDocument) @@ -42,5 +61,6 @@ module.exports = (req, res, next) => { req.setCurrentDocument = setCurrentDocument.bind(this, req) req.requireCurrentDocument = requireCurrentDocument.bind(this, req) req.resetCurrentDocument = resetCurrentDocument.bind(this, req) + req.requireDraftWritable = requireDraftWritable.bind(this, req) next() } diff --git a/packages/app/obojobo-express/server/express_validators.js b/packages/app/obojobo-express/server/express_validators.js index 9b84e8c613..0baaf0bc96 100644 --- a/packages/app/obojobo-express/server/express_validators.js +++ b/packages/app/obojobo-express/server/express_validators.js @@ -41,6 +41,17 @@ exports.requireCurrentVisit = (req, res, next) => requireAndValidateReqMethod(req, res, next, 'getCurrentVisitFromRequest', 'currentVisit') exports.requireCurrentDocument = (req, res, next) => requireAndValidateReqMethod(req, res, next, 'requireCurrentDocument', 'currentDocument') +exports.requireDraftWritable = (req, res, next) => { + return req + .requireDraftWritable() + .then(() => { + next() + }) + .catch(() => { + logger.error('User tried editing read-only module') + res.missing() + }) +} exports.getCurrentUser = (req, res, next) => { return req.getCurrentUser().then(user => { diff --git a/packages/app/obojobo-express/server/routes/editor.js b/packages/app/obojobo-express/server/routes/editor.js index 65ee36a33d..0bbd8d397b 100644 --- a/packages/app/obojobo-express/server/routes/editor.js +++ b/packages/app/obojobo-express/server/routes/editor.js @@ -9,9 +9,13 @@ const { dbLockDurationMinutes } = generalConfig.editLocks const { assetForEnv, webpackAssetPath } = oboRequire('server/asset_resolver') -const { check, requireCanViewEditor, requireCurrentDocument, checkValidationRules } = oboRequire( - 'server/express_validators' -) +const { + check, + requireCanViewEditor, + requireCurrentDocument, + checkValidationRules, + requireDraftWritable +} = oboRequire('server/express_validators') const allowedUploadTypes = mediaConfig.allowedMimeTypesRegex .split('|') .map(i => `.${i}`) @@ -23,6 +27,7 @@ router .route('/visual/:draftId/:page?') .get([ requireCanViewEditor, + requireDraftWritable, requireCurrentDocument, check('revision_id') .optional() diff --git a/packages/app/obojobo-repository/server/models/draft_permissions.js b/packages/app/obojobo-repository/server/models/draft_permissions.js index 7c631f3994..5bc6c016bc 100644 --- a/packages/app/obojobo-repository/server/models/draft_permissions.js +++ b/packages/app/obojobo-repository/server/models/draft_permissions.js @@ -95,14 +95,28 @@ class DraftPermissions { } // returns a boolean - static async userHasPermissionToCopy(userId, draftId) { + static async userHasPermissionToPreview(user, draftId) { try { const results = await Promise.all([ DraftPermissions.draftIsPublic(draftId), - DraftPermissions.getUserAccessLevelToDraft(userId, draftId) + DraftPermissions.getUserAccessLevelToDraft(user.id, draftId) ]) - return results[0] === true || results[1] !== null + return user.perms.includes('canPreviewDrafts') && (results[0] === true || results[1] !== null) + } catch (error) { + throw logger.logError('Error userHasPermissionToPreview', error) + } + } + + // returns a boolean + static async userHasPermissionToCopy(user, draftId) { + try { + const results = await Promise.all([ + DraftPermissions.draftIsPublic(draftId), + DraftPermissions.getUserAccessLevelToDraft(user.id, draftId) + ]) + + return user.perms.includes('canCreateDrafts') && (results[0] === true || results[1] !== null) } catch (error) { throw logger.logError('Error userHasPermissionToCopy', error) } diff --git a/packages/app/obojobo-repository/server/models/draft_permissions.test.js b/packages/app/obojobo-repository/server/models/draft_permissions.test.js index d4d6e5e07e..ba36a1cd8a 100644 --- a/packages/app/obojobo-repository/server/models/draft_permissions.test.js +++ b/packages/app/obojobo-repository/server/models/draft_permissions.test.js @@ -274,21 +274,101 @@ describe('DraftPermissions Model', () => { }) }) + // userHasPermissionToPreview tests + + test.each` + mockUserPerms | draftIsPublic | getUserAccessLevelToDraft | expected + ${['canPreviewDrafts']} | ${null} | ${'mock-db-result'} | ${true} + ${['canPreviewDrafts']} | ${'mock-db-result'} | ${null} | ${true} + ${['canPreviewDrafts']} | ${null} | ${null} | ${false} + ${['canPreviewDrafts']} | ${'mock-db-result'} | ${'mock-db-result'} | ${true} + ${[]} | ${null} | ${'mock-db-result'} | ${false} + ${[]} | ${'mock-db-result'} | ${null} | ${false} + ${[]} | ${null} | ${null} | ${false} + ${[]} | ${'mock-db-result'} | ${'mock-db-result'} | ${false} + `( + 'userHasPermissionToPreview returns $expected with mockUserPerms $mockUserPerms, db results $draftIsPublic and $getUserAccessLevelToDraft', + ({ mockUserPerms, draftIsPublic, getUserAccessLevelToDraft, expected }) => { + expect.hasAssertions() + + const mockUser = { + id: 'MUID', + perms: mockUserPerms + } + + db.oneOrNone.mockResolvedValueOnce(draftIsPublic) // draftIsPublic call + db.oneOrNone.mockResolvedValueOnce(getUserAccessLevelToDraft) // getUserAccessLevelToDraft call + + return DraftPermissions.userHasPermissionToPreview(mockUser, 'MDID').then(hasPermissions => { + expect(hasPermissions).toBe(expected) + + const [isPublicQuery, isPublicOptions] = db.oneOrNone.mock.calls[0] + expect(isPublicQuery).toContain('SELECT') + expect(isPublicQuery).toContain('FROM repository_map_drafts_to_collections') + expect(isPublicOptions).toEqual({ + draftId: 'MDID', + publicLibCollectionId: '00000000-0000-0000-0000-000000000000' + }) + + const [hasPermsQuery, hasPermsOptions] = db.oneOrNone.mock.calls[1] + expect(hasPermsQuery).toContain('SELECT') + expect(hasPermsQuery).toContain('FROM repository_map_user_to_draft') + expect(hasPermsOptions).toEqual({ + draftId: 'MDID', + userId: 'MUID' + }) + }) + } + ) + + test('userHasPermissionToPreview throws and logs error, getUserAccessLeveltoDraft failure', () => { + expect.hasAssertions() + db.oneOrNone.mockResolvedValueOnce('mock-db-results') // draftIsPublic call + db.oneOrNone.mockRejectedValueOnce(mockError) // getUserAccessLevelToDraft call + + return DraftPermissions.userHasPermissionToPreview('MUID', 'MDID').catch(error => { + expect(logger.logError).toHaveBeenCalledWith('Error userHasPermissionToPreview', mockError) + expect(error).toBe(mockError) + }) + }) + + test('userHasPermissionToPreview throws and logs error, draftIsPublic failure', () => { + expect.hasAssertions() + db.oneOrNone.mockRejectedValueOnce(mockError) // draftIsPublic call + db.oneOrNone.mockResolvedValueOnce('mock-db-results') // getUserAccessLevelToDraft call + + return DraftPermissions.userHasPermissionToPreview('MUID', 'MDID').catch(error => { + expect(logger.logError).toHaveBeenCalledWith('Error userHasPermissionToPreview', mockError) + expect(error).toBe(mockError) + }) + }) + + // userHasPermissionToCopy tests + test.each` - draftIsPublic | getUserAccessLevelToDraft | expected - ${null} | ${'mock-db-result'} | ${true} - ${'mock-db-result'} | ${null} | ${true} - ${null} | ${null} | ${false} - ${'mock-db-result'} | ${'mock-db-result'} | ${true} + mockUserPerms | draftIsPublic | getUserAccessLevelToDraft | expected + ${['canCreateDrafts']} | ${null} | ${'mock-db-result'} | ${true} + ${['canCreateDrafts']} | ${'mock-db-result'} | ${null} | ${true} + ${['canCreateDrafts']} | ${null} | ${null} | ${false} + ${['canCreateDrafts']} | ${'mock-db-result'} | ${'mock-db-result'} | ${true} + ${[]} | ${null} | ${'mock-db-result'} | ${false} + ${[]} | ${'mock-db-result'} | ${null} | ${false} + ${[]} | ${null} | ${null} | ${false} + ${[]} | ${'mock-db-result'} | ${'mock-db-result'} | ${false} `( - 'userHasPermissionToCopy returns $expected with db results $draftIsPublic and $getUserAccessLevelToDraft', - ({ draftIsPublic, getUserAccessLevelToDraft, expected }) => { + 'userHasPermissionToCopy returns $expected with mockUserPerms $mockUserPerms, db results $draftIsPublic and $getUserAccessLevelToDraft', + ({ mockUserPerms, draftIsPublic, getUserAccessLevelToDraft, expected }) => { expect.hasAssertions() + const mockUser = { + id: 'MUID', + perms: mockUserPerms + } + db.oneOrNone.mockResolvedValueOnce(draftIsPublic) // draftIsPublic call db.oneOrNone.mockResolvedValueOnce(getUserAccessLevelToDraft) // getUserAccessLevelToDraft call - return DraftPermissions.userHasPermissionToCopy('MUID', 'MDID').then(hasPermissions => { + return DraftPermissions.userHasPermissionToCopy(mockUser, 'MDID').then(hasPermissions => { expect(hasPermissions).toBe(expected) const [isPublicQuery, isPublicOptions] = db.oneOrNone.mock.calls[0] @@ -310,7 +390,7 @@ describe('DraftPermissions Model', () => { } ) - test('userHasPermissionToCopy throws and logs error', () => { + test('userHasPermissionToCopy throws and logs error, getUserAccessLeveltoDraft failure', () => { expect.hasAssertions() db.oneOrNone.mockResolvedValueOnce('mock-db-results') // draftIsPublic call db.oneOrNone.mockRejectedValueOnce(mockError) // getUserAccessLevelToDraft call @@ -321,7 +401,7 @@ describe('DraftPermissions Model', () => { }) }) - test('userHasPermissionToCopy throws and logs error', () => { + test('userHasPermissionToCopy throws and logs error, draftIsPublic failure', () => { expect.hasAssertions() db.oneOrNone.mockRejectedValueOnce(mockError) // draftIsPublic call db.oneOrNone.mockResolvedValueOnce('mock-db-results') // getUserAccessLevelToDraft call diff --git a/packages/app/obojobo-repository/server/models/draft_summary.js b/packages/app/obojobo-repository/server/models/draft_summary.js index 273b12ab25..ec67cb35b3 100644 --- a/packages/app/obojobo-repository/server/models/draft_summary.js +++ b/packages/app/obojobo-repository/server/models/draft_summary.js @@ -18,11 +18,17 @@ const buildQueryWhere = ( count(drafts_content.id) OVER wnd as revision_count, COALESCE(last_value(drafts_content.content->'content'->>'title') OVER wnd, '') as "title", drafts.user_id AS user_id, + drafts_metadata.value AS read_only, ${selectSQL} 'visual' AS editor FROM drafts JOIN drafts_content ON drafts_content.draft_id = drafts.id + LEFT JOIN drafts_metadata + ON ( + drafts_metadata.draft_id = drafts.id + AND drafts_metadata."key" = 'read_only' + ) ${joinSQL} WHERE drafts.deleted = ${deleted} AND ${whereSQL} @@ -49,7 +55,8 @@ class DraftSummary { id, first_name, last_name, - access_level + access_level, + read_only }) { this.draftId = draft_id this.title = title @@ -61,6 +68,7 @@ class DraftSummary { this.editor = editor this.json = content this.revisionId = id + this.readOnly = read_only if (first_name && last_name) this.userFullName = `${first_name} ${last_name}` if (revision_count) this.revisionCount = Number(revision_count) @@ -84,6 +92,22 @@ class DraftSummary { }) } + static fetchByIdMoreRecentThan(id, targetTime) { + return db + .oneOrNone( + buildQueryWhere(`drafts.id = $[id] + AND drafts_content.created_at > $[targetTime]`), + { id, targetTime } + ) + .then(res => { + if (res) return DraftSummary.resultsToObjects(res) + return null + }) + .catch(error => { + throw logger.logError('DraftSummary fetchByIdMoreRecentThan Error', error) + }) + } + static fetchByUserId(userId) { return DraftSummary.fetchAndJoinWhere( `repository_map_user_to_draft.access_level AS access_level,`, diff --git a/packages/app/obojobo-repository/server/models/draft_summary.test.js b/packages/app/obojobo-repository/server/models/draft_summary.test.js index f311179aca..c3edad9281 100644 --- a/packages/app/obojobo-repository/server/models/draft_summary.test.js +++ b/packages/app/obojobo-repository/server/models/draft_summary.test.js @@ -102,11 +102,17 @@ describe('DraftSummary Model', () => { count(drafts_content.id) OVER wnd as revision_count, COALESCE(last_value(drafts_content.content->'content'->>'title') OVER wnd, '') as "title", drafts.user_id AS user_id, + drafts_metadata.value AS read_only, ${selectSQL} 'visual' AS editor FROM drafts JOIN drafts_content ON drafts_content.draft_id = drafts.id + LEFT JOIN drafts_metadata + ON ( + drafts_metadata.draft_id = drafts.id + AND drafts_metadata."key" = 'read_only' + ) ${joinSQL} WHERE drafts.deleted = ${deleted} AND ${whereSQL} @@ -214,6 +220,58 @@ describe('DraftSummary Model', () => { }) }) + test('fetchByIdMoreRecentThan generates the correct query and returns DraftSummary objects correctly', () => { + db.oneOrNone = jest.fn() + db.oneOrNone.mockResolvedValueOnce(mockRawDraftSummaries) + + const mockTargetTime = '1999-01-01 01:00:00.000000+00' + + return DraftSummary.fetchByIdMoreRecentThan('mockDraftId', mockTargetTime).then(summaries => { + const query = queryBuilder(`drafts.id = $[id] + AND drafts_content.created_at > $[targetTime]`) + const [actualQuery, options] = db.oneOrNone.mock.calls[0] + expectQueryToMatch(query, actualQuery) + expect(options).toEqual({ id: 'mockDraftId', targetTime: '1999-01-01 01:00:00.000000+00' }) + expect(summaries.length).toBe(2) + expectIsMockSummary(summaries[0]) + expectIsMockSummary(summaries[1]) + }) + }) + + test('fetchByIdMoreRecentThan generates the correct query and returns for zero results correctly', () => { + db.oneOrNone = jest.fn() + db.oneOrNone.mockResolvedValueOnce() + + const mockTargetTime = '1999-01-01 01:00:00.000000+00' + + return DraftSummary.fetchByIdMoreRecentThan('mockDraftId', mockTargetTime).then(summaries => { + const query = queryBuilder(`drafts.id = $[id] + AND drafts_content.created_at > $[targetTime]`) + const [actualQuery, options] = db.oneOrNone.mock.calls[0] + expectQueryToMatch(query, actualQuery) + expect(options).toEqual({ id: 'mockDraftId', targetTime: '1999-01-01 01:00:00.000000+00' }) + expect(summaries).toBe(null) + }) + }) + + test('fetchByIdMoreRecentThan logs database errors', () => { + expect.hasAssertions() + const mockError = new Error('database error') + logger.logError = jest.fn().mockReturnValueOnce(mockError) + db.oneOrNone.mockRejectedValueOnce(mockError) + + return DraftSummary.fetchByIdMoreRecentThan( + 'mockDraftId', + '1999-01-01 01:00:00.000000+00' + ).catch(err => { + expect(logger.logError).toHaveBeenCalledWith( + 'DraftSummary fetchByIdMoreRecentThan Error', + mockError + ) + expect(err).toBe(mockError) + }) + }) + test('fetchByUserId generates the correct query and returns a DraftSummary object', () => { expect.hasAssertions() diff --git a/packages/app/obojobo-repository/server/models/drafts_metadata.js b/packages/app/obojobo-repository/server/models/drafts_metadata.js index 3d319ee2e1..3b31adc8c0 100644 --- a/packages/app/obojobo-repository/server/models/drafts_metadata.js +++ b/packages/app/obojobo-repository/server/models/drafts_metadata.js @@ -10,6 +10,66 @@ class DraftsMetadata { this.value = value } + static getByDraftId(draftId) { + return db + .manyOrNone( + ` + SELECT * + FROM drafts_metadata + WHERE draft_id = $[draftId] + `, + { draftId } + ) + .then(res => { + if (res) return res.map(r => new DraftsMetadata(r)) + return null + }) + .catch(error => { + logger.logError('DraftMetadata getByDraftId error', error) + throw error + }) + } + + static getByDraftIdAndKey(draftId, key) { + return db + .oneOrNone( + ` + SELECT * + FROM drafts_metadata + WHERE draft_id = $[draftId] AND key = $[key] + `, + { draftId, key } + ) + .then(res => { + if (res) return new DraftsMetadata(res) + return null + }) + .catch(error => { + logger.logError('DraftMetadata getByDraftIdAndKey error', error) + throw error + }) + } + + static getByKeyAndValue(key, value) { + return db + .manyOrNone( + ` + SELECT * + FROM drafts_metadata + WHERE key = $[key] AND value = $[value] + `, + { key, value } + ) + .then(res => { + if (res) return res.map(r => new DraftsMetadata(r)) + return null + }) + .catch(error => { + logger.logError('DraftMetadata getByKeyAndValue error', error) + throw error + }) + } + saveOrCreate() { return db .none( diff --git a/packages/app/obojobo-repository/server/models/drafts_metadata.test.js b/packages/app/obojobo-repository/server/models/drafts_metadata.test.js index 2d52e0f274..ce67bbba87 100644 --- a/packages/app/obojobo-repository/server/models/drafts_metadata.test.js +++ b/packages/app/obojobo-repository/server/models/drafts_metadata.test.js @@ -11,12 +11,26 @@ describe('DraftsMetadata Model', () => { value: 'value' } - const expectMatchesRawMock = draftMetadata => { - expect(draftMetadata.draftId).toBe('mockDraftId') + const mockRawDraftMetadataMultiple = [ + { + draft_id: 'mockDraftId1', + key: 'key', + value: 'value1' + }, + { + draft_id: 'mockDraftId2', + key: 'key', + value: 'value2' + } + ] + + const expectMatchesRawMock = (draftMetadata, number = '') => { + expect(draftMetadata.draftId).toBe(`mockDraftId${number}`) + // these would have dates from the database, but it doesn't really matter here expect(draftMetadata.createdAt).toBeUndefined() expect(draftMetadata.updatedAt).toBeUndefined() expect(draftMetadata.key).toBe('key') - expect(draftMetadata.value).toBe('value') + expect(draftMetadata.value).toBe(`value${number}`) } beforeEach(() => { @@ -76,4 +90,171 @@ describe('DraftsMetadata Model', () => { expect(err).toBe('Error loading DraftsMetadata by query') }) }) + + // getByDraftId tests + + test('getByDraftId generates the correct query and returns DraftsMetadata objects', () => { + expect.hasAssertions() + + db.manyOrNone = jest.fn() + db.manyOrNone.mockResolvedValueOnce(mockRawDraftMetadataMultiple) + + // Trying to match whitespace with the query that's actually running + const query = ` + SELECT * + FROM drafts_metadata + WHERE draft_id = $[draftId] + ` + + return DraftsMetadata.getByDraftId('mockDraftId').then(res => { + expect(db.manyOrNone).toHaveBeenCalledWith(query, { draftId: 'mockDraftId' }) + expect(res.length).toBe(2) + expectMatchesRawMock(res[0], 1) + expectMatchesRawMock(res[1], 2) + }) + }) + + test('getByDraftId generates the correct query and returns for zero results correctly', () => { + expect.hasAssertions() + + db.manyOrNone = jest.fn() + db.manyOrNone.mockResolvedValueOnce() + + // Trying to match whitespace with the query that's actually running + const query = ` + SELECT * + FROM drafts_metadata + WHERE draft_id = $[draftId] + ` + + return DraftsMetadata.getByDraftId('mockDraftId').then(res => { + expect(db.manyOrNone).toHaveBeenCalledWith(query, { draftId: 'mockDraftId' }) + expect(res).toBe(null) + }) + }) + + test('getByDraftId logs database errors', () => { + expect.hasAssertions() + const mockError = new Error('database error') + logger.logError = jest.fn().mockReturnValueOnce(mockError) + db.manyOrNone.mockRejectedValueOnce(mockError) + + return DraftsMetadata.getByDraftId('metaKey', 'metaValue').catch(err => { + expect(logger.logError).toHaveBeenCalledWith('DraftMetadata getByDraftId error', mockError) + expect(err).toBe(mockError) + }) + }) + + // getByDraftIdAndKey tests + + test('getByDraftIdAndKey generates the correct query and returns a DraftsMetadata object', () => { + expect.hasAssertions() + + db.oneOrNone = jest.fn() + db.oneOrNone.mockResolvedValueOnce(mockRawDraftsMetadata) + + // Trying to match whitespace with the query that's actually running + const query = ` + SELECT * + FROM drafts_metadata + WHERE draft_id = $[draftId] AND key = $[key] + ` + + return DraftsMetadata.getByDraftIdAndKey('draftId', 'metaKey').then(res => { + expect(db.oneOrNone).toHaveBeenCalledWith(query, { draftId: 'draftId', key: 'metaKey' }) + expect(res).toBeInstanceOf(DraftsMetadata) + expectMatchesRawMock(res) + }) + }) + + test('getByDraftIdAndKey generates the correct query and returns for zero results correctly', () => { + expect.hasAssertions() + + db.oneOrNone = jest.fn() + db.oneOrNone.mockResolvedValueOnce() + + // Trying to match whitespace with the query that's actually running + const query = ` + SELECT * + FROM drafts_metadata + WHERE draft_id = $[draftId] AND key = $[key] + ` + + return DraftsMetadata.getByDraftIdAndKey('draftId', 'metaKey').then(res => { + expect(db.oneOrNone).toHaveBeenCalledWith(query, { draftId: 'draftId', key: 'metaKey' }) + expect(res).toBe(null) + }) + }) + + test('getByDraftIdAndKey logs database errors', () => { + expect.hasAssertions() + const mockError = new Error('database error') + logger.logError = jest.fn().mockReturnValueOnce(mockError) + db.oneOrNone.mockRejectedValueOnce(mockError) + + return DraftsMetadata.getByDraftIdAndKey('draftId', 'metaKey').catch(err => { + expect(logger.logError).toHaveBeenCalledWith( + 'DraftMetadata getByDraftIdAndKey error', + mockError + ) + expect(err).toBe(mockError) + }) + }) + + // getByKeyAndValue tests + + test('getByKeyAndValue generates the correct query and returns DraftsMetadata objects', () => { + expect.hasAssertions() + + db.manyOrNone = jest.fn() + db.manyOrNone.mockResolvedValueOnce(mockRawDraftMetadataMultiple) + + // Trying to match whitespace with the query that's actually running + const query = ` + SELECT * + FROM drafts_metadata + WHERE key = $[key] AND value = $[value] + ` + + return DraftsMetadata.getByKeyAndValue('metaKey', 'metaValue').then(res => { + expect(db.manyOrNone).toHaveBeenCalledWith(query, { key: 'metaKey', value: 'metaValue' }) + expect(res.length).toBe(2) + expectMatchesRawMock(res[0], 1) + expectMatchesRawMock(res[1], 2) + }) + }) + + test('getByKeyAndValue generates the correct query and returns for zero results correctly', () => { + expect.hasAssertions() + + db.manyOrNone = jest.fn() + db.manyOrNone.mockResolvedValueOnce() + + // Trying to match whitespace with the query that's actually running + const query = ` + SELECT * + FROM drafts_metadata + WHERE key = $[key] AND value = $[value] + ` + + return DraftsMetadata.getByKeyAndValue('metaKey', 'metaValue').then(res => { + expect(db.manyOrNone).toHaveBeenCalledWith(query, { key: 'metaKey', value: 'metaValue' }) + expect(res).toBe(null) + }) + }) + + test('getByKeyAndValue logs database errors', () => { + expect.hasAssertions() + const mockError = new Error('database error') + logger.logError = jest.fn().mockReturnValueOnce(mockError) + db.manyOrNone.mockRejectedValueOnce(mockError) + + return DraftsMetadata.getByKeyAndValue('metaKey', 'metaValue').catch(err => { + expect(logger.logError).toHaveBeenCalledWith( + 'DraftMetadata getByKeyAndValue error', + mockError + ) + expect(err).toBe(mockError) + }) + }) }) diff --git a/packages/app/obojobo-repository/server/routes/api.js b/packages/app/obojobo-repository/server/routes/api.js index f6f55da1e6..20e4795325 100644 --- a/packages/app/obojobo-repository/server/routes/api.js +++ b/packages/app/obojobo-repository/server/routes/api.js @@ -22,7 +22,12 @@ const { fetchAllCollectionsForDraft } = require('../services/collections') const { getUserModuleCount } = require('../services/count') const publicLibCollectionId = require('../../shared/publicLibCollectionId') -const { levelName, levelNumber, FULL } = require('../../../obojobo-express/server/constants') +const { + levelName, + levelNumber, + FULL, + PARTIAL +} = require('../../../obojobo-express/server/constants') // List public drafts router.route('/drafts-public').get((req, res) => { @@ -179,7 +184,9 @@ router const userId = req.currentUser.id const draftId = req.currentDocument.draftId - const canCopy = await DraftPermissions.userHasPermissionToCopy(userId, draftId) + const readOnly = req.body.readOnly + + const canCopy = await DraftPermissions.userHasPermissionToCopy(req.currentUser, draftId) if (!canCopy) { res.notAuthorized('Current user has no permissions to copy this draft') return @@ -191,14 +198,25 @@ router draftObject.content.title = newTitle const newDraft = await Draft.createWithContent(userId, draftObject) - const draftMetadata = new DraftsMetadata({ + const copiedDraftMetadata = new DraftsMetadata({ draft_id: newDraft.id, key: 'copied', value: draftId }) + let readOnlyDraftMetadata = null + + if (readOnly) { + readOnlyDraftMetadata = new DraftsMetadata({ + draft_id: newDraft.id, + key: 'read_only', + value: true + }) + } + await Promise.all([ - draftMetadata.saveOrCreate(), + copiedDraftMetadata.saveOrCreate(), + readOnlyDraftMetadata ? readOnlyDraftMetadata.saveOrCreate() : Promise.resolve(), insertEvent({ actorTime: 'now()', action: 'draft:copy', @@ -220,6 +238,59 @@ router } }) +// check for any changes to the draft's original +router + .route('/drafts/:draftId/sync') + .get([requireCurrentUser, requireCurrentDocument, requireCanCreateDrafts]) + .get((req, res) => { + DraftsMetadata.getByDraftIdAndKey(req.currentDocument.draftId, 'copied') + .then(md => { + return DraftSummary.fetchByIdMoreRecentThan(md.value, md.updatedAt) + }) + .then(mostRecentOriginalRevision => { + res.success(mostRecentOriginalRevision) + }) + .catch(e => { + res.unexpected(e) + }) + }) + +// replace a read-only draft's draft_content with its parent's most recent draft_content +router + .route('/drafts/:draftId/sync') + .patch([requireCurrentUser, requireCurrentDocument, requireCanCreateDrafts]) + .patch((req, res) => { + let copyMeta = null + + DraftsMetadata.getByDraftIdAndKey(req.currentDocument.draftId, 'copied') + .then(async md => { + const userAccess = await DraftPermissions.getUserAccessLevelToDraft( + req.currentUser.id, + req.currentDocument.draftId + ) + + if (!(userAccess === FULL || userAccess === PARTIAL)) { + res.notAuthorized('Current User does not have permission to share this draft') + return + } + + copyMeta = md + // use original draft ID from the copy metadata + const oldDraft = await Draft.fetchById(md.value) + const draftObject = oldDraft.root.toObject() + const newTitle = req.body.title ? req.body.title : draftObject.content.title + ' Copy' + draftObject.content.title = newTitle + return Draft.updateContent(req.currentDocument.draftId, req.currentUser.id, draftObject) + }) + .then(() => { + copyMeta.saveOrCreate() + res.success() + }) + .catch(e => { + res.unexpected(e) + }) + }) + // list a draft's permissions router .route('/drafts/:draftId/permission') diff --git a/packages/app/obojobo-repository/server/routes/api.test.js b/packages/app/obojobo-repository/server/routes/api.test.js index db541d935e..613764c281 100644 --- a/packages/app/obojobo-repository/server/routes/api.test.js +++ b/packages/app/obojobo-repository/server/routes/api.test.js @@ -525,12 +525,13 @@ describe('repository api route', () => { .send({ visitId: 'mockVisitId' }) .then(response => { expect(DraftPermissions.userHasPermissionToCopy).toHaveBeenCalledWith( - mockCurrentUser.id, + mockCurrentUser, mockCurrentDocument.draftId ) expect(Draft.fetchById).toHaveBeenCalledWith(mockCurrentDocument.draftId) expect(mockDraftObject.content.title).toEqual('mockDraftTitle Copy') expect(Draft.createWithContent).toHaveBeenCalledWith(mockCurrentUser.id, mockDraftObject) + expect(DraftsMetadata).toHaveBeenCalledTimes(1) expect(DraftsMetadata).toHaveBeenCalledWith({ draft_id: 'mockNewDraftId', key: 'copied', @@ -589,6 +590,54 @@ describe('repository api route', () => { }) }) + test('post /drafts/:draftId/copy makes the copy read-only if specified', () => { + expect.hasAssertions() + + const mockDraftObject = { + id: 'mockNewDraftId', + content: { + id: 'mockNewDraftContentId', + title: 'mockDraftTitle' + } + } + + const mockDraftRootToObject = jest.fn() + mockDraftRootToObject.mockReturnValueOnce(mockDraftObject) + + const mockDraft = { + root: { + toObject: mockDraftRootToObject + } + } + + DraftPermissions.userHasPermissionToCopy.mockResolvedValueOnce(true) + + Draft.fetchById = jest.fn() + Draft.fetchById.mockResolvedValueOnce(mockDraft) + Draft.createWithContent.mockResolvedValueOnce(mockDraftObject) + + return request(app) + .post('/drafts/mockDraftId/copy') + .send({ visitId: 'mockVisitId', title: 'New Draft Title', readOnly: true }) + .then(() => { + expect(mockDraftObject.content.title).toEqual('New Draft Title') + // everything else is unchanged from above + expect(DraftsMetadata).toHaveBeenCalledTimes(2) + expect(DraftsMetadata).toHaveBeenCalledWith({ + draft_id: 'mockNewDraftId', + key: 'copied', + value: mockCurrentDocument.draftId + }) + expect({ + draft_id: 'mockNewDraftId', + key: 'read_only', + value: true + }) + expect(DraftsMetadata.mock.instances[0].saveOrCreate).toHaveBeenCalledTimes(1) + expect(DraftsMetadata.mock.instances[1].saveOrCreate).toHaveBeenCalledTimes(1) + }) + }) + test('post /drafts/:draftId/copy returns the expected response when user can not copy draft', () => { expect.hasAssertions() @@ -599,7 +648,7 @@ describe('repository api route', () => { .then(response => { expect(DraftPermissions.userHasPermissionToCopy).toHaveBeenCalledTimes(1) expect(DraftPermissions.userHasPermissionToCopy).toHaveBeenCalledWith( - mockCurrentUser.id, + mockCurrentUser, mockCurrentDocument.draftId ) expect(response.statusCode).toBe(401) @@ -616,7 +665,7 @@ describe('repository api route', () => { .then(response => { expect(DraftPermissions.userHasPermissionToCopy).toHaveBeenCalledTimes(1) expect(DraftPermissions.userHasPermissionToCopy).toHaveBeenCalledWith( - mockCurrentUser.id, + mockCurrentUser, mockCurrentDocument.draftId ) expect(response.statusCode).toBe(500) @@ -624,6 +673,160 @@ describe('repository api route', () => { }) }) + test('get /drafts/:draftId/sync calls the correct functions and returns the expected response', () => { + expect.hasAssertions() + + const mockMetadataResponse = { + value: 'mockOriginalDraftId', + updatedAt: '1999-01-01 01:00:00.000000+00' + } + + const mockDraftResponse = { + draftId: 'originalDraftId' + } + + DraftsMetadata.getByDraftIdAndKey.mockResolvedValueOnce(mockMetadataResponse) + DraftSummary.fetchByIdMoreRecentThan.mockResolvedValueOnce(mockDraftResponse) + + return request(app) + .get('/drafts/mockDraftId/sync') + .then(response => { + expect(DraftsMetadata.getByDraftIdAndKey).toHaveBeenCalledWith( + mockCurrentDocument.draftId, + 'copied' + ) + expect(DraftSummary.fetchByIdMoreRecentThan).toHaveBeenCalledWith( + mockMetadataResponse.value, + mockMetadataResponse.updatedAt + ) + expect(response.body).toEqual(mockDraftResponse) + expect(response.statusCode).toBe(200) + }) + }) + + test('get /drafts/:draftId/sync returns unexpected when encountering an error', () => { + expect.hasAssertions() + + const mockError = new Error('not found in db') + DraftsMetadata.getByDraftIdAndKey.mockRejectedValue(mockError) + + return request(app) + .get('/drafts/mockDraftId/sync') + .then(response => { + expect(DraftsMetadata.getByDraftIdAndKey).toHaveBeenCalledWith( + mockCurrentDocument.draftId, + 'copied' + ) + expect(DraftSummary.fetchByIdMoreRecentThan).not.toHaveBeenCalled() + expect(response.statusCode).toBe(500) + }) + }) + + test('patch /drafts/:draftId/sync returns notAuthorized for users with minimal access to the draft', () => { + expect.hasAssertions() + + const mockMetaSaveOrCreate = jest.fn() + DraftsMetadata.getByDraftIdAndKey.mockResolvedValueOnce({ + value: 'mockOriginalDraftId', + updatedAt: '1999-01-01 01:00:00.000000+00', + saveOrCreate: mockMetaSaveOrCreate + }) + + DraftPermissions.getUserAccessLevelToDraft.mockResolvedValueOnce(MINIMAL) + + return request(app) + .patch('/drafts/mockDraftId/sync') + .then(() => { + expect(DraftsMetadata.getByDraftIdAndKey).toHaveBeenCalledWith('mockDraftId', 'copied') + expect(Draft.fetchById).not.toHaveBeenCalled() + expect(Draft.updateContent).not.toHaveBeenCalled() + expect(mockMetaSaveOrCreate).not.toHaveBeenCalled() + }) + }) + + test('patch /drafts/:draftId/sync returns and calls functions correctly for users with partial access to the draft, no optional title', () => { + expect.hasAssertions() + + const mockMetaSaveOrCreate = jest.fn() + DraftsMetadata.getByDraftIdAndKey.mockResolvedValueOnce({ + value: 'mockOriginalDraftId', + updatedAt: '1999-01-01 01:00:00.000000+00', + saveOrCreate: mockMetaSaveOrCreate + }) + + DraftPermissions.getUserAccessLevelToDraft.mockResolvedValueOnce(PARTIAL) + + const mockDraftObject = { + id: 'mockNewDraftId', + content: { + id: 'mockNewDraftContentId', + title: 'mockDraftTitle' + } + } + + const mockDraftRootToObject = jest.fn() + mockDraftRootToObject.mockReturnValueOnce(mockDraftObject) + + const mockDraft = { + root: { + toObject: mockDraftRootToObject + } + } + Draft.fetchById.mockResolvedValueOnce(mockDraft) + + return request(app) + .patch('/drafts/mockDraftId/sync') + .then(() => { + expect(DraftsMetadata.getByDraftIdAndKey).toHaveBeenCalledWith('mockDraftId', 'copied') + expect(Draft.fetchById).toHaveBeenCalledWith('mockOriginalDraftId') + expect(mockDraftObject.content.title).toEqual('mockDraftTitle Copy') + expect(Draft.updateContent).toHaveBeenCalled() + expect(mockMetaSaveOrCreate).toHaveBeenCalled() + }) + }) + + test('patch /drafts/:draftId/sync returns and calls functions correctly for users with partial access to the draft, optional title', () => { + expect.hasAssertions() + + const mockMetaSaveOrCreate = jest.fn() + DraftsMetadata.getByDraftIdAndKey.mockResolvedValueOnce({ + value: 'mockOriginalDraftId', + updatedAt: '1999-01-01 01:00:00.000000+00', + saveOrCreate: mockMetaSaveOrCreate + }) + + DraftPermissions.getUserAccessLevelToDraft.mockResolvedValueOnce(PARTIAL) + + const mockDraftObject = { + id: 'mockNewDraftId', + content: { + id: 'mockNewDraftContentId', + title: 'mockDraftTitle' + } + } + + const mockDraftRootToObject = jest.fn() + mockDraftRootToObject.mockReturnValueOnce(mockDraftObject) + + const mockDraft = { + root: { + toObject: mockDraftRootToObject + } + } + Draft.fetchById.mockResolvedValueOnce(mockDraft) + + return request(app) + .patch('/drafts/mockDraftId/sync') + .send({ title: 'specified title' }) + .then(() => { + expect(DraftsMetadata.getByDraftIdAndKey).toHaveBeenCalledWith('mockDraftId', 'copied') + expect(Draft.fetchById).toHaveBeenCalledWith('mockOriginalDraftId') + expect(mockDraftObject.content.title).toEqual('specified title') + expect(Draft.updateContent).toHaveBeenCalled() + expect(mockMetaSaveOrCreate).toHaveBeenCalled() + }) + }) + test('get /drafts/:draftId/permission returns the expected response', () => { expect.hasAssertions() const userToJSON = jest.fn().mockReturnValue('filtered-user') diff --git a/packages/app/obojobo-repository/server/routes/library.js b/packages/app/obojobo-repository/server/routes/library.js index 5facba2bb3..b19265ffc7 100644 --- a/packages/app/obojobo-repository/server/routes/library.js +++ b/packages/app/obojobo-repository/server/routes/library.js @@ -151,8 +151,13 @@ router owner = await UserModel.fetchById(module.userId) } + const canPreview = await DraftPermissions.userHasPermissionToPreview( + req.currentUser, + module.draftId + ) + const canCopy = await DraftPermissions.userHasPermissionToCopy( - req.currentUser.id, + req.currentUser, module.draftId ) @@ -163,6 +168,7 @@ router // must use webpackAssetPath for all webpack assets to work in dev and production! appCSSUrl: webpackAssetPath('repository.css'), appJsUrl: webpackAssetPath('page-module.js'), + canPreview, canCopy } res.render('pages/page-module-server.jsx', props) diff --git a/packages/app/obojobo-repository/server/routes/library.test.js b/packages/app/obojobo-repository/server/routes/library.test.js index 812f2f7639..110a26b54f 100644 --- a/packages/app/obojobo-repository/server/routes/library.test.js +++ b/packages/app/obojobo-repository/server/routes/library.test.js @@ -214,7 +214,7 @@ describe('repository library route', () => { expect(UserModel.fetchById).toHaveBeenCalledWith(99) expect(DraftPermissions.userHasPermissionToCopy).toHaveBeenCalledTimes(1) expect(DraftPermissions.userHasPermissionToCopy).toHaveBeenCalledWith( - mockCurrentUser.id, + mockCurrentUser, 'mockDraftId' ) expect(response.header['content-type']).toContain('text/html') @@ -301,7 +301,7 @@ describe('repository library route', () => { expect(DraftSummary.fetchById).toHaveBeenCalledWith(publicLibCollectionId) expect(UserModel.fetchById).not.toHaveBeenCalled() expect(DraftPermissions.userHasPermissionToCopy).toHaveBeenCalledWith( - mockCurrentUser.id, + mockCurrentUser, 'mockDraftId' ) expect(response.header['content-type']).toContain('text/html') diff --git a/packages/app/obojobo-repository/shared/actions/dashboard-actions.js b/packages/app/obojobo-repository/shared/actions/dashboard-actions.js index c9071c48eb..6426e5f660 100644 --- a/packages/app/obojobo-repository/shared/actions/dashboard-actions.js +++ b/packages/app/obojobo-repository/shared/actions/dashboard-actions.js @@ -210,6 +210,16 @@ const apiGetModuleLock = async draftId => { return data.value } +const apiGetModuleSyncStatus = draftId => { + const options = { ...defaultOptions() } + return fetch(`/api/drafts/${draftId}/sync`, options).then(res => res.json()) +} + +const apiSyncModuleUpdates = draftId => { + const options = { ...defaultOptions(), method: 'PATCH' } + return fetch(`/api/drafts/${draftId}/sync`, options).then(res => res.json()) +} + // ================== ACTIONS =================== const SHOW_MODULE_PERMISSIONS = 'SHOW_MODULE_PERMISSIONS' @@ -445,6 +455,38 @@ const showModuleMore = module => ({ module }) +const SHOW_MODULE_SYNC = 'SHOW_MODULE_SYNC' +const showModuleSync = module => ({ + type: SHOW_MODULE_SYNC, + meta: { module }, + promise: apiGetModuleSyncStatus(module.draftId) +}) + +const SYNC_MODULE_UPDATES = 'SYNC_MODULE_UPDATES' +const syncModuleUpdates = (draftId, options = { ...defaultModuleModeOptions }) => { + let apiModuleGetCall + + switch (options.mode) { + case MODE_COLLECTION: + apiModuleGetCall = () => { + return apiGetModulesForCollection(options.collectionId) + } + break + case MODE_RECENT: + apiModuleGetCall = apiGetMyRecentModules + break + case MODE_ALL: + default: + apiModuleGetCall = apiGetMyModules + break + } + + return { + type: SYNC_MODULE_UPDATES, + promise: apiSyncModuleUpdates(draftId).then(apiModuleGetCall) + } +} + const SHOW_MODULE_MANAGE_COLLECTIONS = 'SHOW_MODULE_MANAGE_COLLECTIONS' const showModuleManageCollections = module => ({ type: SHOW_MODULE_MANAGE_COLLECTIONS, @@ -644,6 +686,8 @@ module.exports = { SELECT_MODULES, DESELECT_MODULES, SHOW_MODULE_MORE, + SHOW_MODULE_SYNC, + SYNC_MODULE_UPDATES, CREATE_NEW_COLLECTION, SHOW_MODULE_MANAGE_COLLECTIONS, LOAD_MODULE_COLLECTIONS, @@ -686,6 +730,8 @@ module.exports = { loadUsersForModule, clearPeopleSearchResults, showModuleMore, + showModuleSync, + syncModuleUpdates, showCollectionManageModules, loadCollectionModules, collectionAddModule, diff --git a/packages/app/obojobo-repository/shared/actions/dashboard-actions.test.js b/packages/app/obojobo-repository/shared/actions/dashboard-actions.test.js index 97c8e4460c..5be6a418c1 100644 --- a/packages/app/obojobo-repository/shared/actions/dashboard-actions.test.js +++ b/packages/app/obojobo-repository/shared/actions/dashboard-actions.test.js @@ -1886,23 +1886,18 @@ describe('Dashboard Actions', () => { }) }) - const assertBulkRestoreModulesRunsWithOptions = (secondaryLookupUrl, fetchBody, options) => { + test('bulkRestoreModules returns expected output and calls other functions', () => { global.fetch.mockResolvedValue(standardFetchResponse) - const actionReply = DashboardActions.bulkRestoreModules( - ['mockDraftId1', 'mockDraftId2'], - options - ) + const actionReply = DashboardActions.bulkRestoreModules(['mockDraftId1', 'mockDraftId2']) expect(global.fetch).toHaveBeenCalledTimes(2) expect(global.fetch).toHaveBeenCalledWith('/api/drafts/restore/mockDraftId1', { ...defaultFetchOptions, - method: 'PUT', - body: fetchBody + method: 'PUT' }) expect(global.fetch).toHaveBeenCalledWith('/api/drafts/restore/mockDraftId2', { ...defaultFetchOptions, - method: 'PUT', - body: fetchBody + method: 'PUT' }) global.fetch.mockReset() global.fetch.mockResolvedValueOnce({ @@ -1916,26 +1911,22 @@ describe('Dashboard Actions', () => { return actionReply.promise.then(finalResponse => { expect(standardFetchResponse.json).toHaveBeenCalled() - expect(global.fetch).toHaveBeenCalledWith(secondaryLookupUrl, defaultFetchOptions) + expect(global.fetch).toHaveBeenCalledWith('/api/drafts-deleted', defaultFetchOptions) expect(finalResponse).toEqual({ value: 'mockSecondaryResponse' }) }) - } - test('bulkRestoreModules returns expected output and calls other functions', () => { - return assertBulkRestoreModulesRunsWithOptions('/api/drafts-deleted') }) - const assertGetMyDeletedModulesRunsWithOptions = (secondaryLookupUrl, fetchBody, options) => { + test('apiGetMyDeletedModules returns the expected output', () => { global.fetch.mockResolvedValue(standardFetchResponse) - const actionReply = DashboardActions.getDeletedModules(options) + const actionReply = DashboardActions.getDeletedModules() expect(global.fetch).toHaveBeenCalledTimes(1) expect(global.fetch).toHaveBeenCalledWith('/api/drafts-deleted', { ...defaultFetchOptions, - method: 'GET', - body: fetchBody + method: 'GET' }) global.fetch.mockReset() global.fetch.mockResolvedValueOnce({ @@ -1952,20 +1943,16 @@ describe('Dashboard Actions', () => { expect(global.fetch).not.toHaveBeenCalled() expect(finalResponse).toEqual({ value: 'mockVal' }) }) - } - test('apiGetMyDeletedModules returns the expected output', () => { - return assertGetMyDeletedModulesRunsWithOptions('/api/drafts-deleted') }) - const assertGetMyModulesRunsWithOptions = (secondaryLookupUrl, fetchBody, options) => { + test('apiGetMyModules returns the expected output', () => { global.fetch.mockResolvedValue(standardFetchResponse) - const actionReply = DashboardActions.getModules(options) + const actionReply = DashboardActions.getModules() expect(global.fetch).toHaveBeenCalledTimes(1) expect(global.fetch).toHaveBeenCalledWith('/api/drafts', { ...defaultFetchOptions, - method: 'GET', - body: fetchBody + method: 'GET' }) global.fetch.mockReset() global.fetch.mockResolvedValueOnce({ @@ -1982,8 +1969,74 @@ describe('Dashboard Actions', () => { expect(global.fetch).not.toHaveBeenCalled() expect(finalResponse).toEqual({ value: 'mockVal' }) }) + }) + + test('showModuleSync returns the expected output', () => { + global.fetch.mockResolvedValue(standardFetchResponse) + + const mockModule = { draftId: 'mockDraftId' } + const actionReply = DashboardActions.showModuleSync(mockModule) + + expect(global.fetch).toHaveBeenCalledWith('/api/drafts/mockDraftId/sync', defaultFetchOptions) + expect(actionReply).toEqual({ + type: DashboardActions.SHOW_MODULE_SYNC, + meta: { + module: mockModule + }, + promise: expect.any(Object) + }) + }) + + // three (plus one default) ways of calling syncModuleUpdates + const assertSyncModuleUpdatesRunsWithOptions = (secondaryLookupUrl, options) => { + global.fetch.mockResolvedValueOnce(standardFetchResponse) + const actionReply = DashboardActions.syncModuleUpdates('mockDraftId', options) + + expect(global.fetch).toHaveBeenCalledWith('/api/drafts/mockDraftId/sync', { + ...defaultFetchOptions, + method: 'PATCH' + }) + global.fetch.mockReset() + // two additional API calls are made following the first + global.fetch.mockResolvedValueOnce({ + json: () => ({ value: 'mockSecondVal1' }) + }) + + expect(actionReply).toEqual({ + type: DashboardActions.SYNC_MODULE_UPDATES, + promise: expect.any(Object) + }) + + return actionReply.promise.then(finalResponse => { + expect(standardFetchResponse.json).toHaveBeenCalled() + expect(global.fetch).toHaveBeenCalledWith(secondaryLookupUrl, defaultFetchOptions) + + expect(finalResponse).toEqual({ + value: 'mockSecondVal1' + }) + }) } - test('apiGetMyModules returns the expected output', () => { - return assertGetMyModulesRunsWithOptions('/api/drafts') + //options will contain mode: MODE_COLLECTION and collectionId + test('syncModuleUpdates returns expected output and calls other functions, mode MODE_COLLECTION', () => { + const options = { + mode: MODE_COLLECTION, + collectionId: 'mockCollectionId' + } + return assertSyncModuleUpdatesRunsWithOptions( + '/api/collections/mockCollectionId/modules', + options + ) + }) + //options will contain mode: MODE_RECENT + test('syncModuleUpdates returns expected output and calls other functions, mode MODE_RECENT', () => { + return assertSyncModuleUpdatesRunsWithOptions('/api/recent/drafts', { mode: MODE_RECENT }) + }) + //options will contain mode: MODE_ALL + test('syncModuleUpdates returns expected output and calls other functions, mode MODE_ALL', () => { + return assertSyncModuleUpdatesRunsWithOptions('/api/drafts', { mode: MODE_ALL }) + }) + // no options, default should be equivalent to MODE_ALL + test('syncModuleUpdates returns expected output and calls other functions, default', () => { + return assertSyncModuleUpdatesRunsWithOptions('/api/drafts') }) }) diff --git a/packages/app/obojobo-repository/shared/api-util.js b/packages/app/obojobo-repository/shared/api-util.js index ae43aad975..5e178c44dd 100644 --- a/packages/app/obojobo-repository/shared/api-util.js +++ b/packages/app/obojobo-repository/shared/api-util.js @@ -1,8 +1,8 @@ const API = require('obojobo-document-engine/src/scripts/viewer/util/api') const ViewerAPI = { - copyModule(draftId) { - return API.post(`/api/drafts/${draftId}/copy`).then(result => { + copyModule(draftId, readOnly = false) { + return API.post(`/api/drafts/${draftId}/copy`, { readOnly }).then(result => { if (result.status === 200) { window.location.assign('/dashboard') } else if (result.status === 401) { diff --git a/packages/app/obojobo-repository/shared/api-util.test.js b/packages/app/obojobo-repository/shared/api-util.test.js index 8a41b70ca1..ff0088c6f8 100644 --- a/packages/app/obojobo-repository/shared/api-util.test.js +++ b/packages/app/obojobo-repository/shared/api-util.test.js @@ -39,7 +39,7 @@ describe('repository apiutil', () => { API.post.mockResolvedValueOnce({ status: 200 }) return APIUtil.copyModule('mockDraftId').then(() => { - expect(API.post).toHaveBeenCalledWith('/api/drafts/mockDraftId/copy') + expect(API.post).toHaveBeenCalledWith('/api/drafts/mockDraftId/copy', { readOnly: false }) expect(global.location.assign).toHaveBeenCalledWith('/dashboard') }) }) @@ -50,7 +50,7 @@ describe('repository apiutil', () => { API.post.mockResolvedValueOnce({ status: 401 }) return APIUtil.copyModule('mockDraftId').then(() => { - expect(API.post).toHaveBeenCalledWith('/api/drafts/mockDraftId/copy') + expect(API.post).toHaveBeenCalledWith('/api/drafts/mockDraftId/copy', { readOnly: false }) expect(global.location.assign).not.toHaveBeenCalled() expect(global.alert).toHaveBeenCalledTimes(1) expect(global.alert).toHaveBeenCalledWith('You are not authorized to copy this module') @@ -63,7 +63,7 @@ describe('repository apiutil', () => { API.post.mockResolvedValueOnce({ status: 500 }) return APIUtil.copyModule('mockDraftId').then(() => { - expect(API.post).toHaveBeenCalledWith('/api/drafts/mockDraftId/copy') + expect(API.post).toHaveBeenCalledWith('/api/drafts/mockDraftId/copy', { readOnly: false }) expect(global.location.assign).not.toHaveBeenCalled() expect(global.alert).toHaveBeenCalledTimes(1) expect(global.alert).toHaveBeenCalledWith('Something went wrong while copying') diff --git a/packages/app/obojobo-repository/shared/components/__snapshots__/module-menu.test.js.snap b/packages/app/obojobo-repository/shared/components/__snapshots__/module-menu.test.js.snap index 2c6438472f..3c52a81cbd 100644 --- a/packages/app/obojobo-repository/shared/components/__snapshots__/module-menu.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/__snapshots__/module-menu.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`ModuleMenu ModuleMenu renders correctly with "Full" access level 1`] = ` +exports[`ModuleMenu ModuleMenu renders correctly with "Full" access level, no readOnly 1`] = `
@@ -40,7 +40,137 @@ exports[`ModuleMenu ModuleMenu renders correctly with "Full" access level 1`] =
`; -exports[`ModuleMenu ModuleMenu renders correctly with "Minimal" access level 1`] = ` +exports[`ModuleMenu ModuleMenu renders correctly with "Full" access level, readOnly false 1`] = ` +
+
+ + Preview + + + Edit + + +
+ +
+
+`; + +exports[`ModuleMenu ModuleMenu renders correctly with "Full" access level, readOnly true 1`] = ` +
+
+ + Preview + + + +
+ +
+
+`; + +exports[`ModuleMenu ModuleMenu renders correctly with "Minimal" access level, no readOnly 1`] = ` +
+
+ + Preview + +
+ +
+
+`; + +exports[`ModuleMenu ModuleMenu renders correctly with "Minimal" access level, readOnly false 1`] = ` +
+
+ + Preview + +
+ +
+
+`; + +exports[`ModuleMenu ModuleMenu renders correctly with "Minimal" access level, readOnly true 1`] = `
@@ -66,7 +196,7 @@ exports[`ModuleMenu ModuleMenu renders correctly with "Minimal" access level 1`]
`; -exports[`ModuleMenu ModuleMenu renders correctly with "Partial" access level 1`] = ` +exports[`ModuleMenu ModuleMenu renders correctly with "Partial" access level, no readOnly 1`] = `
@@ -100,12 +230,12 @@ exports[`ModuleMenu ModuleMenu renders correctly with "Partial" access level 1`]
`; -exports[`ModuleMenu ModuleMenu renders correctly with className prop 1`] = ` +exports[`ModuleMenu ModuleMenu renders correctly with "Partial" access level, readOnly false 1`] = `
`; -exports[`ModuleMenu ModuleMenu renders correctly with standard expected props 1`] = ` +exports[`ModuleMenu ModuleMenu renders correctly with "Partial" access level, readOnly true 1`] = `
+ + Preview + + +
+ +
+
+`; + +exports[`ModuleMenu ModuleMenu renders correctly with className prop 1`] = ` +
+
Edit + +
+ +
+
+`; + +exports[`ModuleMenu ModuleMenu renders correctly with standard expected props 1`] = ` +
+
+ + Preview +
+
+
+

+ Synchronize Updates +

+
+ This dialog will indicate if any changes have been made to the module this copy was created from. +
+ If there have been any changes, you will be given the option to automatically update this copy to match. +
+ Please note that synchronizing changes may also change this copy's title. +
+
+

+ Checking for updates to this module's original... +

+
+
+
+`; + +exports[`ModuleSyncDialog ModuleSyncDialog renders with provided newest as null 1`] = ` +
+
+
+ +
+
+ Mock Draft Title +
+ +
+
+

+ Synchronize Updates +

+
+ This dialog will indicate if any changes have been made to the module this copy was created from. +
+ If there have been any changes, you will be given the option to automatically update this copy to match. +
+ Please note that synchronizing changes may also change this copy's title. +
+
+

+ No changes found, copy is up-to-date. +

+
+
+
+`; + +exports[`ModuleSyncDialog ModuleSyncDialog renders with provided newest module 1`] = ` +
+
+
+ +
+
+ Mock Draft Title +
+ +
+
+

+ Synchronize Updates +

+
+ This dialog will indicate if any changes have been made to the module this copy was created from. +
+ If there have been any changes, you will be given the option to automatically update this copy to match. +
+ Please note that synchronizing changes may also change this copy's title. +
+
+
+
+ +
+
+ Original Mock Draft Title +
+ + Last updated: + 1999-01-01 1:01 AM + +
+ +
+
+
+
+`; diff --git a/packages/app/obojobo-repository/shared/components/dashboard-hoc.js b/packages/app/obojobo-repository/shared/components/dashboard-hoc.js index a54ef88455..e2e244a1df 100644 --- a/packages/app/obojobo-repository/shared/components/dashboard-hoc.js +++ b/packages/app/obojobo-repository/shared/components/dashboard-hoc.js @@ -36,7 +36,8 @@ const { checkModuleLock, getDeletedModules, getModules, - bulkRestoreModules + bulkRestoreModules, + syncModuleUpdates } = require('../actions/dashboard-actions') const mapStoreStateToProps = state => state const mapActionsToProps = { @@ -75,7 +76,8 @@ const mapActionsToProps = { checkModuleLock, getDeletedModules, getModules, - bulkRestoreModules + bulkRestoreModules, + syncModuleUpdates } module.exports = connect( mapStoreStateToProps, diff --git a/packages/app/obojobo-repository/shared/components/dashboard-hoc.test.js b/packages/app/obojobo-repository/shared/components/dashboard-hoc.test.js index 65bbcf9a53..3365f99698 100644 --- a/packages/app/obojobo-repository/shared/components/dashboard-hoc.test.js +++ b/packages/app/obojobo-repository/shared/components/dashboard-hoc.test.js @@ -59,7 +59,8 @@ describe('Dashboard HOC', () => { bulkRestoreModules: DashboardActions.bulkRestoreModules, changeAccessLevel: DashboardActions.changeAccessLevel, getDeletedModules: DashboardActions.getDeletedModules, - getModules: DashboardActions.getModules + getModules: DashboardActions.getModules, + syncModuleUpdates: DashboardActions.syncModuleUpdates }) expect(mockReduxConnectReturn).toHaveBeenCalledTimes(1) diff --git a/packages/app/obojobo-repository/shared/components/dashboard.jsx b/packages/app/obojobo-repository/shared/components/dashboard.jsx index e8af9ec058..acfd4c58df 100644 --- a/packages/app/obojobo-repository/shared/components/dashboard.jsx +++ b/packages/app/obojobo-repository/shared/components/dashboard.jsx @@ -8,6 +8,7 @@ const RepositoryBanner = require('./repository-banner') const Module = require('./module') const ModulePermissionsDialog = require('./module-permissions-dialog') const ModuleOptionsDialog = require('./module-options-dialog') +const ModuleSyncDialog = require('./module-sync-dialog') const VersionHistoryDialog = require('./version-history-dialog') const Button = require('./button') const MultiButton = require('./multi-button') @@ -42,6 +43,16 @@ const renderOptionsDialog = (props, extension) => ( /> ) +const renderSyncDialog = (props, extension) => ( + +) + const renderPermissionsDialog = (props, extension) => ( { extendedProps.deleteModulePermissions = (draftId, userId) => { props.deleteModulePermissions(draftId, userId, extendedOptions) } + extendedProps.syncModuleUpdates = draftId => props.syncModuleUpdates(draftId, extendedOptions) break default: @@ -124,6 +136,7 @@ const renderModalDialog = props => { extendedProps.deleteModulePermissions = (draftId, userId) => { props.deleteModulePermissions(draftId, userId, extendedOptions) } + extendedProps.syncModuleUpdates = draftId => props.syncModuleUpdates(draftId, extendedOptions) } switch (props.dialog) { @@ -132,6 +145,10 @@ const renderModalDialog = props => { dialog = renderOptionsDialog(props, extendedProps) break + case 'module-sync': + ;(title = 'Module Sync'), (dialog = renderSyncDialog(props, extendedProps)) + break + case 'module-permissions': title = 'Module Access' dialog = renderPermissionsDialog(props, extendedProps) diff --git a/packages/app/obojobo-repository/shared/components/dashboard.test.js b/packages/app/obojobo-repository/shared/components/dashboard.test.js index e70fc015a3..769cefecb8 100644 --- a/packages/app/obojobo-repository/shared/components/dashboard.test.js +++ b/packages/app/obojobo-repository/shared/components/dashboard.test.js @@ -41,6 +41,9 @@ jest.mock('./module-permissions-dialog', () => props => { jest.mock('./module-options-dialog', () => props => { return }) +jest.mock('./module-sync-dialog', () => props => { + return +}) jest.mock('./assessment-score-data-dialog', () => props => { return }) @@ -63,6 +66,7 @@ import CollectionRenameDialog from './collection-rename-dialog' import ModuleManageCollectionsDialog from './module-manage-collections-dialog' import ModulePermissionsDialog from './module-permissions-dialog' import ModuleOptionsDialog from './module-options-dialog' +import ModuleSyncDialog from './module-sync-dialog' import VersionHistoryDialog from './version-history-dialog' import AssessmentScoreDataDialog from './assessment-score-data-dialog' @@ -1624,6 +1628,61 @@ describe('Dashboard', () => { expect(component.root.findAllByProps({ className: isLoadingClass }).length).toBe(0) }) + test('renders "Module Sync" dialog and adjusts callbacks for each mode', () => { + dashboardProps.syncModuleUpdates = jest.fn() + dashboardProps.dialog = 'module-sync' + dashboardProps.mode = MODE_RECENT + let component + act(() => { + component = create() + }) + + expectDialogToBeRendered(component, ModuleSyncDialog, 'Module Sync') + const dialogComponent = component.root.findByType(ModuleSyncDialog) + + // ordinarily the draft ID would be provided inside the dialog + dialogComponent.props.syncModuleUpdates('mockDraftId') + expectMethodToBeCalledOnceWith(dashboardProps.syncModuleUpdates, [ + 'mockDraftId', + { mode: MODE_RECENT } + ]) + + dialogComponent.props.onClose() + expectMethodToBeCalledOnceWith(dashboardProps.closeModal) + + dashboardProps.mode = MODE_ALL + act(() => { + component.update() + }) + + dialogComponent.props.syncModuleUpdates('mockDraftId') + expectMethodToBeCalledOnceWith(dashboardProps.syncModuleUpdates, [ + 'mockDraftId', + { mode: MODE_ALL } + ]) + + dialogComponent.props.onClose() + expectMethodToBeCalledOnceWith(dashboardProps.closeModal) + + dashboardProps.mode = MODE_COLLECTION + dashboardProps.collection = { + id: 'mockCollectionId', + title: 'Mock Collection Title' + } + act(() => { + component.update() + }) + + dialogComponent.props.syncModuleUpdates('mockDraftId') + expectMethodToBeCalledOnceWith(dashboardProps.syncModuleUpdates, [ + 'mockDraftId', + { collectionId: 'mockCollectionId', mode: MODE_COLLECTION } + ]) + + dialogComponent.props.onClose() + expectMethodToBeCalledOnceWith(dashboardProps.closeModal) + }) + test('renders "Module Access" dialog and adjusts callbacks for each mode', () => { dashboardProps.dialog = 'module-permissions' dashboardProps.loadUsersForModule = jest.fn() diff --git a/packages/app/obojobo-repository/shared/components/module-menu-hoc.js b/packages/app/obojobo-repository/shared/components/module-menu-hoc.js index f9a642afcb..e1f15ff9bd 100644 --- a/packages/app/obojobo-repository/shared/components/module-menu-hoc.js +++ b/packages/app/obojobo-repository/shared/components/module-menu-hoc.js @@ -3,9 +3,10 @@ const connect = require('react-redux').connect const { showModulePermissions, deleteModule, - showModuleMore + showModuleMore, + showModuleSync } = require('../actions/dashboard-actions') -const mapActionsToProps = { showModulePermissions, deleteModule, showModuleMore } +const mapActionsToProps = { showModulePermissions, deleteModule, showModuleMore, showModuleSync } module.exports = connect( null, mapActionsToProps diff --git a/packages/app/obojobo-repository/shared/components/module-menu-hoc.test.js b/packages/app/obojobo-repository/shared/components/module-menu-hoc.test.js index 1feae2eaf4..a433b5e98c 100644 --- a/packages/app/obojobo-repository/shared/components/module-menu-hoc.test.js +++ b/packages/app/obojobo-repository/shared/components/module-menu-hoc.test.js @@ -19,7 +19,8 @@ describe('ModuleMenu HOC', () => { expect(ReactRedux.connect).toHaveBeenCalledWith(null, { showModulePermissions: DashboardActions.showModulePermissions, deleteModule: DashboardActions.deleteModule, - showModuleMore: DashboardActions.showModuleMore + showModuleMore: DashboardActions.showModuleMore, + showModuleSync: DashboardActions.showModuleSync }) expect(mockReduxConnectReturn).toHaveBeenCalledTimes(1) diff --git a/packages/app/obojobo-repository/shared/components/module-menu.jsx b/packages/app/obojobo-repository/shared/components/module-menu.jsx index a910cd946c..0f2c1c7beb 100644 --- a/packages/app/obojobo-repository/shared/components/module-menu.jsx +++ b/packages/app/obojobo-repository/shared/components/module-menu.jsx @@ -15,17 +15,25 @@ const ModuleMenu = props => { props.showModuleMore(props) } + const onSyncButtonClick = () => { + props.showModuleSync(props) + } + + // accessLevel should always be set - to be safe, don't show an edit button if it isn't return (
Preview - {props.accessLevel !== MINIMAL && ( + {!props.readOnly && props.accessLevel && props.accessLevel !== MINIMAL && ( Edit )} + {props.readOnly && props.accessLevel && props.accessLevel !== MINIMAL && ( + + )} {props.accessLevel === FULL && }
- {props.accessLevel !== MINIMAL && ( + {!props.readOnly && props.accessLevel !== MINIMAL && (
Edit @@ -79,7 +79,7 @@ const ModuleOptionsDialog = props => (
View scores by student.
- {props.accessLevel !== MINIMAL && ( + {!props.readOnly && props.accessLevel !== MINIMAL && (
+
+ ) + } else if (props.newest === null) { + syncableStatusRender = ( +

No changes found, copy is up-to-date.

+ ) + } + + return ( +
+
+ +
+ {props.title} +
+ +
+
+

Synchronize Updates

+
+ This dialog will indicate if any changes have been made to the module this copy was + created from. +
+ If there have been any changes, you will be given the option to automatically update this + copy to match. +
+ Please note that synchronizing changes may also change this copy's title. +
+
{syncableStatusRender}
+
+
+ ) +} + +module.exports = ModuleSyncDialog diff --git a/packages/app/obojobo-repository/shared/components/module-sync-dialog.scss b/packages/app/obojobo-repository/shared/components/module-sync-dialog.scss new file mode 100644 index 0000000000..d99474450f --- /dev/null +++ b/packages/app/obojobo-repository/shared/components/module-sync-dialog.scss @@ -0,0 +1,94 @@ +@import '../../client/css/defaults'; + +.module-sync-dialog { + min-width: 23em; + + .repository--module-icon--image { + width: 1.5em; + height: 1.75em; + display: block; + } + + .module-title { + display: block; + font-size: 0.625em; + font-weight: bold; + color: black; + margin: 0; + max-width: calc(100% - 8.5em); + word-break: break-word; + } + + .top-bar { + text-align: left; + position: relative; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + box-sizing: border-box; + height: 3em; + + .repository--module-icon--image { + position: absolute; + left: 0.75em; + top: 50%; + transform: translate(0, -50%); + } + + .module-title { + position: absolute; + left: 4.5em; + top: 50%; + transform: translate(0, -50%); + max-height: 1.2em; + } + + .close-button { + position: absolute; + right: 0.5em; + top: 50%; + transform: translate(0, -50%); + } + } + + .wrapper { + padding: 0 1.25em; + + .title { + font-weight: 700; + font-size: 1.3em; + margin-bottom: 0.2em; + text-align: center; + } + + .sub-title { + font-size: 0.7em; + margin-bottom: 0.5em; + text-align: left; + } + + .sync-info-wrapper { + background-color: $color-banner-bg; + margin: 1.25em 0; + padding: 1em; + + .sync-info { + display: flex; + align-items: center; + + .module-title { + flex-grow: 1; + margin-left: 1em; + + .last-update-time { + font-size: 0.65em; + } + } + } + + .sync-info-text-only { + display: block; + width: 100%; + text-align: center; + } + } + } +} diff --git a/packages/app/obojobo-repository/shared/components/module-sync-dialog.test.js b/packages/app/obojobo-repository/shared/components/module-sync-dialog.test.js new file mode 100644 index 0000000000..07b53f70d7 --- /dev/null +++ b/packages/app/obojobo-repository/shared/components/module-sync-dialog.test.js @@ -0,0 +1,91 @@ +import React from 'react' +import { create } from 'react-test-renderer' + +import ModuleSyncDialog from './module-sync-dialog' + +describe('ModuleSyncDialog', () => { + let defaultProps + + beforeEach(() => { + jest.resetAllMocks() + + defaultProps = { + draftId: 'mockDraftId', + title: 'Mock Draft Title', + newest: false + } + }) + + test('ModuleSyncDialog renders with default props', () => { + const component = create() + + // 'Checking for updates' text should appear by default + const syncInfoComponent = component.root.findAllByProps({ className: 'sync-info' }) + expect(syncInfoComponent.length).toBe(0) + + const syncInfoTextOnlyComponent = component.root.findAllByProps({ + className: 'sync-info-text-only' + }) + expect(syncInfoTextOnlyComponent.length).toBe(1) + expect(syncInfoTextOnlyComponent[0].props.children).toBe( + "Checking for updates to this module's original..." + ) + + expect(component.toJSON()).toMatchSnapshot() + }) + + test('ModuleSyncDialog renders with provided newest as null', () => { + defaultProps.newest = null + const component = create() + + // 'No updates' text should appear + const syncInfoComponent = component.root.findAllByProps({ className: 'sync-info' }) + expect(syncInfoComponent.length).toBe(0) + + const syncInfoTextOnlyComponent = component.root.findAllByProps({ + className: 'sync-info-text-only' + }) + expect(syncInfoTextOnlyComponent.length).toBe(1) + expect(syncInfoTextOnlyComponent[0].props.children).toBe( + 'No changes found, copy is up-to-date.' + ) + + expect(component.toJSON()).toMatchSnapshot() + }) + + test('ModuleSyncDialog renders with provided newest module', () => { + defaultProps.newest = { + draftId: 'mockOriginalDraftId', + title: 'Original Mock Draft Title', + updatedAt: '1999/01/01 01:01' + } + const component = create() + + // text-only fields should not appear + const syncInfoTextOnlyComponent = component.root.findAllByProps({ + className: 'sync-info-text-only' + }) + expect(syncInfoTextOnlyComponent.length).toBe(0) + + // updated module info should appear + const syncInfoComponent = component.root.findAllByProps({ className: 'sync-info' }) + expect(syncInfoComponent.length).toBe(1) + + expect(component.toJSON()).toMatchSnapshot() + }) + + test('Synchronize button onClick calls syncModuleUpdates', () => { + defaultProps.syncModuleUpdates = jest.fn() + defaultProps.newest = { + draftId: 'mockOriginalDraftId', + title: 'Original Mock Draft Title', + updatedAt: '1999/01/01 01:01' + } + const component = create() + + const syncButton = component.root.findByProps({ className: 'sync-button' }) + syncButton.props.onClick() + + expect(defaultProps.syncModuleUpdates).toHaveBeenCalledWith('mockDraftId') + }) +}) diff --git a/packages/app/obojobo-repository/shared/components/module.jsx b/packages/app/obojobo-repository/shared/components/module.jsx index 497e205b2d..7dfe8a8876 100644 --- a/packages/app/obojobo-repository/shared/components/module.jsx +++ b/packages/app/obojobo-repository/shared/components/module.jsx @@ -72,6 +72,7 @@ const Module = props => { editor={props.editor} title={props.title} accessLevel={props.accessLevel} + readOnly={props.readOnly} /> ) : null} {props.children} diff --git a/packages/app/obojobo-repository/shared/components/pages/__snapshots__/page-module.test.js.snap b/packages/app/obojobo-repository/shared/components/pages/__snapshots__/page-module.test.js.snap index 16da8fad6c..1f4ec5ed33 100644 --- a/packages/app/obojobo-repository/shared/components/pages/__snapshots__/page-module.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/pages/__snapshots__/page-module.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`PageModule renders when given props 1`] = ` +exports[`PageModule renders when given props - current user can copy and preview 1`] = `
+ + Click the "Preview this module" button below to view the module as a learner would! + + + Click one of the buttons below to create a copy of this module (or to cancel the copy process). + + + Note: A read-only copy will not be editable, and can be synchronized with the original from the dashboard. + Preview this module - +
+
+ Module created by + + + firstName + + lastName + + + on + + Jan 1, 1970 + + and updated + + A long time ago + . +
+

+ Use this Module in your Canvas Course +

+

+ This module can be used inside your course as an + + assignment + + or + + module + + . +

+
+ Animated gif showing how to create an Obojobo Assignment in canvas +
+ Creating an Assignment in Canvas +
+
+

+ Create an Assignment in Canvas +

+
    +
  1. + Click Assignments in your course's menu. +
  2. +
  3. + Create a new Assignment +
  4. +
  5. + Set the: +
      +
    • + Assignment Name +
    • +
    • + Points (do not use 0) +
    • +
    • + any other relevant settings +
    • +
    +
  6. +
  7. + Set Submission Type to "External Tool" +
  8. +
  9. + Follow the + + Choosing a Obojobo Module + + instructions below +
  10. +
  11. + Click Select +
  12. +
  13. + Save & Publish +
  14. +
+

+ Create an Ungraded Module in Canvas +

+
    +
  1. + Click Modules in your course's menu. +
  2. +
  3. + Click the "+" in a module +
  4. +
  5. + Type an Assignment Name +
  6. +
  7. + Change the top drop down from "Assignment" to "External Tool". +
  8. +
  9. + Follow the + + Choosing a Obojobo Module + + instructions below +
  10. +
  11. + Click Add Item +
  12. +
  13. + You new module will be named " + mockDraftTitle + (doesn't send scores to grade book)" +
  14. +
  15. + Be sure to + + Publish + + within Canvas when ready +
  16. +
+

+ Choosing a Obojobo Module +

+
    +
  1. + Follow one of the sets of instructions above. +
  2. +
  3. + Click "FIND" next to the input labeled "Enter or find an External Tool URL" +
  4. +
  5. + In the popup that appears, scroll down and select "ObojoboNext Module (gradebook synced)" +
  6. +
  7. + Choose Community Collection +
  8. +
  9. + Search for the module by its title ( + + mockDraftTitle + + ) or its id ( + + mockDraftId + + ) +
  10. +
  11. + Click Embed next to your chosen module +
  12. +
+ +
+`; + +exports[`PageModule renders when given props - current user can not copy or preview 1`] = ` +
+
+ +
+
+
+
+
+ +
+

+ mockDraftTitle +

+
+
+
Module created by diff --git a/packages/app/obojobo-repository/shared/components/pages/page-library.scss b/packages/app/obojobo-repository/shared/components/pages/page-library.scss index a6837178ce..c57baf9011 100644 --- a/packages/app/obojobo-repository/shared/components/pages/page-library.scss +++ b/packages/app/obojobo-repository/shared/components/pages/page-library.scss @@ -1,5 +1,6 @@ /* stylelint-disable */ @import '../../../client/css/defaults'; +@import './page-module.scss'; // reduce a larger font-size set on an ancestor in the library page .repository--nav--links--search { @@ -12,8 +13,3 @@ color: $color-text-placeholder; text-align: center; } - -.copy-button { - display: inline-block; - margin: 0.5em; -} diff --git a/packages/app/obojobo-repository/shared/components/pages/page-module.jsx b/packages/app/obojobo-repository/shared/components/pages/page-module.jsx index 1079b656e3..e78d43cc1b 100644 --- a/packages/app/obojobo-repository/shared/components/pages/page-module.jsx +++ b/packages/app/obojobo-repository/shared/components/pages/page-module.jsx @@ -1,6 +1,7 @@ require('./page-module.scss') const React = require('react') +const { useState } = require('react') const RepositoryNav = require('../repository-nav') const RepositoryBanner = require('../repository-banner') const ModuleImage = require('../module-image') @@ -12,116 +13,197 @@ const relativeTime = require('dayjs/plugin/relativeTime') dayjs.extend(relativeTime) -const PageModule = props => ( -
- - - - - - -
+const PageModule = props => { + const [copyOptionsVisible, setCopyOptionsVisible] = useState(false) + + const copyModule = readOnly => { + APIUtil.copyModule(props.module.draftId, readOnly) + setCopyOptionsVisible(false) + } + + let expositionRender = [] + + let previewButtonRender = null + if (props.canPreview) { + previewButtonRender = ( Preview this module + ) + expositionRender.push( + 'Click the "Preview this module" button below to view the module as a learner would!' + ) + } + + let copyButtonRender = null + if (props.canCopy) { + if (copyOptionsVisible) { + copyButtonRender = ( +
+ + + +
+ ) + } else { + copyButtonRender = ( +
+ +
+ ) + } + expositionRender.push( + 'Click one of the buttons below to create a copy of this module (or to cancel the copy process).' + ) + expositionRender.push( + 'Note: A read-only copy will not be editable, and can be synchronized with the original from the dashboard.' + ) + } + + if (expositionRender.length) { + expositionRender = expositionRender.map((string, index) => ( + + {string} + + )) + } + + return ( +
+ + + + + + +
+ {expositionRender} + {previewButtonRender} + {copyButtonRender} + +
+ Module created by{' '} + + {props.owner.firstName} {props.owner.lastName} + {' '} + on {dayjs(props.module.createdAt).format('MMM D, YYYY')} and updated{' '} + {dayjs(props.module.updatedAt).fromNow()}. +
+ +

Use this Module in your Canvas Course

+

+ This module can be used inside your course as an assignment or module. +

+ +
+ Animated gif showing how to create an Obojobo Assignment in canvas +
Creating an Assignment in Canvas
+
+ +

Create an Assignment in Canvas

+
    +
  1. Click Assignments in your course's menu.
  2. +
  3. Create a new Assignment
  4. +
  5. + Set the: +
      +
    • Assignment Name
    • +
    • Points (do not use 0)
    • +
    • any other relevant settings
    • +
    +
  6. +
  7. Set Submission Type to "External Tool"
  8. +
  9. + Follow the Choosing a Obojobo Module instructions + below +
  10. +
  11. Click Select
  12. +
  13. Save & Publish
  14. +
+ +

Create an Ungraded Module in Canvas

+
    +
  1. Click Modules in your course's menu.
  2. +
  3. Click the "+" in a module
  4. +
  5. Type an Assignment Name
  6. +
  7. + Change the top drop down from "Assignment" to "External Tool". +
  8. +
  9. + Follow the Choosing a Obojobo Module instructions + below +
  10. +
  11. Click Add Item
  12. +
  13. + You new module will be named "{props.module.title} (doesn't send scores to + grade book)" +
  14. +
  15. + Be sure to Publish within Canvas when ready +
  16. +
- - -
- Module created by{' '} - - {props.owner.firstName} {props.owner.lastName} - {' '} - on {dayjs(props.module.createdAt).format('MMM D, YYYY')} and updated{' '} - {dayjs(props.module.updatedAt).fromNow()}. -
- -

Use this Module in your Canvas Course

-

- This module can be used inside your course as an assignment or module. -

- -
- Animated gif showing how to create an Obojobo Assignment in canvas -
Creating an Assignment in Canvas
-
- -

Create an Assignment in Canvas

-
    -
  1. Click Assignments in your course's menu.
  2. -
  3. Create a new Assignment
  4. -
  5. - Set the: -
      -
    • Assignment Name
    • -
    • Points (do not use 0)
    • -
    • any other relevant settings
    • -
    -
  6. -
  7. Set Submission Type to "External Tool"
  8. -
  9. - Follow the Choosing a Obojobo Module instructions - below -
  10. -
  11. Click Select
  12. -
  13. Save & Publish
  14. -
- -

Create an Ungraded Module in Canvas

-
    -
  1. Click Modules in your course's menu.
  2. -
  3. Click the "+" in a module
  4. -
  5. Type an Assignment Name
  6. -
  7. Change the top drop down from "Assignment" to "External Tool".
  8. -
  9. - Follow the Choosing a Obojobo Module instructions - below -
  10. -
  11. Click Add Item
  12. -
  13. - You new module will be named "{props.module.title} (doesn't send scores to grade - book)" -
  14. -
  15. - Be sure to Publish within Canvas when ready -
  16. -
- -

Choosing a Obojobo Module

-
    -
  1. Follow one of the sets of instructions above.
  2. -
  3. - Click "FIND" next to the input labeled "Enter or find an External Tool - URL" -
  4. -
  5. - In the popup that appears, scroll down and select "ObojoboNext Module (gradebook - synced)" -
  6. -
  7. Choose Community Collection
  8. -
  9. - Search for the module by its title ({props.module.title}) or its id ( - {props.module.draftId}) -
  10. -
  11. Click Embed next to your chosen module
  12. -
-
-
-) +

Choosing a Obojobo Module

+
    +
  1. Follow one of the sets of instructions above.
  2. +
  3. + Click "FIND" next to the input labeled "Enter or find an External Tool + URL" +
  4. +
  5. + In the popup that appears, scroll down and select "ObojoboNext Module (gradebook + synced)" +
  6. +
  7. Choose Community Collection
  8. +
  9. + Search for the module by its title ({props.module.title}) or its id ( + {props.module.draftId}) +
  10. +
  11. Click Embed next to your chosen module
  12. +
+
+
+ ) +} module.exports = PageModule diff --git a/packages/app/obojobo-repository/shared/components/pages/page-module.scss b/packages/app/obojobo-repository/shared/components/pages/page-module.scss index c6390c805a..3e4cc028f9 100644 --- a/packages/app/obojobo-repository/shared/components/pages/page-module.scss +++ b/packages/app/obojobo-repository/shared/components/pages/page-module.scss @@ -1,7 +1,17 @@ @import '../layouts/default.scss'; @import '../layouts/footer.scss'; -.copy-button { +.exposition-text { + display: block; + font-size: 0.8em; +} + +.copy-button-container { display: inline-block; - margin: 0.5em; + margin: 0 0.5em; + + .copy-button { + display: inline-block; + margin: 0 0.5em; + } } diff --git a/packages/app/obojobo-repository/shared/components/pages/page-module.test.js b/packages/app/obojobo-repository/shared/components/pages/page-module.test.js index 6e3b1ed2de..57c61106f5 100644 --- a/packages/app/obojobo-repository/shared/components/pages/page-module.test.js +++ b/packages/app/obojobo-repository/shared/components/pages/page-module.test.js @@ -3,10 +3,10 @@ jest.mock('dayjs') import React from 'react' import PageModule from './page-module' -import renderer from 'react-test-renderer' -import { shallow } from 'enzyme' +import { create, act } from 'react-test-renderer' const Button = require('../button') +const ButtonLink = require('../button-link') const APIUtil = require('../../api-util') const dayjs = require('dayjs') @@ -26,6 +26,8 @@ describe('PageModule', () => { }) beforeEach(() => { + jest.clearAllMocks() + mockCurrentUser = { id: 99, avatarUrl: '/path/to/avatar/img', @@ -42,28 +44,189 @@ describe('PageModule', () => { } }) - test('renders when given props', () => { - const component = renderer.create( - + test('renders when given props - current user can copy and preview', () => { + const component = create( + ) + + const previewButton = component.root.findAllByType(ButtonLink) + expect(previewButton.length).toBe(1) + + const copyButtonArea = component.root.findAllByProps({ className: 'copy-button-container' }) + expect(copyButtonArea.length).toBe(1) + + // should only have one button in it + const copyButtons = copyButtonArea[0].findAllByType(Button) + expect(copyButtons.length).toBe(1) + expect(copyButtons[0].props.children).toBe('Copy this module') + const tree = component.toJSON() expect(tree).toMatchSnapshot() }) - test('reacts properly when the copy button is clicked', () => { - const component = shallow( + test('renders when given props - current user can not copy or preview', () => { + const component = create( ) - component.find(Button).simulate('click') + const previewButton = component.root.findAllByType(ButtonLink) + expect(previewButton.length).toBe(0) + + const copyButtonArea = component.root.findAllByProps({ className: 'copy-button-container' }) + expect(copyButtonArea.length).toBe(0) + + const tree = component.toJSON() + expect(tree).toMatchSnapshot() + }) + + test('Shows copy options when the initial copy button is clicked', () => { + let component + act(() => { + component = create( + + ) + }) + + const copyButtonArea = component.root.findByProps({ className: 'copy-button-container' }) + + // should only have one button in it + let copyButtons = copyButtonArea.findAllByType(Button) + expect(copyButtons.length).toBe(1) + expect(copyButtons[0].props.children).toBe('Copy this module') + + act(() => { + copyButtons[0].props.onClick() + }) + + // single button should be replaced with three buttons + copyButtons = copyButtonArea.findAllByType(Button) + expect(copyButtons.length).toBe(3) + + expect(copyButtons[0].props.children).toBe('Normal Copy') + expect(copyButtons[1].props.children).toBe('Read-Only Copy') + expect(copyButtons[2].props.children).toBe('Cancel') + }) + + test('Runs correct functions when the "Normal Copy" button is clicked', () => { + let component + act(() => { + component = create( + + ) + }) + + const copyButtonArea = component.root.findByProps({ className: 'copy-button-container' }) + let copyButtons = copyButtonArea.findAllByType(Button) + + act(() => { + copyButtons[0].props.onClick() + }) + + copyButtons = copyButtonArea.findAllByType(Button) + + act(() => { + copyButtons[0].props.onClick() + }) expect(APIUtil.copyModule).toHaveBeenCalledTimes(1) - expect(APIUtil.copyModule).toHaveBeenCalledWith('mockDraftId') + expect(APIUtil.copyModule).toHaveBeenCalledWith('mockDraftId', false) + }) + + test('Runs correct functions when the "Read-Only Copy" button is clicked', () => { + let component + act(() => { + component = create( + + ) + }) + + const copyButtonArea = component.root.findByProps({ className: 'copy-button-container' }) + let copyButtons = copyButtonArea.findAllByType(Button) + + act(() => { + copyButtons[0].props.onClick() + }) + + copyButtons = copyButtonArea.findAllByType(Button) + + act(() => { + copyButtons[1].props.onClick() + }) + + expect(APIUtil.copyModule).toHaveBeenCalledTimes(1) + expect(APIUtil.copyModule).toHaveBeenCalledWith('mockDraftId', true) + }) + + test('Runs correct functions when the "Cancel" button is clicked', () => { + let component + act(() => { + component = create( + + ) + }) + + const copyButtonArea = component.root.findByProps({ className: 'copy-button-container' }) + + // should only have one button in it + let copyButtons = copyButtonArea.findAllByType(Button) + expect(copyButtons.length).toBe(1) + expect(copyButtons[0].props.children).toBe('Copy this module') + + act(() => { + copyButtons[0].props.onClick() + }) + + // single button should be replaced with three buttons + copyButtons = copyButtonArea.findAllByType(Button) + expect(copyButtons.length).toBe(3) + + expect(copyButtons[0].props.children).toBe('Normal Copy') + expect(copyButtons[1].props.children).toBe('Read-Only Copy') + expect(copyButtons[2].props.children).toBe('Cancel') + + act(() => { + copyButtons[2].props.onClick() + }) + + copyButtons = copyButtonArea.findAllByType(Button) + expect(copyButtons.length).toBe(1) + expect(copyButtons[0].props.children).toBe('Copy this module') }) }) diff --git a/packages/app/obojobo-repository/shared/reducers/dashboard-reducer.js b/packages/app/obojobo-repository/shared/reducers/dashboard-reducer.js index de69ff682e..1ddd6c1c15 100644 --- a/packages/app/obojobo-repository/shared/reducers/dashboard-reducer.js +++ b/packages/app/obojobo-repository/shared/reducers/dashboard-reducer.js @@ -18,6 +18,8 @@ const { SELECT_MODULES, DESELECT_MODULES, SHOW_MODULE_MORE, + SHOW_MODULE_SYNC, + SYNC_MODULE_UPDATES, CREATE_NEW_COLLECTION, SHOW_MODULE_MANAGE_COLLECTIONS, LOAD_MODULE_COLLECTIONS, @@ -114,9 +116,10 @@ function DashboardReducer(state, action) { }) }) + case SYNC_MODULE_UPDATES: case DELETE_MODULE: return handle(state, action, { - // close the dialog containing the delete button + // close the dialog start: () => ({ ...state, ...closedDialogState() }), // update myModules and re-apply the filter if one exists success: prevState => { @@ -180,6 +183,24 @@ function DashboardReducer(state, action) { selectedModule: action.module } + case SHOW_MODULE_SYNC: + return handle(state, action, { + // open the dialog while the fetch is in progress + start: () => ({ + ...state, + dialog: 'module-sync', + selectedModule: action.meta.module, + newest: false + }), + // update myModules and re-apply the filter if one exists + success: prevState => { + return { + ...prevState, + newest: action.payload.value + } + } + }) + case SHOW_MODULE_PERMISSIONS: return { ...state, diff --git a/packages/app/obojobo-repository/shared/reducers/dashboard-reducer.test.js b/packages/app/obojobo-repository/shared/reducers/dashboard-reducer.test.js index 2da368adaf..eb4a636c35 100644 --- a/packages/app/obojobo-repository/shared/reducers/dashboard-reducer.test.js +++ b/packages/app/obojobo-repository/shared/reducers/dashboard-reducer.test.js @@ -25,6 +25,8 @@ const { SELECT_MODULES, DESELECT_MODULES, SHOW_MODULE_MORE, + SHOW_MODULE_SYNC, + SYNC_MODULE_UPDATES, CREATE_NEW_COLLECTION, SHOW_MODULE_MANAGE_COLLECTIONS, LOAD_MODULE_COLLECTIONS, @@ -181,8 +183,9 @@ describe('Dashboard Reducer', () => { expect(newState.collection.title).toEqual(expectedCollectionTitle) } - const runCreateOrDeleteModuleActionTest = testAction => { - const isDeleteModuleTest = testAction === DELETE_MODULE + const runCreateOrSyncUpdatesOrDeleteModuleActionTest = testAction => { + const isSyncOrDeleteModuleTest = + testAction === DELETE_MODULE || testAction === SYNC_MODULE_UPDATES const mockModuleList = [ { draftId: 'mockDraftId', @@ -196,7 +199,7 @@ describe('Dashboard Reducer', () => { const initialState = { dialog: 'module-options', - moduleSearchString: isDeleteModuleTest ? 'B' : '', + moduleSearchString: isSyncOrDeleteModuleTest ? 'B' : '', myModules: [ { draftId: 'oldMockDraftId', @@ -226,7 +229,7 @@ describe('Dashboard Reducer', () => { // DELETE_MODULE changes state on start AND success, CREATE_MODULE just on success let newState - if (isDeleteModuleTest) { + if (isSyncOrDeleteModuleTest) { newState = handleStart(handler) expect(newState.dialog).toBe(null) // no module list changes should have happened yet @@ -237,7 +240,7 @@ describe('Dashboard Reducer', () => { newState = handleSuccess(handler) expect(newState.myModules).not.toEqual(initialState.myModules) expect(newState.myModules).toEqual(mockModuleList) - if (isDeleteModuleTest) { + if (isSyncOrDeleteModuleTest) { expect(newState.filteredModules).not.toEqual(initialState.filteredModules) expect(newState.moduleSearchString).toEqual(initialState.moduleSearchString) expect(newState.filteredModules).toEqual([{ ...mockModuleList[1] }]) @@ -436,12 +439,16 @@ describe('Dashboard Reducer', () => { }) test('CREATE_NEW_MODULE action modifies state correctly', () => { - runCreateOrDeleteModuleActionTest(CREATE_NEW_MODULE) + runCreateOrSyncUpdatesOrDeleteModuleActionTest(CREATE_NEW_MODULE) }) //DELETE_MODULE is more or less the same as CREATE_MODULE, but will auto-filter new modules test('DELETE_MODULE action modifies state correctly', () => { - runCreateOrDeleteModuleActionTest(DELETE_MODULE) + runCreateOrSyncUpdatesOrDeleteModuleActionTest(DELETE_MODULE) + }) + //SYNC_MODULE_UPDATES should be identical to DELETE_MODULE + test('SYNC_MODULE_UPDATE action modifies state correctly', () => { + runCreateOrSyncUpdatesOrDeleteModuleActionTest(SYNC_MODULE_UPDATES) }) test('BULK_DELETE_MODULES action modifies state correctly', () => { @@ -586,6 +593,43 @@ describe('Dashboard Reducer', () => { expect(newState.selectedModule).toEqual(mockSelectedModule) }) + test('SHOW_MODULE_SYNC action modifies state correctly', () => { + const initialState = { + dialog: null, + selectedModule: { + draftId: 'someMockDraftId', + title: 'Some Mock Module Title' + } + } + + const mockModule = { + draftId: 'originalMockDraftId', + title: 'Some New Mock Module Title' + } + const action = { + type: SHOW_MODULE_SYNC, + meta: { + module: { + draftId: 'originalMockDraftId', + title: 'Some New Mock Module Title' + } + }, + payload: { + value: mockModule + } + } + + // asynchronous action - state changes on success + const handler = dashboardReducer(initialState, action) + let newState + + newState = handleStart(handler) + expect(newState.newest).toEqual(false) + + newState = handleSuccess(handler) + expect(newState.newest).toEqual(mockModule) + }) + test('SHOW_MODULE_PERMISSIONS action modifies state correctly', () => { const initialState = { dialog: null, From 49ca2667142e92b4a2646583863c0b5df51b54f7 Mon Sep 17 00:00:00 2001 From: Brandon Stull Date: Thu, 27 Apr 2023 09:42:39 -0400 Subject: [PATCH 15/25] #2005 Added a 'Synchronize' button to the expanded module options menu. --- .../module-options-dialog.test.js.snap | 368 +++++++++++++++++- .../shared/components/dashboard-hoc.js | 2 + .../shared/components/dashboard-hoc.test.js | 1 + .../shared/components/dashboard.jsx | 1 + .../components/module-options-dialog.jsx | 13 + .../components/module-options-dialog.test.js | 112 +++++- 6 files changed, 493 insertions(+), 4 deletions(-) diff --git a/packages/app/obojobo-repository/shared/components/__snapshots__/module-options-dialog.test.js.snap b/packages/app/obojobo-repository/shared/components/__snapshots__/module-options-dialog.test.js.snap index a907aa7bba..e22d35b434 100644 --- a/packages/app/obojobo-repository/shared/components/__snapshots__/module-options-dialog.test.js.snap +++ b/packages/app/obojobo-repository/shared/components/__snapshots__/module-options-dialog.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`ModuleOptionsDialog renders correctly with Full access level 1`] = ` +exports[`ModuleOptionsDialog renders correctly with Full access level - not read-only 1`] = `
@@ -216,6 +216,204 @@ exports[`ModuleOptionsDialog renders correctly with Full access level 1`] = `
`; +exports[`ModuleOptionsDialog renders correctly with Full access level - read-only 1`] = ` +
+
+
+ +
+
+ Mock Module Title +
+ +
+
+

+ Module Options +

+

+ Your Access Level: + Full +

+
+
+ + Preview + +
+ View with preview controls. +
+
+
+ +
+ Update this module with changes to the original. +
+
+
+ +
+ Add or remove collaborators. +
+
+
+ +
+ View scores by student. +
+
+
+ +
+ Add to or remove from private collections. +
+
+
+ +
+ Download a copy in JSON format. +
+
+
+ +
+ Download a copy in XML format. +
+
+
+ + Public Page + +
+ Visit this modules public page. +
+
+
+ +
+ Say farewell. +
+
+
+ +
+
+`; + exports[`ModuleOptionsDialog renders correctly with Minimal access level 1`] = `
`; -exports[`ModuleOptionsDialog renders correctly with Partial access level 1`] = ` +exports[`ModuleOptionsDialog renders correctly with Partial access level - not read-only 1`] = `
@@ -519,6 +717,172 @@ exports[`ModuleOptionsDialog renders correctly with Partial access level 1`] = `
`; +exports[`ModuleOptionsDialog renders correctly with Partial access level - read-only 1`] = ` +
+
+
+ +
+
+ Mock Module Title +
+ +
+
+

+ Module Options +

+

+ Your Access Level: + Partial +

+
+
+ + Preview + +
+ View with preview controls. +
+
+
+ +
+ Update this module with changes to the original. +
+
+
+ +
+ View scores by student. +
+
+
+ +
+ Add to or remove from private collections. +
+
+
+ +
+ Download a copy in JSON format. +
+
+
+ +
+ Download a copy in XML format. +
+
+
+ + Public Page + +
+ Visit this modules public page. +
+
+
+ +
+
+`; + exports[`ModuleOptionsDialog renders correctly with standard expected props 1`] = `
state @@ -77,6 +78,7 @@ const mapActionsToProps = { getDeletedModules, getModules, bulkRestoreModules, + showModuleSync, syncModuleUpdates } module.exports = connect( diff --git a/packages/app/obojobo-repository/shared/components/dashboard-hoc.test.js b/packages/app/obojobo-repository/shared/components/dashboard-hoc.test.js index 3365f99698..8a62b0d132 100644 --- a/packages/app/obojobo-repository/shared/components/dashboard-hoc.test.js +++ b/packages/app/obojobo-repository/shared/components/dashboard-hoc.test.js @@ -60,6 +60,7 @@ describe('Dashboard HOC', () => { changeAccessLevel: DashboardActions.changeAccessLevel, getDeletedModules: DashboardActions.getDeletedModules, getModules: DashboardActions.getModules, + showModuleSync: DashboardActions.showModuleSync, syncModuleUpdates: DashboardActions.syncModuleUpdates }) diff --git a/packages/app/obojobo-repository/shared/components/dashboard.jsx b/packages/app/obojobo-repository/shared/components/dashboard.jsx index acfd4c58df..8613fb507e 100644 --- a/packages/app/obojobo-repository/shared/components/dashboard.jsx +++ b/packages/app/obojobo-repository/shared/components/dashboard.jsx @@ -40,6 +40,7 @@ const renderOptionsDialog = (props, extension) => ( startLoadingAnimation={props.startLoadingAnimation} stopLoadingAnimation={props.stopLoadingAnimation} showModuleManageCollections={props.showModuleManageCollections} + showModuleSync={props.showModuleSync} /> ) diff --git a/packages/app/obojobo-repository/shared/components/module-options-dialog.jsx b/packages/app/obojobo-repository/shared/components/module-options-dialog.jsx index e67851ab7a..a46f5ce9a3 100644 --- a/packages/app/obojobo-repository/shared/components/module-options-dialog.jsx +++ b/packages/app/obojobo-repository/shared/components/module-options-dialog.jsx @@ -51,6 +51,19 @@ const ModuleOptionsDialog = props => (
Write, edit, and update.
)} + {props.readOnly && props.accessLevel !== MINIMAL && ( +
+ +
Update this module with changes to the original.
+
+ )} {props.accessLevel === FULL && (
diff --git a/packages/app/obojobo-repository/shared/components/module-options-dialog.test.js b/packages/app/obojobo-repository/shared/components/module-options-dialog.test.js index c90f109d65..b7ea5dccdf 100644 --- a/packages/app/obojobo-repository/shared/components/module-options-dialog.test.js +++ b/packages/app/obojobo-repository/shared/components/module-options-dialog.test.js @@ -48,30 +48,127 @@ describe('ModuleOptionsDialog', () => { const component = create() + // should only be showing the preview, assessment stats, manage collections and public page buttons + const expectedButtons = ['Preview', 'Assessment Stats', 'Manage Collections', 'Public Page'] + const allButtons = component.root.findAllByProps({ className: 'button-label-group' }) + expect(allButtons.length).toEqual(expectedButtons.length) + allButtons.forEach((b, i) => { + expect(b.children[0].props.children).toEqual(expectedButtons[i]) + }) + expect(mockRepositoryUtils.urlForEditor).not.toHaveBeenCalled() expect(component.toJSON()).toMatchSnapshot() }) - test('renders correctly with Partial access level', () => { + test('renders correctly with Partial access level - not read-only', () => { defaultProps.accessLevel = PARTIAL const component = create() + // should be showing minimal access buttons plus edit and download json/xml buttons + const expectedButtons = [ + 'Preview', + 'Edit', + 'Assessment Stats', + 'Version History', + 'Manage Collections', + 'Download JSON', + 'Download XML', + 'Public Page' + ] + const allButtons = component.root.findAllByProps({ className: 'button-label-group' }) + expect(allButtons.length).toEqual(expectedButtons.length) + allButtons.forEach((b, i) => { + expect(b.children[0].props.children).toEqual(expectedButtons[i]) + }) + expect(mockRepositoryUtils.urlForEditor).toHaveBeenCalledTimes(1) expect(mockRepositoryUtils.urlForEditor).toHaveBeenCalledWith('mockEditorType', 'mockDraftId') expect(component.toJSON()).toMatchSnapshot() }) + test('renders correctly with Partial access level - read-only', () => { + defaultProps.accessLevel = PARTIAL + defaultProps.readOnly = true + const component = create() + + // should be showing minimal access buttons plus synchronize and download json/xml buttons + // but no version history because read-only + const expectedButtons = [ + 'Preview', + 'Synchronize', + 'Assessment Stats', + 'Manage Collections', + 'Download JSON', + 'Download XML', + 'Public Page' + ] + const allButtons = component.root.findAllByProps({ className: 'button-label-group' }) + expect(allButtons.length).toEqual(expectedButtons.length) + allButtons.forEach((b, i) => { + expect(b.children[0].props.children).toEqual(expectedButtons[i]) + }) + + expect(mockRepositoryUtils.urlForEditor).not.toHaveBeenCalled() + + expect(component.toJSON()).toMatchSnapshot() + }) - test('renders correctly with Full access level', () => { + test('renders correctly with Full access level - not read-only', () => { const component = create() + // should be showing partial access buttons plus share and delete buttons + const expectedButtons = [ + 'Preview', + 'Edit', + 'Share', + 'Assessment Stats', + 'Version History', + 'Manage Collections', + 'Download JSON', + 'Download XML', + 'Public Page', + 'Delete' + ] + const allButtons = component.root.findAllByProps({ className: 'button-label-group' }) + // expect(allButtons.length).toEqual(expectedButtons.length) + allButtons.forEach((b, i) => { + expect(b.children[0].props.children).toEqual(expectedButtons[i]) + }) + expect(mockRepositoryUtils.urlForEditor).toHaveBeenCalledTimes(1) expect(mockRepositoryUtils.urlForEditor).toHaveBeenCalledWith('mockEditorType', 'mockDraftId') expect(component.toJSON()).toMatchSnapshot() }) + test('renders correctly with Full access level - read-only', () => { + defaultProps.readOnly = true + const component = create() + + // should be showing partial access buttons plus share and delete buttons + const expectedButtons = [ + 'Preview', + 'Synchronize', + 'Share', + 'Assessment Stats', + 'Manage Collections', + 'Download JSON', + 'Download XML', + 'Public Page', + 'Delete' + ] + const allButtons = component.root.findAllByProps({ className: 'button-label-group' }) + // expect(allButtons.length).toEqual(expectedButtons.length) + allButtons.forEach((b, i) => { + expect(b.children[0].props.children).toEqual(expectedButtons[i]) + // console.log(b.children[0].props.children) + }) + + expect(mockRepositoryUtils.urlForEditor).not.toHaveBeenCalled() + + expect(component.toJSON()).toMatchSnapshot() + }) test('"Share" button calls showModulePermissions', () => { defaultProps.showModulePermissions = jest.fn() @@ -172,4 +269,15 @@ describe('ModuleOptionsDialog', () => { expect(defaultProps.deleteModule).toHaveBeenCalledTimes(1) expect(defaultProps.deleteModule).toHaveBeenCalledWith('mockDraftId') }) + + test('"Synchronize" button brings up synchronize dialog', () => { + defaultProps.readOnly = true + defaultProps.showModuleSync = jest.fn(() => Promise.resolve()) + const component = create() + + component.root.findByProps({ id: 'moduleOptionsDialog-synchronizeButton' }).props.onClick() + + expect(defaultProps.showModuleSync).toHaveBeenCalledTimes(1) + expect(defaultProps.showModuleSync).toHaveBeenCalledWith(defaultProps) + }) }) From 35e8e233776901f342c67d5602281bacf93f5672 Mon Sep 17 00:00:00 2001 From: Brandon Stull Date: Tue, 23 May 2023 16:21:12 -0400 Subject: [PATCH 16/25] #2081 When copying a module, all node IDs that match the UUID pattern are replaced with new UUIDs. References to the old node IDs in button actions etc. are also replaced with the corresponding new IDs. --- .../obojobo-repository/server/routes/api.js | 33 ++++++- .../server/routes/api.test.js | 98 +++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) diff --git a/packages/app/obojobo-repository/server/routes/api.js b/packages/app/obojobo-repository/server/routes/api.js index f6f55da1e6..aa6f65836d 100644 --- a/packages/app/obojobo-repository/server/routes/api.js +++ b/packages/app/obojobo-repository/server/routes/api.js @@ -24,6 +24,8 @@ const publicLibCollectionId = require('../../shared/publicLibCollectionId') const { levelName, levelNumber, FULL } = require('../../../obojobo-express/server/constants') +const uuid = require('uuid').v4 + // List public drafts router.route('/drafts-public').get((req, res) => { return Collection.fetchById(publicLibCollectionId) @@ -186,10 +188,39 @@ router } const oldDraft = await Draft.fetchById(draftId) + + // gather all of the node IDs in the document and determine a new ID to replace each with + const idsForChange = {} + + // this should never not exist, but just in case + if (oldDraft.nodesById) { + // only generate a replacement for ids that are UUIDs, not custom + const uuidRegex = /[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i + oldDraft.nodesById.forEach((node, key) => { + if (key && uuidRegex.test(key)) idsForChange[key] = uuid() + }) + } + + // now convert the updated document to an object for use const draftObject = oldDraft.root.toObject() + const newTitle = req.body.title ? req.body.title : draftObject.content.title + ' Copy' draftObject.content.title = newTitle - const newDraft = await Draft.createWithContent(userId, draftObject) + + // convert the object to a JSON string so we can swap out all the old IDs with the new ones + let draftString = JSON.stringify(draftObject) + + // globally replace each old ID with the equivalent new ID + // this should replace node IDs as well as action trigger references to those node IDs + for (const [oldId, newId] of Object.entries(idsForChange)) { + // this works, but there may be a more efficient way of doing it + draftString = draftString.replace(new RegExp(oldId, 'g'), newId) + } + + const newDraftObject = JSON.parse(draftString) + + // const newDraft = await Draft.createWithContent(userId, draftObject) + const newDraft = await Draft.createWithContent(userId, newDraftObject) const draftMetadata = new DraftsMetadata({ draft_id: newDraft.id, diff --git a/packages/app/obojobo-repository/server/routes/api.test.js b/packages/app/obojobo-repository/server/routes/api.test.js index db541d935e..7c5abfcd3a 100644 --- a/packages/app/obojobo-repository/server/routes/api.test.js +++ b/packages/app/obojobo-repository/server/routes/api.test.js @@ -13,6 +13,10 @@ jest.mock('obojobo-express/server/insert_event') jest.unmock('fs') // need fs working for view rendering jest.unmock('express') // we'll use supertest + express for this +jest.mock('uuid', () => ({ + v4: jest.fn() +})) + let CollectionSummary let Collection let DraftSummary @@ -59,6 +63,8 @@ const express = require('express') const bodyParser = require('body-parser') const app = express() +const uuid = require('uuid').v4 + // register express-react-views template engine if not already registered app.engine('jsx', require('express-react-views-custom').createEngine()) @@ -589,6 +595,98 @@ describe('repository api route', () => { }) }) + test('post /drafts/:draftId/copy refreshes all node IDs in a document', () => { + expect.hasAssertions() + + // have a bit of a document just to make sure substitutions work everywhere + // actual details such as type, etc. don't matter too much here + const mockDraftObject = { + id: 'mockNewDraftId', + content: { + id: 'mockNewDraftContentId', + title: 'mockDraftTitle' + }, + children: [ + { + id: 'do-not-change-me', + children: [ + { id: '4baa2860-5219-404f-9d99-616ca8f81e41' }, + { + id: 'adcc55b7-e412-4f44-b64f-6c317021f812', + reference: { + id: '4baa2860-5219-404f-9d99-616ca8f81e41' + } + }, + { id: '9d992860-3540-5219-8b4a-1e41616ca8f8' } + ] + } + ] + } + + // this is admittedly sort of magical - we happen to know how many times + // this should run based on the document structure we made above + // potentially find a more elegant way of doing this + uuid + .mockReturnValueOnce('00000000-0000-0000-0000-000000000001') + .mockReturnValueOnce('00000000-0000-0000-0000-000000000002') + .mockReturnValueOnce('00000000-0000-0000-0000-000000000003') + + // this is also a bit brute force, but it does the job + const expectedNewDraftDocument = { + id: 'mockNewDraftId', + content: { + id: 'mockNewDraftContentId', + title: 'New Draft Title' + }, + children: [ + { + id: 'do-not-change-me', + children: [ + { id: '00000000-0000-0000-0000-000000000001' }, + { + id: '00000000-0000-0000-0000-000000000002', + reference: { + id: '00000000-0000-0000-0000-000000000001' + } + }, + { id: '00000000-0000-0000-0000-000000000003' } + ] + } + ] + } + + const mockDraftRootToObject = jest.fn() + mockDraftRootToObject.mockReturnValueOnce(mockDraftObject) + + const mockDraft = { + root: { + toObject: mockDraftRootToObject + }, + // this would be handled by the Draft model, but we're mocking that so + // we have to do this ourselves + nodesById: new Map([ + ['do-not-change-me', {}], + ['4baa2860-5219-404f-9d99-616ca8f81e41', {}], + ['adcc55b7-e412-4f44-b64f-6c317021f812', {}], + ['9d992860-3540-5219-8b4a-1e41616ca8f8', {}] + ]) + } + + DraftPermissions.userHasPermissionToCopy.mockResolvedValueOnce(true) + + Draft.fetchById = jest.fn() + Draft.fetchById.mockResolvedValueOnce(mockDraft) + + return request(app) + .post('/drafts/mockDraftId/copy') + .send({ visitId: 'mockVisitId', title: 'New Draft Title' }) + .then(() => { + expect(uuid).toHaveBeenCalledTimes(3) + // 99 = mock user id + expect(Draft.createWithContent).toHaveBeenCalledWith(99, expectedNewDraftDocument) + }) + }) + test('post /drafts/:draftId/copy returns the expected response when user can not copy draft', () => { expect.hasAssertions() From ce9fb77ddded30bd632568f3c2bb3ebbd72d10ec Mon Sep 17 00:00:00 2001 From: Brandon Stull Date: Tue, 27 Jun 2023 13:38:51 -0400 Subject: [PATCH 17/25] #2013 Made minimal changes to locked package versions to support Node 18. Updated Node version requirements in relevant package.json files, fixed new undefined error message in tests. --- .github/workflows/tests.yml | 10 +- .../obojobo-node-debian.Dockerfile | 2 +- package.json | 2 +- .../app/obojobo-document-engine/package.json | 2 +- .../__tests__/routes/api/visits.test.js | 2 +- packages/app/obojobo-express/package.json | 2 +- .../app/obojobo-module-selector/package.json | 2 +- packages/app/obojobo-repository/package.json | 2 +- yarn.lock | 537 +++++++++--------- 9 files changed, 277 insertions(+), 284 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 73b49df994..a710db52d9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,7 +5,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [14.x] + node-version: [18.x] steps: - name: Checkout code uses: actions/checkout@v2 @@ -19,10 +19,10 @@ jobs: # should help to speed up yarn install and be safe # across changes to the repo and platforms - name: Cache Yarn Deps - uses: c-hive/gha-yarn-cache@v1 + uses: c-hive/gha-yarn-cache@v1 - run: echo "github.ref = ${{ github.ref }}" - + # frozen lockfile should make the cache more effective # and our tests more predictable - run: yarn install --frozen-lockfile @@ -35,7 +35,7 @@ jobs: # will fail the PRs that need prettier run on them - name: Does Prettier Need to Be Run run: git --no-pager diff --exit-code -- . - + - run: yarn test:ci build_docker_images: @@ -83,7 +83,7 @@ jobs: - name: NPM - Test, Build, Deploy uses: actions/setup-node@v1 with: - node-version: 14 + node-version: 18 registry-url: https://registry.npmjs.org/ - name: Cache Yarn Deps diff --git a/docker/dockerfiles/obojobo-node-debian.Dockerfile b/docker/dockerfiles/obojobo-node-debian.Dockerfile index a8cbba9894..acafcc817a 100644 --- a/docker/dockerfiles/obojobo-node-debian.Dockerfile +++ b/docker/dockerfiles/obojobo-node-debian.Dockerfile @@ -1,7 +1,7 @@ # ===================================================================================================== # Base stage used for build and final stages # ===================================================================================================== -FROM node:14.16.0-alpine AS base_stage +FROM node:18.16.0-alpine AS base_stage # ======== PUT NEW NODE BIN DIR IN PATH RUN npm config set prefix '/home/node/.npm-global' diff --git a/package.json b/package.json index 908fc4b17f..773cda6b26 100644 --- a/package.json +++ b/package.json @@ -103,6 +103,6 @@ ], "engines": { "yarn": "^1.15.2", - "node": "^14.16.0" + "node": "^18.16.0" } } diff --git a/packages/app/obojobo-document-engine/package.json b/packages/app/obojobo-document-engine/package.json index 1904ee58cf..cd9acb8bd5 100644 --- a/packages/app/obojobo-document-engine/package.json +++ b/packages/app/obojobo-document-engine/package.json @@ -4,7 +4,7 @@ "license": "AGPL-3.0-only", "description": "", "engines": { - "node": "^14.16.0" + "node": "^18.16.0" }, "main": "index.js", "scripts": { diff --git a/packages/app/obojobo-express/__tests__/routes/api/visits.test.js b/packages/app/obojobo-express/__tests__/routes/api/visits.test.js index 8e319ab7c9..9e85d9565d 100644 --- a/packages/app/obojobo-express/__tests__/routes/api/visits.test.js +++ b/packages/app/obojobo-express/__tests__/routes/api/visits.test.js @@ -368,7 +368,7 @@ describe('api visits route', () => { expect(response.body.value).toHaveProperty('type', 'reject') expect(response.body.value).toHaveProperty( 'message', - "Cannot read property 'lis_outcome_service_url' of undefined" + "Cannot read properties of undefined (reading 'lis_outcome_service_url')" ) }) }) diff --git a/packages/app/obojobo-express/package.json b/packages/app/obojobo-express/package.json index 6c2d613d53..e4e7a8a3a2 100644 --- a/packages/app/obojobo-express/package.json +++ b/packages/app/obojobo-express/package.json @@ -28,7 +28,7 @@ "precommit": "lint-staged" }, "engines": { - "node": "^14.16.0" + "node": "^18.16.0" }, "lint-staged": { "**/*.scss": [ diff --git a/packages/app/obojobo-module-selector/package.json b/packages/app/obojobo-module-selector/package.json index eabde8d61c..fb6f6679be 100644 --- a/packages/app/obojobo-module-selector/package.json +++ b/packages/app/obojobo-module-selector/package.json @@ -15,7 +15,7 @@ "precommit": "lint-staged" }, "engines": { - "node": "^14.16.0" + "node": "^18.16.0" }, "lint-staged": { "**/*.scss": [ diff --git a/packages/app/obojobo-repository/package.json b/packages/app/obojobo-repository/package.json index 98e826a9e0..2157fecb29 100644 --- a/packages/app/obojobo-repository/package.json +++ b/packages/app/obojobo-repository/package.json @@ -15,7 +15,7 @@ "precommit": "lint-staged" }, "engines": { - "node": "^14.16.0" + "node": "^18.16.0" }, "lint-staged": { "**/*.scss": [ diff --git a/yarn.lock b/yarn.lock index 462ee1ef8d..b8c983fef8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1394,10 +1394,10 @@ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" - integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== +"@jridgewell/source-map@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.3.tgz#8108265659d4c33e72ffe14e33d6cc5eb59f2fda" + integrity sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg== dependencies: "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" @@ -2094,6 +2094,21 @@ npmlog "^4.1.2" write-file-atomic "^3.0.3" +"@mapbox/node-pre-gyp@^1.0.0": + version "1.0.10" + resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c" + integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA== + dependencies: + detect-libc "^2.0.0" + https-proxy-agent "^5.0.0" + make-dir "^3.1.0" + node-fetch "^2.6.7" + nopt "^5.0.0" + npmlog "^5.0.1" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.11" + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" @@ -2532,11 +2547,16 @@ resolved "https://registry.yarnpkg.com/@types/esrever/-/esrever-0.2.0.tgz#96404a2284b2c7527f08a1e957f8a31705f9880f" integrity sha512-5NI6TeGzVEy/iBcuYtcPzzIC6EqlfQ2+UZ54vT0ulq8bPNGAy8UJD+XcsAyEOcnYFUjOVWuUV+k4/rVkxt9/XQ== -"@types/estree@*", "@types/estree@^0.0.51": +"@types/estree@*": version "0.0.51" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== +"@types/estree@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" + integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== + "@types/glob@^7.1.1": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" @@ -2725,125 +2745,125 @@ dependencies: "@types/yargs-parser" "*" -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== +"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" + integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== +"@webassemblyjs/helper-buffer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" + integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== +"@webassemblyjs/helper-wasm-section@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" + integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" + integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-opt" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/wast-printer" "1.11.6" + +"@webassemblyjs/wasm-gen@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" + integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" + integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + +"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" + integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" + integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== + dependencies: + "@webassemblyjs/ast" "1.11.6" "@xtuc/long" "4.2.2" "@webpack-cli/configtest@^1.0.2": @@ -2907,10 +2927,10 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== acorn-jsx@^5.3.1: version "5.3.1" @@ -2927,11 +2947,16 @@ acorn@^7.1.1, acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.0.5, acorn@^8.5.0, acorn@^8.7.1: +acorn@^8.0.5, acorn@^8.7.1: version "8.8.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== +acorn@^8.8.2: + version "8.9.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.9.0.tgz#78a16e3b2bcc198c10822786fa6679e245db5b59" + integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== + add-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" @@ -3124,6 +3149,14 @@ aproba@^1.0.3: resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== +are-we-there-yet@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" + integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + are-we-there-yet@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" @@ -4573,12 +4606,12 @@ caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.300011 integrity sha512-JUdjWpcxfJ9IPamy2f5JaRDCaqJOxDzOSKtbdx4rH9VivMd1vIzoPumsJa9LoMIi4Fx2BV2KZOxWhNkBjaYivQ== canvas@^2.6.1: - version "2.7.0" - resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.7.0.tgz#3ce3fe30c69595ccd2bd1232967e681c026be61e" - integrity sha512-pzCxtkHb+5su5MQjTtepMDlIOtaXo277x0C0u3nMOxtkhTyQ+h2yNKhlROAaDllWgRyePAUitC08sXw26Eb6aw== + version "2.11.2" + resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.11.2.tgz#553d87b1e0228c7ac0fc72887c3adbac4abbd860" + integrity sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw== dependencies: - nan "^2.14.0" - node-pre-gyp "^0.15.0" + "@mapbox/node-pre-gyp" "^1.0.0" + nan "^2.17.0" simple-get "^3.0.3" capture-exit@^2.0.0: @@ -4722,7 +4755,7 @@ chokidar@^3.2.2: optionalDependencies: fsevents "~2.3.1" -chownr@^1.1.1, chownr@^1.1.4: +chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== @@ -4941,7 +4974,7 @@ color-string@^1.9.0: color-name "^1.0.0" simple-swizzle "^0.2.2" -color-support@^1.1.3: +color-support@^1.1.2, color-support@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== @@ -4954,7 +4987,7 @@ color@^4.2.3: color-convert "^2.0.1" color-string "^1.9.0" -colorette@^1.2.1, colorette@^1.2.2: +colorette@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== @@ -5803,11 +5836,6 @@ detect-indent@^6.0.0: resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.0.0.tgz#0abd0f549f69fc6659a254fe96786186b6f528fd" integrity sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA== -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - detect-libc@^2.0.0, detect-libc@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" @@ -6083,10 +6111,10 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" -enhanced-resolve@^5.10.0: - version "5.12.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634" - integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ== +enhanced-resolve@^5.15.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -6228,10 +6256,10 @@ es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.18.0-next.1, es-abstrac string.prototype.trimstart "^1.0.4" unbox-primitive "^1.0.0" -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-module-lexer@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.0.tgz#6be9c9e0b4543a60cd166ff6f8b4e9dae0b0c16f" + integrity sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA== es-to-primitive@^1.2.1: version "1.2.1" @@ -6969,13 +6997,6 @@ fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -7026,6 +7047,21 @@ functions-have-names@^1.2.2: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.2.tgz#98d93991c39da9361f8e50b337c4f6e41f120e21" integrity sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA== +gauge@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" + integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.2" + console-control-strings "^1.0.0" + has-unicode "^2.0.1" + object-assign "^4.1.1" + signal-exit "^3.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.2" + gauge@^4.0.3: version "4.0.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" @@ -7714,7 +7750,7 @@ i@0.3.x: resolved "https://registry.yarnpkg.com/i/-/i-0.3.7.tgz#2a7437a923d59c14b17243dc63a549af24d85799" integrity sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q== -iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: +iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -7748,7 +7784,7 @@ ignore-styles@^5.0.1: resolved "https://registry.yarnpkg.com/ignore-styles/-/ignore-styles-5.0.1.tgz#b49ef2274bdafcd8a4880a966bfe38d1a0bf4671" integrity sha1-tJ7yJ0va/NikiAqWa/440aC/RnE= -ignore-walk@^3.0.1, ignore-walk@^3.0.3: +ignore-walk@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== @@ -9992,14 +10028,6 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" -minipass@^2.6.0, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" @@ -10021,13 +10049,6 @@ minipass@^4.0.0: dependencies: yallist "^4.0.0" -minizlib@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -10058,7 +10079,7 @@ mkdirp-infer-owner@^2.0.0: infer-owner "^1.0.4" mkdirp "^1.0.3" -mkdirp@0.x.x, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.x.x, mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -10164,7 +10185,7 @@ mute-stream@0.0.8, mute-stream@~0.0.4: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nan@^2.12.1, nan@^2.14.0, nan@^2.17.0: +nan@^2.12.1, nan@^2.17.0: version "2.17.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== @@ -10174,10 +10195,10 @@ nanoid@^2.1.0: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280" integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA== -nanoid@^3.1.20: - version "3.1.22" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844" - integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ== +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== nanomatch@^1.2.9: version "1.2.13" @@ -10221,15 +10242,6 @@ nearley@^2.7.10: railroad-diagrams "^1.0.0" randexp "0.4.6" -needle@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.6.0.tgz#24dbb55f2509e2324b4a99d61f413982013ccdbe" - integrity sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - negotiator@0.6.3, negotiator@^0.6.2, negotiator@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" @@ -10264,6 +10276,13 @@ node-fetch@^2.6.1: dependencies: whatwg-url "^5.0.0" +node-fetch@^2.6.7: + version "2.6.11" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25" + integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== + dependencies: + whatwg-url "^5.0.0" + node-forge@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" @@ -10312,22 +10331,6 @@ node-notifier@^8.0.0: uuid "^8.3.0" which "^2.0.2" -node-pre-gyp@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz#c2fc383276b74c7ffa842925241553e8b40f1087" - integrity sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.3" - needle "^2.5.0" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4.4.2" - node-releases@^1.1.70: version "1.1.71" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" @@ -10369,14 +10372,6 @@ nodemon@^2.0.4: undefsafe "^2.0.3" update-notifier "^4.1.0" -nopt@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" - integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== - dependencies: - abbrev "1" - osenv "^0.1.4" - nopt@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" @@ -10443,7 +10438,7 @@ normalize-url@^4.1.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== -npm-bundled@^1.0.1, npm-bundled@^1.1.1: +npm-bundled@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== @@ -10485,15 +10480,6 @@ npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.0, npm-pack semver "^7.3.4" validate-npm-package-name "^3.0.0" -npm-packlist@^1.1.6: - version "1.4.8" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" - integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - npm-normalize-package-bin "^1.0.1" - npm-packlist@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-2.1.4.tgz#40e96b2b43787d0546a574542d01e066640d09da" @@ -10542,7 +10528,7 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -npmlog@^4.0.1, npmlog@^4.0.2, npmlog@^4.1.2: +npmlog@^4.0.1, npmlog@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== @@ -10552,6 +10538,16 @@ npmlog@^4.0.1, npmlog@^4.0.2, npmlog@^4.1.2: gauge "~2.7.3" set-blocking "~2.0.0" +npmlog@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" + integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== + dependencies: + are-we-there-yet "^2.0.0" + console-control-strings "^1.1.0" + gauge "^3.0.0" + set-blocking "^2.0.0" + npmlog@^6.0.0: version "6.0.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" @@ -10780,19 +10776,11 @@ os-homedir@^1.0.0: resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - p-cancelable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" @@ -11208,6 +11196,16 @@ pgpass@1.x: dependencies: split2 "^3.1.1" +picocolors@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" + integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" @@ -11428,22 +11426,21 @@ postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.35, postcss@^7.0.6, postcss@^7.0.7: - version "7.0.36" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.36.tgz#056f8cffa939662a8f5905950c07d5285644dfcb" - integrity sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw== + version "7.0.39" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== dependencies: - chalk "^2.4.2" + picocolors "^0.2.1" source-map "^0.6.1" - supports-color "^6.1.0" postcss@^8.2.8: - version "8.2.8" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.8.tgz#0b90f9382efda424c4f0f69a2ead6f6830d08ece" - integrity sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw== + version "8.4.24" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.24.tgz#f714dba9b2284be3cc07dbd2fc57ee4dc972d2df" + integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg== dependencies: - colorette "^1.2.2" - nanoid "^3.1.20" - source-map "^0.6.1" + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" postgres-array@~2.0.0: version "2.0.0" @@ -12488,7 +12485,7 @@ rimraf@2.6.3: dependencies: glob "^7.1.3" -rimraf@2.x.x, rimraf@^2.6.1, rimraf@^2.6.3: +rimraf@2.x.x, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -12534,7 +12531,7 @@ rxjs@^6.6.0, rxjs@^6.6.6: dependencies: tslib "^1.9.0" -safe-buffer@*, safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.1, safe-buffer@~5.2.0: +safe-buffer@*, safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -12642,7 +12639,7 @@ schema-utils@^2.6.5: ajv "^6.12.4" ajv-keywords "^3.5.2" -schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: +schema-utils@^3.0.0, schema-utils@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== @@ -12651,6 +12648,15 @@ schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: ajv "^6.12.5" ajv-keywords "^3.5.2" +schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + scroll-into-view-if-needed@^2.2.20: version "2.2.28" resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.28.tgz#5a15b2f58a52642c88c8eca584644e01703d645a" @@ -13152,6 +13158,11 @@ source-list-map@^2.0.0, source-list-map@^2.0.1: resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + source-map-resolve@^0.5.0: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" @@ -13945,19 +13956,6 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" -tar@^4.4.2: - version "4.4.19" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" - integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== - dependencies: - chownr "^1.1.4" - fs-minipass "^1.2.7" - minipass "^2.9.0" - minizlib "^1.3.3" - mkdirp "^0.5.5" - safe-buffer "^5.2.1" - yallist "^3.1.1" - tar@^6.0.2, tar@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" @@ -14011,24 +14009,24 @@ terminal-link@^2.0.0: ansi-escapes "^4.2.1" supports-hyperlinks "^2.0.0" -terser-webpack-plugin@^5.1.3: - version "5.3.7" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz#ef760632d24991760f339fe9290deb936ad1ffc7" - integrity sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw== +terser-webpack-plugin@^5.3.7: + version "5.3.9" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" + integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== dependencies: "@jridgewell/trace-mapping" "^0.3.17" jest-worker "^27.4.5" schema-utils "^3.1.1" serialize-javascript "^6.0.1" - terser "^5.16.5" + terser "^5.16.8" -terser@^5.16.5: - version "5.16.6" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.6.tgz#f6c7a14a378ee0630fbe3ac8d1f41b4681109533" - integrity sha512-IBZ+ZQIA9sMaXmRZCUMDjNH0D5AQQfdn4WUjHL0+1lF4TP1IHRJbrhb6fNaXWikrYQTSkb7SLxkeXAiy1p7mbg== +terser@^5.16.8: + version "5.18.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.18.1.tgz#6d8642508ae9fb7b48768e48f16d675c89a78460" + integrity sha512-j1n0Ao919h/Ai5r43VAnfV/7azUYW43GPxK7qSATzrsERfW7+y2QW9Cp9ufnRF5CQUWbnLSo7UJokSWCqg4tsQ== dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" commander "^2.20.0" source-map-support "~0.5.20" @@ -14988,21 +14986,21 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.30.0: - version "5.76.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c" - integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA== + version "5.88.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.0.tgz#a07aa2f8e7a64a8f1cec0c6c2e180e3cb34440c8" + integrity sha512-O3jDhG5e44qIBSi/P6KpcCcH7HD+nYIHVBhdWFxcLOcIGN8zGo5nqF3BjyNCxIh4p1vFdNnreZv2h2KkoAw3lw== dependencies: "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" acorn "^8.7.1" - acorn-import-assertions "^1.7.6" + acorn-import-assertions "^1.9.0" browserslist "^4.14.5" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" + enhanced-resolve "^5.15.0" + es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" @@ -15011,9 +15009,9 @@ webpack@^5.30.0: loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^3.1.0" + schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" + terser-webpack-plugin "^5.3.7" watchpack "^2.4.0" webpack-sources "^3.2.3" @@ -15102,7 +15100,7 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -wide-align@^1.1.5: +wide-align@^1.1.2, wide-align@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== @@ -15336,11 +15334,6 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yallist@^3.0.0, yallist@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" From b4e1f404483974d7507f1ddaebc8d47a4ac26acf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 00:19:03 +0000 Subject: [PATCH 18/25] Bump semver from 5.7.1 to 5.7.2 Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2) --- updated-dependencies: - dependency-name: semver dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/yarn.lock b/yarn.lock index 462ee1ef8d..df47f48bfb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12696,9 +12696,9 @@ semver-diff@^3.1.1: semver "^6.3.0" "semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== semver@7.0.0: version "7.0.0" @@ -12706,14 +12706,14 @@ semver@7.0.0: integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" From 730e6237add08c65c45c40aafab4ca9efcbccb4d Mon Sep 17 00:00:00 2001 From: Brandon Stull Date: Tue, 18 Jul 2023 11:28:35 -0400 Subject: [PATCH 19/25] v17.0.0-alpha.0 --- docker/obojobo-pm2-server-src/package.json | 2 +- lerna.json | 2 +- packages/app/obojobo-document-engine/package.json | 2 +- packages/app/obojobo-document-json-parser/package.json | 6 +++--- packages/app/obojobo-document-xml-parser/package.json | 4 ++-- packages/app/obojobo-express/package.json | 8 ++++---- packages/app/obojobo-module-selector/package.json | 8 ++++---- packages/app/obojobo-repository/package.json | 6 +++--- .../obojobo-chunks-abstract-assessment/package.json | 6 +++--- .../obonode/obojobo-chunks-action-button/package.json | 4 ++-- packages/obonode/obojobo-chunks-break/package.json | 4 ++-- packages/obonode/obojobo-chunks-code/package.json | 4 ++-- packages/obonode/obojobo-chunks-excerpt/package.json | 4 ++-- packages/obonode/obojobo-chunks-figure/package.json | 4 ++-- packages/obonode/obojobo-chunks-heading/package.json | 4 ++-- packages/obonode/obojobo-chunks-html/package.json | 4 ++-- packages/obonode/obojobo-chunks-iframe/package.json | 4 ++-- packages/obonode/obojobo-chunks-list/package.json | 4 ++-- packages/obonode/obojobo-chunks-materia/package.json | 8 ++++---- .../obonode/obojobo-chunks-math-equation/package.json | 4 ++-- .../package.json | 6 +++--- .../obojobo-chunks-numeric-assessment/package.json | 6 +++--- .../obonode/obojobo-chunks-question-bank/package.json | 4 ++-- packages/obonode/obojobo-chunks-question/package.json | 4 ++-- packages/obonode/obojobo-chunks-table/package.json | 4 ++-- packages/obonode/obojobo-chunks-text/package.json | 4 ++-- packages/obonode/obojobo-chunks-youtube/package.json | 4 ++-- packages/obonode/obojobo-modules-module/package.json | 4 ++-- packages/obonode/obojobo-pages-page/package.json | 6 +++--- packages/obonode/obojobo-sections-assessment/package.json | 6 +++--- packages/obonode/obojobo-sections-content/package.json | 4 ++-- packages/util/eslint-config-obojobo/package.json | 2 +- packages/util/obojobo-lib-utils/package.json | 2 +- packages/util/stylelint-config-obojobo/package.json | 2 +- 34 files changed, 75 insertions(+), 75 deletions(-) diff --git a/docker/obojobo-pm2-server-src/package.json b/docker/obojobo-pm2-server-src/package.json index 7ad6695f08..c4e622d341 100644 --- a/docker/obojobo-pm2-server-src/package.json +++ b/docker/obojobo-pm2-server-src/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-pm2-server-app", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "description": "Reference project for deploying and customizing an Obojobo Next server", "main": "./index.js", "private": true, diff --git a/lerna.json b/lerna.json index 540ee3dcb0..a8cd6b935c 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "packages/**/*" ], - "version": "16.0.1", + "version": "17.0.0-alpha.0", "command": { "command": { "run": { diff --git a/packages/app/obojobo-document-engine/package.json b/packages/app/obojobo-document-engine/package.json index be6a1c5cec..c02d9e49b6 100644 --- a/packages/app/obojobo-document-engine/package.json +++ b/packages/app/obojobo-document-engine/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-document-engine", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "", "engines": { diff --git a/packages/app/obojobo-document-json-parser/package.json b/packages/app/obojobo-document-json-parser/package.json index 258a447747..1ec92e0510 100644 --- a/packages/app/obojobo-document-json-parser/package.json +++ b/packages/app/obojobo-document-json-parser/package.json @@ -3,11 +3,11 @@ "xml-formatter": "^2.4.0" }, "peerDependencies": { - "obojobo-document-engine": "^16.0.1", - "obojobo-lib-utils": "^16.0.1" + "obojobo-document-engine": "^17.0.0-alpha.0", + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "name": "obojobo-document-json-parser", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "main": "", "scripts": { diff --git a/packages/app/obojobo-document-xml-parser/package.json b/packages/app/obojobo-document-xml-parser/package.json index 5a1bb6cfe8..b0d5602663 100644 --- a/packages/app/obojobo-document-xml-parser/package.json +++ b/packages/app/obojobo-document-xml-parser/package.json @@ -4,10 +4,10 @@ "xml-js": "^1.0.2" }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "name": "obojobo-document-xml-parser", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "main": "xml2draft.js", "scripts": { diff --git a/packages/app/obojobo-express/package.json b/packages/app/obojobo-express/package.json index 9da0ee47ad..166ef57cbf 100644 --- a/packages/app/obojobo-express/package.json +++ b/packages/app/obojobo-express/package.json @@ -1,7 +1,7 @@ { "name": "obojobo-express", "license": "AGPL-3.0-only", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "repository": "https://github.com/ucfopen/Obojobo.git", "homepage": "https://ucfopen.github.io/Obojobo-Docs/", "description": "Obojobo express server middleware.", @@ -69,9 +69,9 @@ "uuid": "^8.3.2" }, "peerDependencies": { - "obojobo-document-engine": "^16.0.1", - "obojobo-document-xml-parser": "^16.0.1", - "obojobo-lib-utils": "^16.0.1" + "obojobo-document-engine": "^17.0.0-alpha.0", + "obojobo-document-xml-parser": "^17.0.0-alpha.0", + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "devDependencies": { "@svgr/webpack": "^5.5.0", diff --git a/packages/app/obojobo-module-selector/package.json b/packages/app/obojobo-module-selector/package.json index 71504c03d0..231edc463d 100644 --- a/packages/app/obojobo-module-selector/package.json +++ b/packages/app/obojobo-module-selector/package.json @@ -1,7 +1,7 @@ { "name": "obojobo-module-selector", "license": "AGPL-3.0-only", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "repository": "https://github.com/ucfopen/Obojobo.git", "homepage": "https://ucfopen.github.io/Obojobo-Docs/", "description": "Obojobo package responsible for selecting which module you use in a course.", @@ -29,8 +29,8 @@ "express": "~4.18.2" }, "peerDependencies": { - "obojobo-express": "^16.0.1", - "obojobo-lib-utils": "^16.0.1", - "obojobo-repository": "^16.0.1" + "obojobo-express": "^17.0.0-alpha.0", + "obojobo-lib-utils": "^17.0.0-alpha.0", + "obojobo-repository": "^17.0.0-alpha.0" } } diff --git a/packages/app/obojobo-repository/package.json b/packages/app/obojobo-repository/package.json index aa6e1ef4cc..2c72365f38 100644 --- a/packages/app/obojobo-repository/package.json +++ b/packages/app/obojobo-repository/package.json @@ -1,7 +1,7 @@ { "name": "obojobo-repository", "license": "AGPL-3.0-only", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "repository": "https://github.com/ucfopen/Obojobo.git", "homepage": "https://ucfopen.github.io/Obojobo-Docs/", "description": "Obojobo express server middleware.", @@ -46,8 +46,8 @@ "use-debounce": "^7.0.0" }, "peerDependencies": { - "obojobo-express": "^16.0.1", - "obojobo-lib-utils": "^16.0.1" + "obojobo-express": "^17.0.0-alpha.0", + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "setupFilesAfterEnv": [ diff --git a/packages/obonode/obojobo-chunks-abstract-assessment/package.json b/packages/obonode/obojobo-chunks-abstract-assessment/package.json index 06ca2a8003..762e6b161a 100644 --- a/packages/obonode/obojobo-chunks-abstract-assessment/package.json +++ b/packages/obonode/obojobo-chunks-abstract-assessment/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-abstract-assessment", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "AbstractAssessment chunk for Obojobo", "scripts": { @@ -28,8 +28,8 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-chunks-question": "^16.0.1", - "obojobo-lib-utils": "^16.0.1" + "obojobo-chunks-question": "^17.0.0-alpha.0", + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "devDependencies": { "lint-staged": "^10.2.2" diff --git a/packages/obonode/obojobo-chunks-action-button/package.json b/packages/obonode/obojobo-chunks-action-button/package.json index 0322c79920..d4c0c186a8 100644 --- a/packages/obonode/obojobo-chunks-action-button/package.json +++ b/packages/obonode/obojobo-chunks-action-button/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-action-button", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "scripts": { "test": "TZ='America/New_York' jest --verbose", @@ -20,7 +20,7 @@ ] }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-break/package.json b/packages/obonode/obojobo-chunks-break/package.json index e2d8e7378a..856e4e9922 100644 --- a/packages/obonode/obojobo-chunks-break/package.json +++ b/packages/obonode/obojobo-chunks-break/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-break", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Break content chunk for Obojobo", "scripts": { @@ -21,7 +21,7 @@ ] }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-code/package.json b/packages/obonode/obojobo-chunks-code/package.json index 559a426445..3ba905c67d 100644 --- a/packages/obonode/obojobo-chunks-code/package.json +++ b/packages/obonode/obojobo-chunks-code/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-code", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Code content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-excerpt/package.json b/packages/obonode/obojobo-chunks-excerpt/package.json index 8f4f0ea5cb..c940ceeec2 100644 --- a/packages/obonode/obojobo-chunks-excerpt/package.json +++ b/packages/obonode/obojobo-chunks-excerpt/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-excerpt", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Excerpt content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-figure/package.json b/packages/obonode/obojobo-chunks-figure/package.json index 0a96049ebd..b25036012c 100644 --- a/packages/obonode/obojobo-chunks-figure/package.json +++ b/packages/obonode/obojobo-chunks-figure/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-figure", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Figure content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-heading/package.json b/packages/obonode/obojobo-chunks-heading/package.json index a3ead51d6b..f2a69b2b14 100644 --- a/packages/obonode/obojobo-chunks-heading/package.json +++ b/packages/obonode/obojobo-chunks-heading/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-heading", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Heading content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-html/package.json b/packages/obonode/obojobo-chunks-html/package.json index e25a6efba3..a9c56b0243 100644 --- a/packages/obonode/obojobo-chunks-html/package.json +++ b/packages/obonode/obojobo-chunks-html/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-html", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "HTML content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-iframe/package.json b/packages/obonode/obojobo-chunks-iframe/package.json index 35f019364e..392c9676f2 100644 --- a/packages/obonode/obojobo-chunks-iframe/package.json +++ b/packages/obonode/obojobo-chunks-iframe/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-iframe", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "IFrame content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-list/package.json b/packages/obonode/obojobo-chunks-list/package.json index d0f252f432..0c7faf0083 100644 --- a/packages/obonode/obojobo-chunks-list/package.json +++ b/packages/obonode/obojobo-chunks-list/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-list", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "List content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-materia/package.json b/packages/obonode/obojobo-chunks-materia/package.json index 2d7ff86436..160fc2cdca 100644 --- a/packages/obonode/obojobo-chunks-materia/package.json +++ b/packages/obonode/obojobo-chunks-materia/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-materia", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Materia content chunk for Obojobo", "scripts": { @@ -35,9 +35,9 @@ "lint-staged": "^10.5.4" }, "peerDependencies": { - "obojobo-chunks-iframe": "^16.0.1", - "obojobo-document-engine": "^16.0.1", - "obojobo-lib-utils": "^16.0.1" + "obojobo-chunks-iframe": "^17.0.0-alpha.0", + "obojobo-document-engine": "^17.0.0-alpha.0", + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-math-equation/package.json b/packages/obonode/obojobo-chunks-math-equation/package.json index b49e161320..0e2e91a41c 100644 --- a/packages/obonode/obojobo-chunks-math-equation/package.json +++ b/packages/obonode/obojobo-chunks-math-equation/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-math-equation", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "MathEquation content chunk for Obojobo", "scripts": { @@ -30,7 +30,7 @@ "katex": "^0.13.1" }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json b/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json index 73a0120afa..19f86cf7c7 100644 --- a/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json +++ b/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-multiple-choice-assessment", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "MCAssessment chunk for Obojobo", "scripts": { @@ -27,8 +27,8 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-chunks-question": "^16.0.1", - "obojobo-lib-utils": "^16.0.1" + "obojobo-chunks-question": "^17.0.0-alpha.0", + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-numeric-assessment/package.json b/packages/obonode/obojobo-chunks-numeric-assessment/package.json index 98e744c8fd..a50e83eea5 100644 --- a/packages/obonode/obojobo-chunks-numeric-assessment/package.json +++ b/packages/obonode/obojobo-chunks-numeric-assessment/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-numeric-assessment", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "NumericAssessment chunk for Obojobo", "scripts": { @@ -30,8 +30,8 @@ "big.js": "^6.1.1" }, "peerDependencies": { - "obojobo-chunks-question": "^16.0.1", - "obojobo-lib-utils": "^16.0.1" + "obojobo-chunks-question": "^17.0.0-alpha.0", + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-question-bank/package.json b/packages/obonode/obojobo-chunks-question-bank/package.json index 65dcc980fa..a8d969e289 100644 --- a/packages/obonode/obojobo-chunks-question-bank/package.json +++ b/packages/obonode/obojobo-chunks-question-bank/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-question-bank", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "QuestionBank chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-question/package.json b/packages/obonode/obojobo-chunks-question/package.json index 645e88319d..4b40db0d60 100644 --- a/packages/obonode/obojobo-chunks-question/package.json +++ b/packages/obonode/obojobo-chunks-question/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-question", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Question content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-table/package.json b/packages/obonode/obojobo-chunks-table/package.json index 4453d69838..19d25e079b 100644 --- a/packages/obonode/obojobo-chunks-table/package.json +++ b/packages/obonode/obojobo-chunks-table/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-table", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Table content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-text/package.json b/packages/obonode/obojobo-chunks-text/package.json index 69f06ea077..53cf1a95d5 100644 --- a/packages/obonode/obojobo-chunks-text/package.json +++ b/packages/obonode/obojobo-chunks-text/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-text", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Text content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-youtube/package.json b/packages/obonode/obojobo-chunks-youtube/package.json index 64ca40e17a..cf257e2eaf 100644 --- a/packages/obonode/obojobo-chunks-youtube/package.json +++ b/packages/obonode/obojobo-chunks-youtube/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-youtube", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Youtube content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-modules-module/package.json b/packages/obonode/obojobo-modules-module/package.json index ec70e63afd..c880c04cdf 100644 --- a/packages/obonode/obojobo-modules-module/package.json +++ b/packages/obonode/obojobo-modules-module/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-modules-module", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Default Module node for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-pages-page/package.json b/packages/obonode/obojobo-pages-page/package.json index 5b8f411060..59876685db 100644 --- a/packages/obonode/obojobo-pages-page/package.json +++ b/packages/obonode/obojobo-pages-page/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-pages-page", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Page chunk for Obojobo", "scripts": { @@ -27,8 +27,8 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-document-engine": "^16.0.1", - "obojobo-lib-utils": "^16.0.1" + "obojobo-document-engine": "^17.0.0-alpha.0", + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-sections-assessment/package.json b/packages/obonode/obojobo-sections-assessment/package.json index 012e3c2a03..6d25c9a738 100644 --- a/packages/obonode/obojobo-sections-assessment/package.json +++ b/packages/obonode/obojobo-sections-assessment/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-sections-assessment", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Assessment section for Obojobo", "scripts": { @@ -27,8 +27,8 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-document-engine": "^16.0.1", - "obojobo-lib-utils": "^16.0.1" + "obojobo-document-engine": "^17.0.0-alpha.0", + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-sections-content/package.json b/packages/obonode/obojobo-sections-content/package.json index 8f2c823006..d93cf9f052 100644 --- a/packages/obonode/obojobo-sections-content/package.json +++ b/packages/obonode/obojobo-sections-content/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-sections-content", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Content section chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^16.0.1" + "obojobo-lib-utils": "^17.0.0-alpha.0" }, "jest": { "testMatch": [ diff --git a/packages/util/eslint-config-obojobo/package.json b/packages/util/eslint-config-obojobo/package.json index 78ee337e8f..4b1c396f4f 100644 --- a/packages/util/eslint-config-obojobo/package.json +++ b/packages/util/eslint-config-obojobo/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-obojobo", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "scripts": { "lint": "echo 'not implemented'", diff --git a/packages/util/obojobo-lib-utils/package.json b/packages/util/obojobo-lib-utils/package.json index 2c2c550701..9140e0e299 100644 --- a/packages/util/obojobo-lib-utils/package.json +++ b/packages/util/obojobo-lib-utils/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-lib-utils", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "description": "Assortment of reusable parts for obojobo libraries.", "scripts": { diff --git a/packages/util/stylelint-config-obojobo/package.json b/packages/util/stylelint-config-obojobo/package.json index dbbdf45452..292416610e 100644 --- a/packages/util/stylelint-config-obojobo/package.json +++ b/packages/util/stylelint-config-obojobo/package.json @@ -1,6 +1,6 @@ { "name": "stylelint-config-obojobo", - "version": "16.0.1", + "version": "17.0.0-alpha.0", "license": "AGPL-3.0-only", "scripts": { "lint": "echo 'not implemented'", From 7b994aba51cbed2a5e59606f8baf897b7caaf1c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 08:33:30 +0000 Subject: [PATCH 20/25] Bump word-wrap from 1.2.3 to 1.2.4 Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4. - [Release notes](https://github.com/jonschlinkert/word-wrap/releases) - [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4) --- updated-dependencies: - dependency-name: word-wrap dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 462ee1ef8d..d261a49530 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15134,9 +15134,9 @@ winston@2.x: stack-trace "0.0.x" word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + version "1.2.4" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f" + integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== wordwrap@^1.0.0: version "1.0.0" From a62ca8154a360bad8b977c07e7b78703345eab34 Mon Sep 17 00:00:00 2001 From: Brandon Stull Date: Fri, 21 Jul 2023 16:19:39 -0400 Subject: [PATCH 21/25] #2005 Added a read-only copy button to the module editor file menu. --- .../__tests__/Viewer/util/editor-api.test.js | 32 +++++++++- .../__snapshots__/file-menu.test.js.snap | 2 +- .../components/toolbars/file-menu.test.js | 58 ++++++++++++++++++- .../components/toolbars/file-menu.js | 44 +++++++++++++- .../src/scripts/viewer/util/editor-api.js | 6 +- .../shared/components/dashboard.jsx | 3 +- 6 files changed, 134 insertions(+), 11 deletions(-) diff --git a/packages/app/obojobo-document-engine/__tests__/Viewer/util/editor-api.test.js b/packages/app/obojobo-document-engine/__tests__/Viewer/util/editor-api.test.js index 7c2984fa03..d1acfcb3a1 100644 --- a/packages/app/obojobo-document-engine/__tests__/Viewer/util/editor-api.test.js +++ b/packages/app/obojobo-document-engine/__tests__/Viewer/util/editor-api.test.js @@ -115,10 +115,33 @@ describe('EditorAPI', () => { expect(res).toBe(mockJsonResult) }) - test('copyDraft fetches with the correct args', async () => { + test('copyDraft fetches with the correct args - allow default readOnly', async () => { const res = await EditorAPI.copyDraft('draft-id', 'new-title') - expect(post).toHaveBeenCalledWith('/api/drafts/draft-id/copy', { title: 'new-title' }) + expect(post).toHaveBeenCalledWith('/api/drafts/draft-id/copy', { + title: 'new-title', + readOnly: false + }) + expect(res).toBe(mockJsonResult) + }) + + test('copyDraft fetches with the correct args - readOnly true', async () => { + const res = await EditorAPI.copyDraft('draft-id', 'new-title', true) + + expect(post).toHaveBeenCalledWith('/api/drafts/draft-id/copy', { + title: 'new-title', + readOnly: true + }) + expect(res).toBe(mockJsonResult) + }) + + test('copyDraft fetches with the correct args - readOnly false', async () => { + const res = await EditorAPI.copyDraft('draft-id', 'new-title', false) + + expect(post).toHaveBeenCalledWith('/api/drafts/draft-id/copy', { + title: 'new-title', + readOnly: false + }) expect(res).toBe(mockJsonResult) }) @@ -147,7 +170,10 @@ describe('EditorAPI', () => { expect.hasAssertions() return EditorAPI.copyDraft('mock-draft-id', 'new title').then(result => { - expect(post).toHaveBeenCalledWith('/api/drafts/mock-draft-id/copy', { title: 'new title' }) + expect(post).toHaveBeenCalledWith('/api/drafts/mock-draft-id/copy', { + title: 'new title', + readOnly: false + }) expect(result).toEqual(mockJsonResult) }) }) diff --git a/packages/app/obojobo-document-engine/__tests__/oboeditor/components/toolbars/__snapshots__/file-menu.test.js.snap b/packages/app/obojobo-document-engine/__tests__/oboeditor/components/toolbars/__snapshots__/file-menu.test.js.snap index 13f3f96345..7d62fb860d 100644 --- a/packages/app/obojobo-document-engine/__tests__/oboeditor/components/toolbars/__snapshots__/file-menu.test.js.snap +++ b/packages/app/obojobo-document-engine/__tests__/oboeditor/components/toolbars/__snapshots__/file-menu.test.js.snap @@ -2,5 +2,5 @@ exports[`File Menu File Menu node 1`] = ` "
" +CTRL+S
" `; diff --git a/packages/app/obojobo-document-engine/__tests__/oboeditor/components/toolbars/file-menu.test.js b/packages/app/obojobo-document-engine/__tests__/oboeditor/components/toolbars/file-menu.test.js index d3ba4ddb26..f4de074627 100644 --- a/packages/app/obojobo-document-engine/__tests__/oboeditor/components/toolbars/file-menu.test.js +++ b/packages/app/obojobo-document-engine/__tests__/oboeditor/components/toolbars/file-menu.test.js @@ -119,6 +119,20 @@ describe('File Menu', () => { expect(ModalUtil.show).toHaveBeenCalled() }) + test('FileMenu calls Copy (Read-Only)', () => { + const model = { + title: 'mockTitle' + } + + const component = mount() + + component + .findWhere(n => n.type() === 'button' && n.html().includes('Make a read-only copy...')) + .simulate('click') + + expect(ModalUtil.show).toHaveBeenCalled() + }) + test('FileMenu calls Download', done => { // setup const model = { @@ -243,7 +257,49 @@ describe('File Menu', () => { .instance() .copyModule('new title') .then(() => { - expect(EditorAPI.copyDraft).toHaveBeenCalledWith('mockDraftId', 'new title') + expect(EditorAPI.copyDraft).toHaveBeenCalledWith('mockDraftId', 'new title', false) + }) + }) + + test('copyModuleReadOnly calls copyDraft api', () => { + expect.hasAssertions() + const model = { + flatJSON: () => ({ children: [] }), + children: [ + { + get: () => CONTENT_NODE, + flatJSON: () => ({ children: [] }), + children: { models: [{ get: () => 'mockValue' }] } + }, + { + get: () => ASSESSMENT_NODE + } + ] + } + + const exportToJSON = jest.fn() + + const component = mount( + + ) + + EditorAPI.copyDraft.mockResolvedValueOnce({ + status: 'ok', + value: { + draftId: 'new-copy-draft-id' + } + }) + + return component + .instance() + .copyModuleReadOnly('new title') + .then(() => { + expect(EditorAPI.copyDraft).toHaveBeenCalledWith('mockDraftId', 'new title', true) }) }) diff --git a/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/toolbars/file-menu.js b/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/toolbars/file-menu.js index ceda023c9a..e913af1451 100644 --- a/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/toolbars/file-menu.js +++ b/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/toolbars/file-menu.js @@ -15,6 +15,7 @@ class FileMenu extends React.PureComponent { constructor(props) { super(props) this.copyModule = this.copyModule.bind(this) + this.copyModuleReadOnly = this.copyModuleReadOnly.bind(this) this.deleteModule = this.deleteModule.bind(this) this.buildFileSelector = this.buildFileSelector.bind(this) } @@ -27,13 +28,37 @@ class FileMenu extends React.PureComponent { }) } - copyModule(newTitle) { + copyModule(newTitle, readOnly = false) { ModalUtil.hide() - return EditorAPI.copyDraft(this.props.draftId, newTitle).then(result => { - window.open(window.location.origin + '/editor/visual/' + result.value.draftId, '_blank') + return EditorAPI.copyDraft(this.props.draftId, newTitle, readOnly).then(result => { + if (readOnly) { + const buttons = [ + { + value: 'OK', + onClick: ModalUtil.hide, + default: true + } + ] + ModalUtil.show( + + A read-only copy of this module has been created. +
+ Read-only copies can not be edited directly. +
+ View the read-only copy in the dashboard to optionally synchronize any edits made to + this module. +
+ ) + } else { + window.open(window.location.origin + '/editor/visual/' + result.value.draftId, '_blank') + } }) } + copyModuleReadOnly(newTitle) { + return this.copyModule(newTitle, true) + } + processFileContent(id, content, type) { EditorAPI.postDraft( id, @@ -101,6 +126,19 @@ class FileMenu extends React.PureComponent { /> ) }, + { + name: 'Make a read-only copy...', + type: 'action', + action: () => + ModalUtil.show( + + ) + }, { name: 'Download', type: 'sub-menu', diff --git a/packages/app/obojobo-document-engine/src/scripts/viewer/util/editor-api.js b/packages/app/obojobo-document-engine/src/scripts/viewer/util/editor-api.js index 3c29b3fb47..cb4645196c 100644 --- a/packages/app/obojobo-document-engine/src/scripts/viewer/util/editor-api.js +++ b/packages/app/obojobo-document-engine/src/scripts/viewer/util/editor-api.js @@ -40,8 +40,10 @@ const EditorAPI = { return API.delete(`/api/drafts/${draftId}`).then(API.processJsonResults) }, - copyDraft(draftId, newTitle) { - return API.post(`/api/drafts/${draftId}/copy`, { title: newTitle }).then(API.processJsonResults) + copyDraft(draftId, newTitle, readOnly = false) { + return API.post(`/api/drafts/${draftId}/copy`, { title: newTitle, readOnly }).then( + API.processJsonResults + ) }, requestEditLock(draftId, contentId) { diff --git a/packages/app/obojobo-repository/shared/components/dashboard.jsx b/packages/app/obojobo-repository/shared/components/dashboard.jsx index 01cdd98e69..be5490103c 100644 --- a/packages/app/obojobo-repository/shared/components/dashboard.jsx +++ b/packages/app/obojobo-repository/shared/components/dashboard.jsx @@ -155,7 +155,8 @@ const renderModalDialog = props => { break case 'module-sync': - ;(title = 'Module Sync'), (dialog = renderSyncDialog(props, extendedProps)) + title = 'Module Sync' + dialog = renderSyncDialog(props, extendedProps) break case 'module-permissions': From 76d1945dc9b2deb58769399f66213d3f11a6cd5a Mon Sep 17 00:00:00 2001 From: Brandon Stull Date: Fri, 4 Aug 2023 11:30:46 -0400 Subject: [PATCH 22/25] #2104 Bumped version requirements for stylelint and postcss-loader. Removed declaration-use-variable dev dependency. Added stylelint-config-standard-scss, stylelint-declaration-strict-value, and autoprefixer dev dependencies. Replaced all instances of 'sh-waqar/declaration-use-variable' with 'scale-unlimited/declaration-strict-value'. Numerous stylelint rule configuration changes to account for existing code not validating against new rules (for now). Fixed sudden descending specificity failures. --- .../oboeditor/components/editor-app.scss | 4 +- .../components/navigation/editor-nav.scss | 2 +- .../src/scripts/viewer/components/nav.scss | 2 +- packages/app/obojobo-express/package.json | 3 +- .../app/obojobo-module-selector/.stylelintrc | 2 +- packages/app/obojobo-repository/.stylelintrc | 2 +- .../stats/assessment-stats-controls.scss | 50 +- .../obojobo-chunks-code/viewer-component.scss | 2 +- .../choose-image-modal.scss | 2 +- .../viewer-component.scss | 10 +- .../obojobo-chunks-table/table-menu.scss | 6 +- .../components/rubric/rubric-modal.scss | 2 +- packages/util/obojobo-lib-utils/package.json | 6 +- .../util/stylelint-config-obojobo/index.js | 33 +- .../stylelint-config-obojobo/package.json | 4 +- yarn.lock | 1637 ++++++----------- 16 files changed, 675 insertions(+), 1092 deletions(-) diff --git a/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/editor-app.scss b/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/editor-app.scss index f724c44dda..3ffca88228 100644 --- a/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/editor-app.scss +++ b/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/editor-app.scss @@ -4,8 +4,8 @@ margin-bottom: 10rem; span::selection { - background-color: highlight; /* stylelint-disable-line sh-waqar/declaration-use-variable */ - color: inherit; /* stylelint-disable-line sh-waqar/declaration-use-variable */ + background-color: highlight; /* stylelint-disable-line scale-unlimited/declaration-strict-value */ + color: inherit; /* stylelint-disable-line scale-unlimited/declaration-strict-value */ } .draft-toolbars { diff --git a/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/navigation/editor-nav.scss b/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/navigation/editor-nav.scss index c09ac7aa29..b7ff5acf63 100644 --- a/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/navigation/editor-nav.scss +++ b/packages/app/obojobo-document-engine/src/scripts/oboeditor/components/navigation/editor-nav.scss @@ -190,7 +190,7 @@ cursor: pointer; padding: 0; margin: 0; - color: inherit; /* stylelint-disable-line sh-waqar/declaration-use-variable */ + color: inherit; /* stylelint-disable-line scale-unlimited/declaration-strict-value */ font-weight: inherit; text-align: left; } diff --git a/packages/app/obojobo-document-engine/src/scripts/viewer/components/nav.scss b/packages/app/obojobo-document-engine/src/scripts/viewer/components/nav.scss index f2fb869f8c..87c745425e 100644 --- a/packages/app/obojobo-document-engine/src/scripts/viewer/components/nav.scss +++ b/packages/app/obojobo-document-engine/src/scripts/viewer/components/nav.scss @@ -270,7 +270,7 @@ cursor: pointer; padding: 0; margin: 0; - color: inherit; /* stylelint-disable-line sh-waqar/declaration-use-variable */ + color: inherit; /* stylelint-disable-line scale-unlimited/declaration-strict-value */ font-weight: inherit; text-align: left; width: 100%; diff --git a/packages/app/obojobo-express/package.json b/packages/app/obojobo-express/package.json index 166ef57cbf..0f35a7e81c 100644 --- a/packages/app/obojobo-express/package.json +++ b/packages/app/obojobo-express/package.json @@ -75,6 +75,7 @@ }, "devDependencies": { "@svgr/webpack": "^5.5.0", + "autoprefixer": "^10.4.14", "babel-loader": "^8.2.2", "babel-polyfill": "^6.26.0", "bluebird": "^3.7.2", @@ -83,7 +84,7 @@ "mini-css-extract-plugin": "^1.4.0", "node-sass": "^8.0.0", "oauth-signature": "^1.5.0", - "postcss-loader": "^5.2.0", + "postcss-loader": "^7.3.3", "sass-loader": "^11.0.1", "style-loader": "^2.0.0", "supertest": "^6.1.3", diff --git a/packages/app/obojobo-module-selector/.stylelintrc b/packages/app/obojobo-module-selector/.stylelintrc index 3b392761f8..51c9e8696d 100644 --- a/packages/app/obojobo-module-selector/.stylelintrc +++ b/packages/app/obojobo-module-selector/.stylelintrc @@ -2,7 +2,7 @@ "extends": "stylelint-config-obojobo", "rules": { "unit-disallowed-list": "warning", - "sh-waqar/declaration-use-variable": "warning", + "scale-unlimited/declaration-strict-value": "warning", "no-descending-specificity": null } } diff --git a/packages/app/obojobo-repository/.stylelintrc b/packages/app/obojobo-repository/.stylelintrc index c9ad9ab7e8..bf338315f0 100644 --- a/packages/app/obojobo-repository/.stylelintrc +++ b/packages/app/obojobo-repository/.stylelintrc @@ -2,6 +2,6 @@ "extends": "stylelint-config-obojobo", "rules": { "unit-disallowed-list": "warning", - "sh-waqar/declaration-use-variable": "warning" + "scale-unlimited/declaration-strict-value": "warning" } } diff --git a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss index 07858890f7..11300063e0 100644 --- a/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss +++ b/packages/app/obojobo-repository/shared/components/stats/assessment-stats-controls.scss @@ -5,6 +5,31 @@ margin-bottom: 1em; } + .filter-controls { + display: flex; + flex-direction: column; + width: 100%; + + hr { + margin-top: 1em; + } + + input { + margin-right: 0.5em; + margin-left: 0; + } + + label { + cursor: pointer; + display: flex; + align-items: center; + + span { + white-space: nowrap; + } + } + } + .search-controls { select { @include select-input(); @@ -90,29 +115,4 @@ font-family: $font-monospace; } } - - .filter-controls { - display: flex; - flex-direction: column; - width: 100%; - - hr { - margin-top: 1em; - } - - input { - margin-right: 0.5em; - margin-left: 0; - } - - label { - cursor: pointer; - display: flex; - align-items: center; - - span { - white-space: nowrap; - } - } - } } diff --git a/packages/obonode/obojobo-chunks-code/viewer-component.scss b/packages/obonode/obojobo-chunks-code/viewer-component.scss index 5d8226a8e4..f138bdf736 100644 --- a/packages/obonode/obojobo-chunks-code/viewer-component.scss +++ b/packages/obonode/obojobo-chunks-code/viewer-component.scss @@ -27,7 +27,7 @@ } code { - font-family: inherit; /* stylelint-disable-line sh-waqar/declaration-use-variable */ + font-family: inherit; /* stylelint-disable-line scale-unlimited/declaration-strict-value */ } } diff --git a/packages/obonode/obojobo-chunks-figure/choose-image-modal.scss b/packages/obonode/obojobo-chunks-figure/choose-image-modal.scss index 5f027a2417..fbd84b46df 100644 --- a/packages/obonode/obojobo-chunks-figure/choose-image-modal.scss +++ b/packages/obonode/obojobo-chunks-figure/choose-image-modal.scss @@ -71,7 +71,7 @@ .choose-image--divider { /* stylelint-disable-next-line unit-disallowed-list */ height: 1px; - /* stylelint-disable-next-line sh-waqar/declaration-use-variable */ + /* stylelint-disable-next-line scale-unlimited/declaration-strict-value */ background-color: darken($color-bg2, 30%); margin: 0.5rem 0; } diff --git a/packages/obonode/obojobo-chunks-math-equation/viewer-component.scss b/packages/obonode/obojobo-chunks-math-equation/viewer-component.scss index 87efb321ce..64c6f3ae07 100644 --- a/packages/obonode/obojobo-chunks-math-equation/viewer-component.scss +++ b/packages/obonode/obojobo-chunks-math-equation/viewer-component.scss @@ -25,12 +25,18 @@ left: 0; top: 0; font-size: 0.8em; - color: lighten($color-text, 30%); // stylelint-disable-line sh-waqar/declaration-use-variable + color: lighten( + $color-text, + 30% + ); // stylelint-disable-line scale-unlimited/declaration-strict-value &::before { content: 'Equation '; font-style: italic; - color: lighten($color-text, 50%); // stylelint-disable-line sh-waqar/declaration-use-variable + color: lighten( + $color-text, + 50% + ); // stylelint-disable-line scale-unlimited/declaration-strict-value } } diff --git a/packages/obonode/obojobo-chunks-table/table-menu.scss b/packages/obonode/obojobo-chunks-table/table-menu.scss index c1b139ad9c..c6e419a453 100644 --- a/packages/obonode/obojobo-chunks-table/table-menu.scss +++ b/packages/obonode/obojobo-chunks-table/table-menu.scss @@ -12,7 +12,7 @@ &:hover { z-index: 2; - // stylelint-disable-next-line sh-waqar/declaration-use-variable + // stylelint-disable-next-line scale-unlimited/declaration-strict-value background-color: white; //$color-action; ul { @@ -58,7 +58,7 @@ font-size: 0.9em; height: auto; background: white; - // stylelint-disable-next-line sh-waqar/declaration-use-variable, font-family-no-missing-generic-family-keyword + // stylelint-disable-next-line scale-unlimited/declaration-strict-value, font-family-no-missing-generic-family-keyword font-family: 'Noto Sans'; font-weight: normal; list-style-type: none; @@ -78,7 +78,7 @@ &:hover { background: $color-action; - // stylelint-disable-next-line sh-waqar/declaration-use-variable + // stylelint-disable-next-line scale-unlimited/declaration-strict-value color: white; } diff --git a/packages/obonode/obojobo-sections-assessment/components/rubric/rubric-modal.scss b/packages/obonode/obojobo-sections-assessment/components/rubric/rubric-modal.scss index 239364d669..454abe11e6 100644 --- a/packages/obonode/obojobo-sections-assessment/components/rubric/rubric-modal.scss +++ b/packages/obonode/obojobo-sections-assessment/components/rubric/rubric-modal.scss @@ -113,7 +113,7 @@ .obojobo-draft--components--button { .button { color: $color-action; - background-color: inherit; /* stylelint-disable-line sh-waqar/declaration-use-variable */ + background-color: inherit; /* stylelint-disable-line scale-unlimited/declaration-strict-value */ border-color: $color-action; border-width: 2px; diff --git a/packages/util/obojobo-lib-utils/package.json b/packages/util/obojobo-lib-utils/package.json index 9140e0e299..43c713c4fe 100644 --- a/packages/util/obojobo-lib-utils/package.json +++ b/packages/util/obojobo-lib-utils/package.json @@ -37,6 +37,7 @@ "@babel/preset-env": "^7.13.12", "@babel/preset-react": "^7.13.13", "@babel/runtime": "^7.13.10", + "autoprefixer": "^10.4.14", "babel-core": "^7.0.0-bridge", "babel-eslint": "^10.1.0", "babel-jest": "26.6.3", @@ -48,9 +49,10 @@ "lint-staged": "^10.5.4", "prettier": "1.18.2", "react-test-renderer": "16.13.1", - "stylelint": "^13.12.0", + "stylelint": "^15.10.0", "stylelint-config-standard": "^21.0.0", - "stylelint-declaration-use-variable": "^1.7.2" + "stylelint-config-standard-scss": "^10.0.0", + "stylelint-declaration-strict-value": "^1.9.2" }, "bin": { "obojobo-migrate": "./bin/obojobo-migrate" diff --git a/packages/util/stylelint-config-obojobo/index.js b/packages/util/stylelint-config-obojobo/index.js index 64faae5f5f..7f2caf0a70 100644 --- a/packages/util/stylelint-config-obojobo/index.js +++ b/packages/util/stylelint-config-obojobo/index.js @@ -1,8 +1,7 @@ module.exports = { - "extends": "stylelint-config-standard", - "plugins": ["stylelint-declaration-use-variable"], + "extends": "stylelint-config-standard-scss", + "plugins": ["stylelint-declaration-strict-value"], "rules": { - "indentation": "tab", "at-rule-no-unknown": [ true, { @@ -18,6 +17,32 @@ module.exports = { } ], "color-hex-length": "long", - "sh-waqar/declaration-use-variable": [["/color/", "font-family"]] + "scale-unlimited/declaration-strict-value": [["/color/", "font-family"]], + + // all below are new rule configurations following the jump to version 15 + // consider overhauling all of the styles to validate against the defaults for these rules + // rather than ignore the rules entirely + "shorthand-property-no-redundant-values": null, + "color-function-notation": "legacy", + "media-feature-range-notation": "prefix", + "property-no-vendor-prefix": null, + "alpha-value-notation": "number", + "declaration-block-no-redundant-longhand-properties": null, + "number-max-precision": 10, + "no-invalid-position-at-import-rule": null, + + // allow for 'thing', 'thing-name', 'parent-name--thing-name', 'parent-name--thing-name--child-name' etc. + "selector-class-pattern": /([\w]+[-]{0,2})+[\w]+/, + "selector-id-pattern": /([\w]+[-]{0,2})+[\w]+/, + "keyframes-name-pattern": /([\w]+[-]{0,2})+[\w]+/, + + "scss/no-global-function-names": null, + "scss/at-mixin-argumentless-call-parentheses": null, + "scss/double-slash-comment-empty-line-before": null, + "scss/double-slash-comment-whitespace-inside": null, + "scss/dollar-variable-empty-line-before": null, + "scss/at-import-partial-extension": null, + "scss/at-import-no-partial-leading-underscore": null, + "scss/operator-no-unspaced": null, } } diff --git a/packages/util/stylelint-config-obojobo/package.json b/packages/util/stylelint-config-obojobo/package.json index 292416610e..08182630d8 100644 --- a/packages/util/stylelint-config-obojobo/package.json +++ b/packages/util/stylelint-config-obojobo/package.json @@ -12,7 +12,9 @@ "precommit": "echo 'not implemented'" }, "devDependencies": { + "autoprefixer": "^10.4.14", "stylelint-config-standard": "^21.0.0", - "stylelint-declaration-use-variable": "^1.7.2" + "stylelint-config-standard-scss": "^10.0.0", + "stylelint-declaration-strict-value": "^1.9.2" } } diff --git a/yarn.lock b/yarn.lock index 9b9016ac1b..c8b475dab2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -28,7 +28,7 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.12.tgz#a8a5ccac19c200f9dd49624cac6e19d7be1236a1" integrity sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ== -"@babel/core@>=7.2.2", "@babel/core@>=7.9.0", "@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.5": +"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.5": version "7.13.10" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.10.tgz#07de050bbd8193fcd8a3c27918c0890613a94559" integrity sha512-bfIYcT0BdKeAZrovpMqX2Mx5NrgAckGbwT982AkdS5GNfn3KMGiprlBAtmBcFZRUmpaufS6WZFP8trvx8ptFDw== @@ -1141,6 +1141,26 @@ exec-sh "^0.3.2" minimist "^1.2.0" +"@csstools/css-parser-algorithms@^2.3.0": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.1.tgz#ec4fc764ba45d2bb7ee2774667e056aa95003f3a" + integrity sha512-xrvsmVUtefWMWQsGgFffqWSK03pZ1vfDki4IVIIUxxDKnGBzqNgv0A7SB1oXtVNEkcVO8xi1ZrTL29HhSu5kGA== + +"@csstools/css-tokenizer@^2.1.1": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-2.2.0.tgz#9d70e6dcbe94e44c7400a2929928db35c4de32b5" + integrity sha512-wErmsWCbsmig8sQKkM6pFhr/oPha1bHfvxsUY5CYSQxwyhA9Ulrs8EqCgClhg4Tgg2XapVstGqSVcz0xOYizZA== + +"@csstools/media-query-list-parser@^2.1.2": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.3.tgz#4471ebd436a22019378fe9c8ac8c0f30c4fbb796" + integrity sha512-ATul1u+pic4aVpstgueqxEv4MsObEbszAxfTXpx9LHaeD3LAh+wFqdCteyegWmjk0k5rkSCAvIOaJe9U3DD09w== + +"@csstools/selector-specificity@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-3.0.0.tgz#798622546b63847e82389e473fd67f2707d82247" + integrity sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g== + "@discoveryjs/json-ext@^0.5.0": version "0.5.2" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752" @@ -2109,14 +2129,6 @@ semver "^7.3.5" tar "^6.1.11" -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - "@nodelib/fs.scandir@2.1.4": version "2.1.4" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" @@ -2130,11 +2142,6 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== - "@nodelib/fs.walk@^1.2.3": version "1.2.6" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" @@ -2353,21 +2360,6 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@stylelint/postcss-css-in-js@^0.37.2": - version "0.37.2" - resolved "https://registry.yarnpkg.com/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.2.tgz#7e5a84ad181f4234a2480803422a47b8749af3d2" - integrity sha512-nEhsFoJurt8oUmieT8qy4nk81WRHmJynmVwn/Vts08PL9fhgIsMhk1GId5yAN643OzqEEb5S/6At2TZW7pqPDA== - dependencies: - "@babel/core" ">=7.9.0" - -"@stylelint/postcss-markdown@^0.36.2": - version "0.36.2" - resolved "https://registry.yarnpkg.com/@stylelint/postcss-markdown/-/postcss-markdown-0.36.2.tgz#0a540c4692f8dcdfc13c8e352c17e7bfee2bb391" - integrity sha512-2kGbqUVJUGE8dM+bMzXG/PYUWKkjLIkRLWNh39OaADkiabDRdw8ATFCgbMz5xdIcvwspPAluSL7uY+ZiTWdWmQ== - dependencies: - remark "^13.0.0" - unist-util-find-all-after "^3.0.2" - "@svgr/babel-plugin-add-jsx-attribute@^5.4.0": version "5.4.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz#81ef61947bb268eb9d50523446f9c638fb355906" @@ -2619,13 +2611,6 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008" integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q== -"@types/mdast@^3.0.0": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.3.tgz#2d7d671b1cd1ea3deb306ea75036c2a0407d2deb" - integrity sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw== - dependencies: - "@types/unist" "*" - "@types/minimatch@*", "@types/minimatch@^3.0.3": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -2636,6 +2621,11 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== +"@types/minimist@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" + integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== + "@types/node@*": version "14.14.35" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.35.tgz#42c953a4e2b18ab931f72477e7012172f4ffa313" @@ -2712,27 +2702,6 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== -"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" - integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== - -"@types/vfile-message@*": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/vfile-message/-/vfile-message-2.0.0.tgz#690e46af0fdfc1f9faae00cd049cc888957927d5" - integrity sha512-GpTIuDpb9u4zIO165fUy9+fXcULdD8HFRNli04GehoMVbeNq7D6OBnqSmg3lxZnC+UvgUhEWKxdKiwYUkGltIw== - dependencies: - vfile-message "*" - -"@types/vfile@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/vfile/-/vfile-3.0.2.tgz#19c18cd232df11ce6fa6ad80259bc86c366b09b9" - integrity sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw== - dependencies: - "@types/node" "*" - "@types/unist" "*" - "@types/vfile-message" "*" - "@types/yargs-parser@*": version "20.2.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" @@ -3020,7 +2989,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -3180,6 +3149,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -3236,7 +3210,7 @@ array-includes@^3.1.2, array-includes@^3.1.3: get-intrinsic "^1.1.1" is-string "^1.0.5" -array-union@^1.0.1, array-union@^1.0.2: +array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= @@ -3322,11 +3296,6 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" @@ -3384,18 +3353,17 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@^9.5.1, autoprefixer@^9.8.6: - version "9.8.6" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" - integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg== +autoprefixer@^10.4.14: + version "10.4.14" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d" + integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== dependencies: - browserslist "^4.12.0" - caniuse-lite "^1.0.30001109" - colorette "^1.2.1" + browserslist "^4.21.5" + caniuse-lite "^1.0.30001464" + fraction.js "^4.2.0" normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^7.0.32" - postcss-value-parser "^4.1.0" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" aws-sign2@~0.7.0: version "0.7.0" @@ -4141,11 +4109,6 @@ backbone@^1.3.3: dependencies: underscore ">=1.8.3" -bail@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" - integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -4339,7 +4302,7 @@ browserslist@^3.2.6: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" -browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.3: +browserslist@^4.14.5, browserslist@^4.16.3: version "4.16.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717" integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw== @@ -4350,6 +4313,16 @@ browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.3: escalade "^3.1.1" node-releases "^1.1.70" +browserslist@^4.21.5: + version "4.21.10" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" + integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== + dependencies: + caniuse-lite "^1.0.30001517" + electron-to-chromium "^1.4.477" + node-releases "^2.0.13" + update-browserslist-db "^1.0.11" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -4520,30 +4493,6 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" -call-me-maybe@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" - integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= - -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -4557,15 +4506,6 @@ camelcase-keys@^2.0.0: camelcase "^2.0.0" map-obj "^1.0.0" -camelcase-keys@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" - integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c= - dependencies: - camelcase "^4.1.0" - map-obj "^2.0.0" - quick-lru "^1.0.0" - camelcase-keys@^6.1.0, camelcase-keys@^6.2.2: version "6.2.2" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" @@ -4575,16 +4515,21 @@ camelcase-keys@^6.1.0, camelcase-keys@^6.2.2: map-obj "^4.0.0" quick-lru "^4.0.1" +camelcase-keys@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-7.0.2.tgz#d048d8c69448745bb0de6fc4c1c52a30dfbe7252" + integrity sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg== + dependencies: + camelcase "^6.3.0" + map-obj "^4.1.0" + quick-lru "^5.1.1" + type-fest "^1.2.1" + camelcase@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= -camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= - camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -4595,16 +4540,26 @@ camelcase@^6.0.0, camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== +camelcase@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + camelize@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= -caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001181: +caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001181: version "1.0.30001204" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001204.tgz#256c85709a348ec4d175e847a3b515c66e79f2aa" integrity sha512-JUdjWpcxfJ9IPamy2f5JaRDCaqJOxDzOSKtbdx4rH9VivMd1vIzoPumsJa9LoMIi4Fx2BV2KZOxWhNkBjaYivQ== +caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001517: + version "1.0.30001519" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz#3e7b8b8a7077e78b0eb054d69e6edf5c7df35601" + integrity sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg== + canvas@^2.6.1: version "2.11.2" resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.11.2.tgz#553d87b1e0228c7ac0fc72887c3adbac4abbd860" @@ -4626,11 +4581,6 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -ccount@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" - integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== - chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -4642,7 +4592,7 @@ chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -4659,7 +4609,7 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -4672,26 +4622,6 @@ char-regex@^1.0.2: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -character-entities-html4@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.4.tgz#0e64b0a3753ddbf1fdc044c5fd01d0199a02e125" - integrity sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g== - -character-entities-legacy@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" - integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== - -character-entities@^1.0.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" - integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== - -character-reference-invalid@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" - integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== - chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -4755,7 +4685,7 @@ chokidar@^3.2.2: optionalDependencies: fsevents "~2.3.1" -chownr@^1.1.1: +chownr@^1.1.1, chownr@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== @@ -4874,13 +4804,6 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -clone-regexp@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-2.2.0.tgz#7d65e00885cd8796405c35a737e7a86b7429e36f" - integrity sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q== - dependencies: - is-regexp "^2.0.0" - clone-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" @@ -4924,11 +4847,6 @@ codemirror@^5.60.0: resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.60.0.tgz#00a8cfd287d5d8737ceb73987f04aee2fe5860da" integrity sha512-AEL7LhFOlxPlCL8IdTcJDblJm8yrAGib7I+DErJPdZd4l6imx8IMgKK3RblVgBQqz3TZJR4oknQ03bz+uNjBYA== -collapse-white-space@^1.0.2: - version "1.0.6" - resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" - integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ== - collect-v8-coverage@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" @@ -4987,6 +4905,11 @@ color@^4.2.3: color-convert "^2.0.1" color-string "^1.9.0" +colord@^2.9.3: + version "2.9.3" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" + integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== + colorette@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" @@ -5292,16 +5215,6 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cosmiconfig@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" - cosmiconfig@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" @@ -5324,6 +5237,16 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" +cosmiconfig@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.2.0.tgz#f7d17c56a590856cd1e7cee98734dca272b0d8fd" + integrity sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ== + dependencies: + import-fresh "^3.2.1" + js-yaml "^4.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + create-jest-runner@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/create-jest-runner/-/create-jest-runner-0.6.0.tgz#9ca6583d969acc15cdc21cd07d430945daf83de6" @@ -5375,6 +5298,16 @@ css-color-keywords@^1.0.0: resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU= +css-color-names@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + integrity sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q== + +css-functions-list@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.2.0.tgz#8290b7d064bf483f48d6559c10e98dc4d1ad19ee" + integrity sha512-d/jBMPyYybkkLVypgtGv12R+pIFw4/f/IHtCTxWpZc8ofTYOPigIgmA6vu5rMHartZC+WuXhBUHfnyNUIQSYrg== + css-loader@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.0.tgz#a9ecda190500863673ce4434033710404efbff00" @@ -5419,6 +5352,11 @@ css-select@^3.1.2: domutils "^2.4.3" nth-check "^2.0.0" +css-shorthand-properties@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/css-shorthand-properties/-/css-shorthand-properties-1.1.1.tgz#1c808e63553c283f289f2dd56fcee8f3337bd935" + integrity sha512-Md+Juc7M3uOdbAFwOYlTrccIZ7oCFuzrhKYQjdeUEW/sE1hv17Jp/Bws+ReOPpGVBTYCBoYo+G17V5Qo8QQ75A== + css-to-react-native@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756" @@ -5444,6 +5382,23 @@ css-tree@^1.1.2: mdn-data "2.0.14" source-map "^0.6.1" +css-tree@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" + integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== + dependencies: + mdn-data "2.0.30" + source-map-js "^1.0.1" + +css-values@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/css-values/-/css-values-0.1.0.tgz#128b7ce103d4dc027a814a5d5995c54781d7b4c6" + integrity sha512-hQ6JSn4t/70aOCvdlP9zTOsFFUifMSKWz3PX7rz5NZl+uEHCqTFVJJvfP07isErCGEVHYoc8Orja8wLKZRvOeg== + dependencies: + css-color-names "0.0.4" + ends-with "^0.2.0" + postcss-value-parser "^3.3.0" + css-what@^3.2.1: version "3.4.2" resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" @@ -5605,7 +5560,7 @@ debug@2.6.9, debug@^2.1.0, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6. dependencies: ms "2.0.0" -debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@~4.3.1: +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@~4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== @@ -5619,7 +5574,7 @@ debug@^3.1.1, debug@^3.2.6: dependencies: ms "^2.1.1" -debug@^4.3.3: +debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -5631,7 +5586,7 @@ debuglog@^1.0.1: resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= -decamelize-keys@^1.0.0, decamelize-keys@^1.1.0: +decamelize-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= @@ -5644,6 +5599,11 @@ decamelize@^1.1.0, decamelize@^1.1.2, decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= +decamelize@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-5.0.1.tgz#db11a92e58c741ef339fb0a2868d8a06a9a7b1e9" + integrity sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA== + decimal.js@^10.2.1: version "10.2.1" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" @@ -5872,13 +5832,6 @@ diff-sequences@^26.6.2: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== -dir-glob@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" - integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== - dependencies: - path-type "^3.0.0" - dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -5955,7 +5908,7 @@ dom-serializer@^1.0.1, dom-serializer@~1.2.0: domhandler "^4.0.0" entities "^2.0.0" -domelementtype@1, domelementtype@^1.3.1: +domelementtype@1: version "1.3.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== @@ -5972,13 +5925,6 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== - dependencies: - domelementtype "1" - domhandler@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.0.0.tgz#01ea7821de996d85f69029e81fa873c21833098e" @@ -5986,7 +5932,7 @@ domhandler@^4.0.0: dependencies: domelementtype "^2.1.0" -domutils@^1.5.1, domutils@^1.7.0: +domutils@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== @@ -6072,6 +6018,11 @@ electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.649: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.699.tgz#854eea9db8bc8109c409a4807bfdb200dd75a2c7" integrity sha512-fjt43CPXdPYwD9ybmKbNeLwZBmCVdLY2J5fGZub7/eMPuiqQznOGNXv/wurnpXIlE7ScHnvG9Zi+H4/i6uMKmw== +electron-to-chromium@^1.4.477: + version "1.4.484" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.484.tgz#770358eba089471c5dae5719db3a5a4fbf02bfb2" + integrity sha512-nO3ZEomTK2PO/3TUXgEx0A97xZTpKVf4p427lABHuCpT1IQ2N+njVh29DkQkCk6Q4m2wjU+faK4xAcfFndwjvw== + emittery@^0.7.1: version "0.7.2" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82" @@ -6111,6 +6062,11 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" +ends-with@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ends-with/-/ends-with-0.2.0.tgz#2f9da98d57a50cfda4571ce4339000500f4e6b8a" + integrity sha512-lRppY4dK3VkqBdR242sKcAJeYc8Gf/DhoX9AWvWI2RzccmLnqBQfwm2k4oSDv5MPDjUqawCauXhZkyWxkVhRsg== + enhanced-resolve@^5.15.0: version "5.15.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" @@ -6126,11 +6082,6 @@ enquirer@^2.3.5, enquirer@^2.3.6: dependencies: ansi-colors "^4.1.1" -entities@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== - entities@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" @@ -6516,13 +6467,6 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -execall@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/execall/-/execall-2.0.0.tgz#16a06b5fe5099df7d00be5d9c06eecded1663b45" - integrity sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow== - dependencies: - clone-regexp "^2.1.0" - exenv@^1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" @@ -6659,7 +6603,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@^3.0.0, extend@~3.0.2: +extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== @@ -6707,19 +6651,7 @@ fast-deep-equal@^3.1.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^2.2.6: - version "2.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" - integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - -fast-glob@^3.2.5, fast-glob@^3.2.9: +fast-glob@^3.2.9: version "3.2.12" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== @@ -6730,6 +6662,17 @@ fast-glob@^3.2.5, fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -6755,6 +6698,11 @@ fastest-levenshtein@^1.0.12: resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== +fastest-levenshtein@^1.0.16: + version "1.0.16" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== + fastq@^1.6.0: version "1.11.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" @@ -6783,13 +6731,6 @@ figures@^3.0.0, figures@^3.2.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -6900,14 +6841,13 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" + locate-path "^6.0.0" + path-exists "^4.0.0" flat-cache@^3.0.4: version "3.0.4" @@ -6917,11 +6857,6 @@ flat-cache@^3.0.4: flatted "^3.1.0" rimraf "^3.0.2" -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - flatted@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" @@ -6970,6 +6905,11 @@ forwarded@0.2.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -6997,6 +6937,13 @@ fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-minipass@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -7147,16 +7094,6 @@ get-stdin@^4.0.1: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= -get-stdin@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-7.0.0.tgz#8d5de98f15171a125c5e516643c7a6d0ea8a96f6" - integrity sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ== - -get-stdin@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" - integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== - get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -7257,11 +7194,6 @@ glob-parent@^5.0.0, glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.0: dependencies: is-glob "^4.0.1" -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= - glob-to-regexp@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" @@ -7349,7 +7281,7 @@ globals@^9.18.0: resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== -globby@^11.0.2, globby@^11.0.3: +globby@^11.0.2, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -7372,20 +7304,6 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" -globby@^9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" - integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^1.0.2" - dir-glob "^2.2.2" - fast-glob "^2.2.6" - glob "^7.1.3" - ignore "^4.0.3" - pify "^4.0.1" - slash "^2.0.0" - globjoin@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" @@ -7400,13 +7318,6 @@ globule@^1.0.0: lodash "~4.17.10" minimatch "~3.0.2" -gonzales-pe@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3" - integrity sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ== - dependencies: - minimist "^1.2.5" - got@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" @@ -7424,7 +7335,7 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.3, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -7606,22 +7517,10 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -html-tags@^3.0.0, html-tags@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140" - integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg== - -htmlparser2@^3.10.0: - version "3.10.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" - integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== - dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" +html-tags@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" + integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== htmlparser2@^6.0.0: version "6.0.1" @@ -7791,12 +7690,12 @@ ignore-walk@^3.0.3: dependencies: minimatch "^3.0.4" -ignore@^4.0.3, ignore@^4.0.6: +ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.0.6, ignore@^5.1.8, ignore@^5.2.0: +ignore@^5.2.0, ignore@^5.2.4: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== @@ -7806,14 +7705,6 @@ immer@^5.0.0: resolved "https://registry.yarnpkg.com/immer/-/immer-5.3.6.tgz#51eab8cbbeb13075fe2244250f221598818cac04" integrity sha512-pqWQ6ozVfNOUDjrLfm4Pt7q4Q12cGw2HUZgry4Q5+Myxu9nmHRkWBpI0J4+MK0AxbdFtdMTwEGVl7Vd+vEiK+A== -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -7868,20 +7759,15 @@ indent-string@^2.1.0: dependencies: repeating "^2.0.0" -indent-string@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" - integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= - indent-string@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= +indent-string@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-5.0.0.tgz#4fd2980fccaf8622d14c64d694f4cf33c81951a5" + integrity sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg== infer-owner@^1.0.4: version "1.0.4" @@ -7901,7 +7787,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -8032,24 +7918,6 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-alphabetical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" - integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== - -is-alphanumeric@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz#4a9cef71daf4c001c1d81d63d140cf53fd6889f4" - integrity sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ= - -is-alphanumerical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" - integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== - dependencies: - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - is-arguments@^1.0.4: version "1.1.0" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" @@ -8098,11 +7966,6 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - is-callable@^1.1.4, is-callable@^1.1.5, is-callable@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" @@ -8122,6 +7985,13 @@ is-core-module@^2.2.0: dependencies: has "^1.0.3" +is-core-module@^2.5.0: + version "2.12.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" + integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== + dependencies: + has "^1.0.3" + is-core-module@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" @@ -8148,11 +8018,6 @@ is-date-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== -is-decimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" - integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== - is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -8171,11 +8036,6 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= - is-docker@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156" @@ -8239,11 +8099,6 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-hexadecimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" - integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== - is-hotkey@^0.1.6: version "0.1.8" resolved "https://registry.yarnpkg.com/is-hotkey/-/is-hotkey-0.1.8.tgz#6b1f4b2d0e5639934e20c05ed24d623a21d36d25" @@ -8368,11 +8223,6 @@ is-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= -is-regexp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-2.1.0.tgz#cd734a56864e23b956bf4e7c66c396a4c0b22c2d" - integrity sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA== - is-ssh@^1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.3.2.tgz#a4b82ab63d73976fd8263cceee27f99a88bdae2b" @@ -8436,21 +8286,11 @@ is-utf8@^0.2.0: resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= -is-whitespace-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" - integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== - is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== -is-word-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" - integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== - is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" @@ -8955,6 +8795,11 @@ jest@26.6.3: import-local "^3.0.2" jest-cli "^26.6.3" +jiti@^1.18.2: + version "1.19.1" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.19.1.tgz#fa99e4b76a23053e0e7cde098efe1704a14c16f1" + integrity sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg== + js-base64@^2.4.9: version "2.6.4" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4" @@ -8989,6 +8834,13 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -9197,15 +9049,10 @@ klona@^2.0.4: resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== -known-css-properties@^0.16.0: - version "0.16.0" - resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.16.0.tgz#3f0597214db11a460df77cd44bcb39e263b9da6c" - integrity sha512-0g5vDDPvNnQk7WM/aE92dTDxXJoOE0biiIcUb3qkn/F6h/ZQZPlZIbE2XSXH2vFPfphkgCxuR2vH6HHnobEOaQ== - -known-css-properties@^0.21.0: - version "0.21.0" - resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.21.0.tgz#15fbd0bbb83447f3ce09d8af247ed47c68ede80d" - integrity sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw== +known-css-properties@^0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.27.0.tgz#82a9358dda5fe7f7bd12b5e7142c0a205393c0c5" + integrity sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg== latest-version@^5.0.0: version "5.1.0" @@ -9398,6 +9245,13 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash._reinterpolate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" @@ -9468,21 +9322,7 @@ lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== - dependencies: - chalk "^2.0.1" - -log-symbols@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" - integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== - dependencies: - chalk "^2.4.2" - -log-symbols@^4.0.0, log-symbols@^4.1.0: +log-symbols@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== @@ -9505,11 +9345,6 @@ loglevel@^1.6.8: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== -longest-streak@^2.0.0, longest-streak@^2.0.1: - version "2.0.4" - resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4" - integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg== - loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -9652,16 +9487,16 @@ map-obj@^1.0.0, map-obj@^1.0.1: resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= -map-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" - integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= - map-obj@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.2.0.tgz#0e8bc823e2aaca8a0942567d12ed14f389eec153" integrity sha512-NAq0fCmZYGz9UFEQyndp7sisrow4GroyGeKluyKC/chuITZsPyOyC1UJZPJlVFImhXdROIP5xqouRLThT3BbpQ== +map-obj@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" + integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== + map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -9669,61 +9504,21 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -markdown-escapes@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" - integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== - -markdown-table@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60" - integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q== - -mathml-tag-names@^2.1.0, mathml-tag-names@^2.1.3: +mathml-tag-names@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3" integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== -mdast-util-compact@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz#d531bb7667b5123abf20859be086c4d06c894593" - integrity sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg== - dependencies: - unist-util-visit "^1.1.0" - -mdast-util-from-markdown@^0.8.0: - version "0.8.5" - resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz#d1ef2ca42bc377ecb0463a987910dae89bd9a28c" - integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-to-string "^2.0.0" - micromark "~2.11.0" - parse-entities "^2.0.0" - unist-util-stringify-position "^2.0.0" - -mdast-util-to-markdown@^0.6.0: - version "0.6.5" - resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz#b33f67ca820d69e6cc527a93d4039249b504bebe" - integrity sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ== - dependencies: - "@types/unist" "^2.0.0" - longest-streak "^2.0.0" - mdast-util-to-string "^2.0.0" - parse-entities "^2.0.0" - repeat-string "^1.0.0" - zwitch "^1.0.0" - -mdast-util-to-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b" - integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w== - mdn-data@2.0.14: version "2.0.14" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== +mdn-data@2.0.30: + version "2.0.30" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" + integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== + mdn-data@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" @@ -9742,6 +9537,24 @@ memory-fs@^0.4.1: errno "^0.1.3" readable-stream "^2.0.1" +meow@^10.1.5: + version "10.1.5" + resolved "https://registry.yarnpkg.com/meow/-/meow-10.1.5.tgz#be52a1d87b5f5698602b0f32875ee5940904aa7f" + integrity sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw== + dependencies: + "@types/minimist" "^1.2.2" + camelcase-keys "^7.0.0" + decamelize "^5.0.0" + decamelize-keys "^1.1.0" + hard-rejection "^2.1.0" + minimist-options "4.1.0" + normalize-package-data "^3.0.2" + read-pkg-up "^8.0.0" + redent "^4.0.0" + trim-newlines "^4.0.2" + type-fest "^1.2.2" + yargs-parser "^20.2.9" + meow@^3.3.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" @@ -9758,21 +9571,6 @@ meow@^3.3.0: redent "^1.0.0" trim-newlines "^1.0.0" -meow@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" - integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig== - dependencies: - camelcase-keys "^4.0.0" - decamelize-keys "^1.0.0" - loud-rejection "^1.0.0" - minimist-options "^3.0.1" - normalize-package-data "^2.3.4" - read-pkg-up "^3.0.0" - redent "^2.0.0" - trim-newlines "^2.0.0" - yargs-parser "^10.0.0" - meow@^8.0.0: version "8.1.2" resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" @@ -9818,7 +9616,7 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: +merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -9828,14 +9626,6 @@ methods@^1.1.2, methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micromark@~2.11.0: - version "2.11.4" - resolved "https://registry.yarnpkg.com/micromark/-/micromark-2.11.4.tgz#d13436138eea826383e822449c9a5c50ee44665a" - integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA== - dependencies: - debug "^4.0.0" - parse-entities "^2.0.0" - micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -9855,7 +9645,7 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4: +micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -9910,7 +9700,7 @@ mimic-response@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -min-indent@^1.0.0: +min-indent@^1.0.0, min-indent@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== @@ -9952,14 +9742,6 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist-options@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" - integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== - dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.3, minimist@^1.2.5: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" @@ -10028,6 +9810,14 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" +minipass@^2.6.0, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" @@ -10049,6 +9839,13 @@ minipass@^4.0.0: dependencies: yallist "^4.0.0" +minizlib@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -10293,10 +10090,43 @@ node-fs@~0.1.5: resolved "https://registry.yarnpkg.com/node-fs/-/node-fs-0.1.7.tgz#32323cccb46c9fbf0fc11812d45021cc31d325bb" integrity sha1-MjI8zLRsn78PwRgS1FAhzDHTJbs= -node-gyp@^5.0.2, node-gyp@^7.1.0, node-gyp@^8.0.0, node-gyp@^8.4.1: - version "8.4.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" - integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== +node-gyp@^5.0.2: + version "5.1.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e" + integrity sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.2" + mkdirp "^0.5.1" + nopt "^4.0.1" + npmlog "^4.1.2" + request "^2.88.0" + rimraf "^2.6.3" + semver "^5.7.1" + tar "^4.4.12" + which "^1.3.1" + +node-gyp@^7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae" + integrity sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.3" + nopt "^5.0.0" + npmlog "^4.1.2" + request "^2.88.2" + rimraf "^3.0.2" + semver "^7.3.2" + tar "^6.0.2" + which "^2.0.2" + +node-gyp@^8.4.1: + version "8.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" + integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== dependencies: env-paths "^2.2.0" glob "^7.1.4" @@ -10336,6 +10166,11 @@ node-releases@^1.1.70: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== + node-sass@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-8.0.0.tgz#c80d52148db0ce88610bcf1e1d112027393c13e1" @@ -10372,6 +10207,14 @@ nodemon@^2.0.4: undefsafe "^2.0.3" update-notifier "^4.1.0" +nopt@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== + dependencies: + abbrev "1" + osenv "^0.1.4" + nopt@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" @@ -10406,6 +10249,16 @@ normalize-package-data@^3.0.0: semver "^7.3.4" validate-npm-package-license "^3.0.1" +normalize-package-data@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" + integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== + dependencies: + hosted-git-info "^4.0.1" + is-core-module "^2.5.0" + semver "^7.3.4" + validate-npm-package-license "^3.0.1" + normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -10421,12 +10274,7 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: normalize-range@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= - -normalize-selector@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03" - integrity sha1-0LFF62kRicY6eNIB3E/bEpPvDAM= + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== normalize-url@^3.3.0: version "3.3.0" @@ -10572,11 +10420,6 @@ nth-check@^2.0.0: dependencies: boolbase "^1.0.0" -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= - number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" @@ -10776,11 +10619,19 @@ os-homedir@^1.0.0: resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= -os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + p-cancelable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" @@ -10810,6 +10661,13 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -10831,6 +10689,13 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-map-series@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-2.1.0.tgz#7560d4c452d9da0c07e692fdbfe6e2c81a2a91f2" @@ -10951,30 +10816,6 @@ parse-database-url@~0.3.0: dependencies: mongodb-uri ">= 0.9.7" -parse-entities@^1.0.2, parse-entities@^1.1.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50" - integrity sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg== - dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - -parse-entities@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" - integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== - dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - parse-github-repo-url@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" @@ -10995,7 +10836,7 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -11196,11 +11037,6 @@ pgpass@1.x: dependencies: split2 "^3.1.1" -picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== - picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -11290,43 +11126,14 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -postcss-html@^0.36.0: - version "0.36.0" - resolved "https://registry.yarnpkg.com/postcss-html/-/postcss-html-0.36.0.tgz#b40913f94eaacc2453fd30a1327ad6ee1f88b204" - integrity sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw== - dependencies: - htmlparser2 "^3.10.0" - -postcss-jsx@^0.36.3: - version "0.36.4" - resolved "https://registry.yarnpkg.com/postcss-jsx/-/postcss-jsx-0.36.4.tgz#37a68f300a39e5748d547f19a747b3257240bd50" - integrity sha512-jwO/7qWUvYuWYnpOb0+4bIIgJt7003pgU3P6nETBLaOyBXuTD55ho21xnals5nBrlpTIFodyd3/jBi6UO3dHvA== - dependencies: - "@babel/core" ">=7.2.2" - -postcss-less@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/postcss-less/-/postcss-less-3.1.4.tgz#369f58642b5928ef898ffbc1a6e93c958304c5ad" - integrity sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA== - dependencies: - postcss "^7.0.14" - -postcss-loader@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-5.2.0.tgz#ccd6668a778902d653602289c765a8bc481986dc" - integrity sha512-uSuCkENFeUaOYsKrXm0eNNgVIxc71z8RcckLMbVw473rGojFnrUeqEz6zBgXsH2q1EIzXnO/4pEz9RhALjlITA== - dependencies: - cosmiconfig "^7.0.0" - klona "^2.0.4" - semver "^7.3.4" - -postcss-markdown@^0.36.0: - version "0.36.0" - resolved "https://registry.yarnpkg.com/postcss-markdown/-/postcss-markdown-0.36.0.tgz#7f22849ae0e3db18820b7b0d5e7833f13a447560" - integrity sha512-rl7fs1r/LNSB2bWRhyZ+lM/0bwKv9fhl38/06gF6mKMo/NPnp55+K1dSTosSVjFZc0e1ppBlu+WT91ba0PMBfQ== +postcss-loader@^7.3.3: + version "7.3.3" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-7.3.3.tgz#6da03e71a918ef49df1bb4be4c80401df8e249dd" + integrity sha512-YgO/yhtevGO/vJePCQmTxiaEwER94LABZN0ZMT4A0vsak9TpO+RvKRs7EmJ8peIlB9xfXCsS7M8LjqncsUZ5HA== dependencies: - remark "^10.0.1" - unist-util-find-all-after "^1.0.2" + cosmiconfig "^8.2.0" + jiti "^1.18.2" + semver "^7.3.8" postcss-media-query-parser@^0.2.3: version "0.2.3" @@ -11361,53 +11168,30 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-reporter@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-6.0.1.tgz#7c055120060a97c8837b4e48215661aafb74245f" - integrity sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw== - dependencies: - chalk "^2.4.1" - lodash "^4.17.11" - log-symbols "^2.2.0" - postcss "^7.0.7" - postcss-resolve-nested-selector@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e" integrity sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4= -postcss-safe-parser@^4.0.1, postcss-safe-parser@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz#a6d4e48f0f37d9f7c11b2a581bf00f8ba4870b96" - integrity sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g== - dependencies: - postcss "^7.0.26" +postcss-safe-parser@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz#bb4c29894171a94bc5c996b9a30317ef402adaa1" + integrity sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ== -postcss-sass@^0.4.1, postcss-sass@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/postcss-sass/-/postcss-sass-0.4.4.tgz#91f0f3447b45ce373227a98b61f8d8f0785285a3" - integrity sha512-BYxnVYx4mQooOhr+zer0qWbSPYnarAy8ZT7hAQtbxtgVf8gy+LSLT/hHGe35h14/pZDTw1DsxdbrwxBN++H+fg== - dependencies: - gonzales-pe "^4.3.0" - postcss "^7.0.21" +postcss-scss@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.6.tgz#5d62a574b950a6ae12f2aa89b60d63d9e4432bfd" + integrity sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ== -postcss-scss@^2.0.0, postcss-scss@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-2.1.1.tgz#ec3a75fa29a55e016b90bf3269026c53c1d2b383" - integrity sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA== +postcss-selector-parser@^6.0.13: + version "6.0.13" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" + integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== dependencies: - postcss "^7.0.6" - -postcss-selector-parser@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz#b310f5c4c0fdaf76f94902bbaa30db6aa84f5270" - integrity sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA== - dependencies: - dot-prop "^5.2.0" - indexes-of "^1.0.1" - uniq "^1.0.1" + cssesc "^3.0.0" + util-deprecate "^1.0.2" -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5: +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: version "6.0.11" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc" integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== @@ -11415,23 +11199,20 @@ postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-syntax@^0.36.2: - version "0.36.2" - resolved "https://registry.yarnpkg.com/postcss-syntax/-/postcss-syntax-0.36.2.tgz#f08578c7d95834574e5593a82dfbfa8afae3b51c" - integrity sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w== +postcss-value-parser@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== -postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.35, postcss@^7.0.6, postcss@^7.0.7: - version "7.0.39" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" - integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== - dependencies: - picocolors "^0.2.1" - source-map "^0.6.1" +postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== postcss@^8.2.8: version "8.4.24" @@ -11442,6 +11223,15 @@ postcss@^8.2.8: picocolors "^1.0.0" source-map-js "^1.0.2" +postcss@^8.4.25: + version "8.4.27" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.27.tgz#234d7e4b72e34ba5a92c29636734349e0d9c3057" + integrity sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + postgres-array@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" @@ -11690,16 +11480,16 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -quick-lru@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" - integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= - quick-lru@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + raf@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" @@ -11938,6 +11728,15 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" +read-pkg-up@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-8.0.0.tgz#72f595b65e66110f43b052dd9af4de6b10534670" + integrity sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ== + dependencies: + find-up "^5.0.0" + read-pkg "^6.0.0" + type-fest "^1.0.1" + read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" @@ -11966,6 +11765,16 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" +read-pkg@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-6.0.0.tgz#a67a7d6a1c2b0c3cd6aa2ea521f40c458a4a504c" + integrity sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^3.0.2" + parse-json "^5.2.0" + type-fest "^1.0.1" + read@1, read@1.0.x, read@~1.0.1: version "1.0.7" resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" @@ -12061,14 +11870,6 @@ redent@^1.0.0: indent-string "^2.1.0" strip-indent "^1.0.1" -redent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" - integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= - dependencies: - indent-string "^3.0.0" - strip-indent "^2.0.0" - redent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" @@ -12077,6 +11878,14 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +redent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-4.0.0.tgz#0c0ba7caabb24257ab3bb7a4fd95dd1d5c5681f9" + integrity sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag== + dependencies: + indent-string "^5.0.0" + strip-indent "^4.0.0" + redux-pack@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/redux-pack/-/redux-pack-0.1.5.tgz#1973b26ef749dfc020e8a61d54cf3e55ec8ae4cd" @@ -12222,79 +12031,6 @@ regjsparser@^0.6.4: dependencies: jsesc "~0.5.0" -remark-parse@^6.0.0: - version "6.0.3" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-6.0.3.tgz#c99131052809da482108413f87b0ee7f52180a3a" - integrity sha512-QbDXWN4HfKTUC0hHa4teU463KclLAnwpn/FBn87j9cKYJWWawbiLgMfP2Q4XwhxxuuuOxHlw+pSN0OKuJwyVvg== - dependencies: - collapse-white-space "^1.0.2" - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - is-whitespace-character "^1.0.0" - is-word-character "^1.0.0" - markdown-escapes "^1.0.0" - parse-entities "^1.1.0" - repeat-string "^1.5.4" - state-toggle "^1.0.0" - trim "0.0.1" - trim-trailing-lines "^1.0.0" - unherit "^1.0.4" - unist-util-remove-position "^1.0.0" - vfile-location "^2.0.0" - xtend "^4.0.1" - -remark-parse@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640" - integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw== - dependencies: - mdast-util-from-markdown "^0.8.0" - -remark-stringify@^6.0.0: - version "6.0.4" - resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-6.0.4.tgz#16ac229d4d1593249018663c7bddf28aafc4e088" - integrity sha512-eRWGdEPMVudijE/psbIDNcnJLRVx3xhfuEsTDGgH4GsFF91dVhw5nhmnBppafJ7+NWINW6C7ZwWbi30ImJzqWg== - dependencies: - ccount "^1.0.0" - is-alphanumeric "^1.0.0" - is-decimal "^1.0.0" - is-whitespace-character "^1.0.0" - longest-streak "^2.0.1" - markdown-escapes "^1.0.0" - markdown-table "^1.1.0" - mdast-util-compact "^1.0.0" - parse-entities "^1.0.2" - repeat-string "^1.5.4" - state-toggle "^1.0.0" - stringify-entities "^1.0.1" - unherit "^1.0.4" - xtend "^4.0.1" - -remark-stringify@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-9.0.1.tgz#576d06e910548b0a7191a71f27b33f1218862894" - integrity sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg== - dependencies: - mdast-util-to-markdown "^0.6.0" - -remark@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/remark/-/remark-10.0.1.tgz#3058076dc41781bf505d8978c291485fe47667df" - integrity sha512-E6lMuoLIy2TyiokHprMjcWNJ5UxfGQjaMSMhV+f4idM625UjjK4j798+gPs5mfjzDE6vL0oFKVeZM6gZVSVrzQ== - dependencies: - remark-parse "^6.0.0" - remark-stringify "^6.0.0" - unified "^7.0.0" - -remark@^13.0.0: - version "13.0.0" - resolved "https://registry.yarnpkg.com/remark/-/remark-13.0.0.tgz#d15d9bf71a402f40287ebe36067b66d54868e425" - integrity sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA== - dependencies: - remark-parse "^9.0.0" - remark-stringify "^9.0.0" - unified "^9.1.0" - remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -12305,7 +12041,7 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.0.0, repeat-string@^1.5.4, repeat-string@^1.6.1: +repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= @@ -12317,11 +12053,6 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -replace-ext@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" - integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= - request-promise-core@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" @@ -12338,7 +12069,7 @@ request-promise-native@^1.0.9: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.88.2: +request@^2.88.0, request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -12478,13 +12209,6 @@ revalidator@0.1.x: resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" integrity sha1-/s5hv6DBtSoga9axgZgYS91SOjs= -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - rimraf@2.x.x, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" @@ -12531,7 +12255,7 @@ rxjs@^6.6.0, rxjs@^6.6.6: dependencies: tslib "^1.9.0" -safe-buffer@*, safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@*, safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -12716,7 +12440,7 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7: +semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -12880,6 +12604,13 @@ short-uuid@^3.1.1: any-base "^1.1.0" uuid "^3.3.2" +shortcss@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/shortcss/-/shortcss-0.1.3.tgz#ee2a7904d80b7f5502c98408f4a2f313faadfb48" + integrity sha512-MIOoTd99CIGTrAuGiMUx9VZrnrZmWzEHuKbGM/w+ia/w98cezhlN9w4aQOVSxswdoqkUnWrMw3tThOi3sevZAg== + dependencies: + css-shorthand-properties "^1.0.0" + shortid@^2.2.16: version "2.2.16" resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.16.tgz#b742b8f0cb96406fd391c76bfc18a67a57fe5608" @@ -12911,6 +12642,11 @@ signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + simple-concat@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" @@ -12951,11 +12687,6 @@ slash@^1.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -12998,15 +12729,6 @@ slate@0.57.2: is-plain-object "^3.0.0" tiny-warning "^1.0.3" -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - slice-ansi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" @@ -13158,7 +12880,7 @@ source-list-map@^2.0.0, source-list-map@^2.0.1: resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== -source-map-js@^1.0.2: +source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== @@ -13258,11 +12980,6 @@ spdy@^4.0.2: select-hose "^2.0.0" spdy-transport "^3.0.0" -specificity@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/specificity/-/specificity-0.4.1.tgz#aab5e645012db08ba182e151165738d00887b019" - integrity sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg== - spex@3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/spex/-/spex-3.2.0.tgz#fa4a21922407e112624977b445a6d634578a1127" @@ -13361,11 +13078,6 @@ stack-utils@^2.0.2: dependencies: escape-string-regexp "^2.0.0" -state-toggle@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" - integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== - static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -13436,7 +13148,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -13511,16 +13223,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringify-entities@^1.0.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-1.3.2.tgz#a98417e5471fd227b3e45d3db1861c11caf668f7" - integrity sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A== - dependencies: - character-entities-html4 "^1.0.0" - character-entities-legacy "^1.0.0" - is-alphanumerical "^1.0.0" - is-hexadecimal "^1.0.0" - stringify-object@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" @@ -13592,11 +13294,6 @@ strip-indent@^1.0.1: dependencies: get-stdin "^4.0.1" -strip-indent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" - integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= - strip-indent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" @@ -13604,6 +13301,13 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" +strip-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.0.0.tgz#b41379433dd06f5eae805e21d631e07ee670d853" + integrity sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA== + dependencies: + min-indent "^1.0.1" + strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -13660,11 +13364,33 @@ styled-components@^5.3.0: shallowequal "^1.1.0" supports-color "^5.5.0" +stylelint-config-recommended-scss@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-12.0.0.tgz#9d9e82c46012649f11bfebcbc788f58e61860f33" + integrity sha512-5Bb2mlGy6WLa30oNeKpZvavv2lowJUsUJO25+OA68GFTemlwd1zbFsL7q0bReKipOSU3sG47hKneZ6Nd+ctrFA== + dependencies: + postcss-scss "^4.0.6" + stylelint-config-recommended "^12.0.0" + stylelint-scss "^5.0.0" + +stylelint-config-recommended@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-12.0.0.tgz#d0993232fca017065fd5acfcb52dd8a188784ef4" + integrity sha512-x6x8QNARrGO2sG6iURkzqL+Dp+4bJorPMMRNPScdvaUK8PsynriOcMW7AFDKqkWAS5wbue/u8fUT/4ynzcmqdQ== + stylelint-config-recommended@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-4.0.0.tgz#665a0034065e6704d5032ba51bf4efa37d328ef9" integrity sha512-sgna89Ng+25Hr9kmmaIxpGWt2LStVm1xf1807PdcWasiPDaOTkOHRL61sINw0twky7QMzafCGToGDnHT/kTHtQ== +stylelint-config-standard-scss@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-standard-scss/-/stylelint-config-standard-scss-10.0.0.tgz#159a54a01b80649bf0143fa7ba086b676a1a749e" + integrity sha512-bChBEo1p3xUVWh/wenJI+josoMk21f2yuLDGzGjmKYcALfl2u3DFltY+n4UHswYiXghqXaA8mRh+bFy/q1hQlg== + dependencies: + stylelint-config-recommended-scss "^12.0.0" + stylelint-config-standard "^33.0.0" + stylelint-config-standard@^21.0.0: version "21.0.0" resolved "https://registry.yarnpkg.com/stylelint-config-standard/-/stylelint-config-standard-21.0.0.tgz#4942cfa27301eb6702fa8fc46a44da35d1a5cfd7" @@ -13672,127 +13398,76 @@ stylelint-config-standard@^21.0.0: dependencies: stylelint-config-recommended "^4.0.0" -stylelint-declaration-use-variable@^1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/stylelint-declaration-use-variable/-/stylelint-declaration-use-variable-1.7.2.tgz#476b2959ed062c407e1d3d507e33fb2dfe05113d" - integrity sha512-mZgrK7VCx7TYSaZbhWgcdsXxmNhlTkOza3pd2ad+sPNQWWP41R6vlRUonGWVc8BNcBXRSXPTAbLgieq1BXIGcQ== +stylelint-config-standard@^33.0.0: + version "33.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-standard/-/stylelint-config-standard-33.0.0.tgz#1f7bb299153a53874073e93829e37a475842f0f9" + integrity sha512-eyxnLWoXImUn77+ODIuW9qXBDNM+ALN68L3wT1lN2oNspZ7D9NVGlNHb2QCUn4xDug6VZLsh0tF8NyoYzkgTzg== dependencies: - stylelint "11.1.1" + stylelint-config-recommended "^12.0.0" -stylelint@11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-11.1.1.tgz#6dbbb348036576ac6b033ddfedba72a877c1d6bb" - integrity sha512-Vx6TAJsxG6qksiFvxQTKriQhp1CqUWdpTDITEkAjTR+l+8Af7qNlvrUDXfpuFJgXh/ayF8xdMSKE+SstcsPmMA== +stylelint-declaration-strict-value@^1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/stylelint-declaration-strict-value/-/stylelint-declaration-strict-value-1.9.2.tgz#f2a884c669974a73f82c9f24b05beb81bc337480" + integrity sha512-Z/2yr7g4tq2iGOUWhZLzHL2g2GJYJGcPkfjDh++zI8ukLxW0tcLGJjo64XYCDjja6YcECPDUWbpN+OAoAtAYvw== dependencies: - autoprefixer "^9.5.1" - balanced-match "^1.0.0" - chalk "^2.4.2" - cosmiconfig "^5.2.0" - debug "^4.1.1" - execall "^2.0.0" - file-entry-cache "^5.0.1" - get-stdin "^7.0.0" - global-modules "^2.0.0" - globby "^9.2.0" - globjoin "^0.1.4" - html-tags "^3.0.0" - ignore "^5.0.6" - import-lazy "^4.0.0" - imurmurhash "^0.1.4" - known-css-properties "^0.16.0" - leven "^3.1.0" - lodash "^4.17.14" - log-symbols "^3.0.0" - mathml-tag-names "^2.1.0" - meow "^5.0.0" - micromatch "^4.0.0" - normalize-selector "^0.2.0" - postcss "^7.0.14" - postcss-html "^0.36.0" - postcss-jsx "^0.36.3" - postcss-less "^3.1.4" - postcss-markdown "^0.36.0" - postcss-media-query-parser "^0.2.3" - postcss-reporter "^6.0.1" - postcss-resolve-nested-selector "^0.1.1" - postcss-safe-parser "^4.0.1" - postcss-sass "^0.4.1" - postcss-scss "^2.0.0" - postcss-selector-parser "^3.1.0" - postcss-syntax "^0.36.2" - postcss-value-parser "^4.0.2" - resolve-from "^5.0.0" - signal-exit "^3.0.2" - slash "^3.0.0" - specificity "^0.4.1" - string-width "^4.1.0" - strip-ansi "^5.2.0" - style-search "^0.1.0" - sugarss "^2.0.0" - svg-tags "^1.0.0" - table "^5.2.3" - v8-compile-cache "^2.1.0" + css-values "^0.1.0" + shortcss "^0.1.3" -stylelint@^13.12.0: - version "13.13.1" - resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-13.13.1.tgz#fca9c9f5de7990ab26a00f167b8978f083a18f3c" - integrity sha512-Mv+BQr5XTUrKqAXmpqm6Ddli6Ief+AiPZkRsIrAoUKFuq/ElkUh9ZMYxXD0iQNZ5ADghZKLOWz1h7hTClB7zgQ== +stylelint-scss@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-5.0.1.tgz#b33a6580b5734eace083cfc2cc3021225e28547f" + integrity sha512-n87iCRZrr2J7//I/QFsDXxFLnHKw633U4qvWZ+mOW6KDAp/HLj06H+6+f9zOuTYy+MdGdTuCSDROCpQIhw5fvQ== dependencies: - "@stylelint/postcss-css-in-js" "^0.37.2" - "@stylelint/postcss-markdown" "^0.36.2" - autoprefixer "^9.8.6" + postcss-media-query-parser "^0.2.3" + postcss-resolve-nested-selector "^0.1.1" + postcss-selector-parser "^6.0.13" + postcss-value-parser "^4.2.0" + +stylelint@^15.10.0: + version "15.10.2" + resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-15.10.2.tgz#0ee5a8371d3a2e1ff27fefd48309d3ddef7c3405" + integrity sha512-UxqSb3hB74g4DTO45QhUHkJMjKKU//lNUAOWyvPBVPZbCknJ5HjOWWZo+UDuhHa9FLeVdHBZXxu43eXkjyIPWg== + dependencies: + "@csstools/css-parser-algorithms" "^2.3.0" + "@csstools/css-tokenizer" "^2.1.1" + "@csstools/media-query-list-parser" "^2.1.2" + "@csstools/selector-specificity" "^3.0.0" balanced-match "^2.0.0" - chalk "^4.1.1" - cosmiconfig "^7.0.0" - debug "^4.3.1" - execall "^2.0.0" - fast-glob "^3.2.5" - fastest-levenshtein "^1.0.12" + colord "^2.9.3" + cosmiconfig "^8.2.0" + css-functions-list "^3.2.0" + css-tree "^2.3.1" + debug "^4.3.4" + fast-glob "^3.3.0" + fastest-levenshtein "^1.0.16" file-entry-cache "^6.0.1" - get-stdin "^8.0.0" global-modules "^2.0.0" - globby "^11.0.3" + globby "^11.1.0" globjoin "^0.1.4" - html-tags "^3.1.0" - ignore "^5.1.8" + html-tags "^3.3.1" + ignore "^5.2.4" import-lazy "^4.0.0" imurmurhash "^0.1.4" - known-css-properties "^0.21.0" - lodash "^4.17.21" - log-symbols "^4.1.0" + is-plain-object "^5.0.0" + known-css-properties "^0.27.0" mathml-tag-names "^2.1.3" - meow "^9.0.0" - micromatch "^4.0.4" - normalize-selector "^0.2.0" - postcss "^7.0.35" - postcss-html "^0.36.0" - postcss-less "^3.1.4" - postcss-media-query-parser "^0.2.3" + meow "^10.1.5" + micromatch "^4.0.5" + normalize-path "^3.0.0" + picocolors "^1.0.0" + postcss "^8.4.25" postcss-resolve-nested-selector "^0.1.1" - postcss-safe-parser "^4.0.2" - postcss-sass "^0.4.4" - postcss-scss "^2.1.1" - postcss-selector-parser "^6.0.5" - postcss-syntax "^0.36.2" - postcss-value-parser "^4.1.0" + postcss-safe-parser "^6.0.0" + postcss-selector-parser "^6.0.13" + postcss-value-parser "^4.2.0" resolve-from "^5.0.0" - slash "^3.0.0" - specificity "^0.4.1" - string-width "^4.2.2" - strip-ansi "^6.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" style-search "^0.1.0" - sugarss "^2.0.0" + supports-hyperlinks "^3.0.0" svg-tags "^1.0.0" - table "^6.6.0" - v8-compile-cache "^2.3.0" - write-file-atomic "^3.0.3" - -sugarss@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-2.0.0.tgz#ddd76e0124b297d40bf3cca31c8b22ecb43bc61d" - integrity sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ== - dependencies: - postcss "^7.0.2" + table "^6.8.1" + write-file-atomic "^5.0.1" superagent@^6.1.0: version "6.1.0" @@ -13860,6 +13535,14 @@ supports-hyperlinks@^2.0.0: has-flag "^4.0.0" supports-color "^7.0.0" +supports-hyperlinks@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz#c711352a5c89070779b4dad54c05a2f14b15c94b" + integrity sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" @@ -13909,17 +13592,7 @@ sysend@^1.3.5: resolved "https://registry.yarnpkg.com/sysend/-/sysend-1.10.0.tgz#af5f7d52b00947563fc9f4e2fbeb6db52912dd41" integrity sha512-kQDpqW60fvgbNLnWnTRaJ2KGX3aW5fThu9St8T4h+j8XC1YIDXhWVqS8Ho+WYgasmtrP7RvcRRhs+SVCb9o7wA== -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -table@^6.0.4, table@^6.6.0: +table@^6.0.4, table@^6.8.1: version "6.8.1" resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== @@ -13956,6 +13629,19 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" +tar@^4.4.12: + version "4.4.19" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" + integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== + dependencies: + chownr "^1.1.4" + fs-minipass "^1.2.7" + minipass "^2.9.0" + minizlib "^1.3.3" + mkdirp "^0.5.5" + safe-buffer "^5.2.1" + yallist "^3.1.1" + tar@^6.0.2, tar@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" @@ -14206,16 +13892,16 @@ trim-newlines@^1.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= -trim-newlines@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" - integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= - trim-newlines@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.0.tgz#79726304a6a898aa8373427298d54c2ee8b1cb30" integrity sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA== +trim-newlines@^4.0.2: + version "4.1.1" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-4.1.1.tgz#28c88deb50ed10c7ba6dc2474421904a00139125" + integrity sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ== + trim-off-newlines@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.3.tgz#8df24847fcb821b0ab27d58ab6efec9f2fe961a1" @@ -14226,21 +13912,6 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= -trim-trailing-lines@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" - integrity sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ== - -trim@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" - integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= - -trough@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" - integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== - "true-case-path@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-2.2.1.tgz#c5bf04a5bbec3fd118be4084461b3a27c4d796bf" @@ -14321,6 +13992,11 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^1.0.1, type-fest@^1.2.1, type-fest@^1.2.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" + integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== + type-is@^1.6.4, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -14385,14 +14061,6 @@ underscore@1.12.1, underscore@>=1.8.3: resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.12.1.tgz#7bb8cc9b3d397e201cf8553336d262544ead829e" integrity sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw== -unherit@^1.0.4: - version "1.1.3" - resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22" - integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ== - dependencies: - inherits "^2.0.0" - xtend "^4.0.0" - unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -14416,32 +14084,6 @@ unicode-property-aliases-ecmascript@^1.0.4: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== -unified@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/unified/-/unified-7.1.0.tgz#5032f1c1ee3364bd09da12e27fdd4a7553c7be13" - integrity sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw== - dependencies: - "@types/unist" "^2.0.0" - "@types/vfile" "^3.0.0" - bail "^1.0.0" - extend "^3.0.0" - is-plain-obj "^1.1.0" - trough "^1.0.0" - vfile "^3.0.0" - x-is-string "^0.1.0" - -unified@^9.1.0: - version "9.2.1" - resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.1.tgz#ae18d5674c114021bfdbdf73865ca60f410215a3" - integrity sha512-juWjuI8Z4xFg8pJbnEZ41b5xjGUWGHqXALmBZ3FC3WX0PIx1CZBIIJ6mXbYMcf6Yw4Fi0rFUTA1cdz/BglbOhA== - dependencies: - bail "^1.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^2.0.0" - trough "^1.0.0" - vfile "^4.0.0" - union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -14452,11 +14094,6 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" -uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= - unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" @@ -14492,63 +14129,6 @@ unique-string@^2.0.0: dependencies: crypto-random-string "^2.0.0" -unist-util-find-all-after@^1.0.2: - version "1.0.5" - resolved "https://registry.yarnpkg.com/unist-util-find-all-after/-/unist-util-find-all-after-1.0.5.tgz#5751a8608834f41d117ad9c577770c5f2f1b2899" - integrity sha512-lWgIc3rrTMTlK1Y0hEuL+k+ApzFk78h+lsaa2gHf63Gp5Ww+mt11huDniuaoq1H+XMK2lIIjjPkncxXcDp3QDw== - dependencies: - unist-util-is "^3.0.0" - -unist-util-find-all-after@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz#fdfecd14c5b7aea5e9ef38d5e0d5f774eeb561f6" - integrity sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ== - dependencies: - unist-util-is "^4.0.0" - -unist-util-is@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-3.0.0.tgz#d9e84381c2468e82629e4a5be9d7d05a2dd324cd" - integrity sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A== - -unist-util-is@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" - integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== - -unist-util-remove-position@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz#ec037348b6102c897703eee6d0294ca4755a2020" - integrity sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A== - dependencies: - unist-util-visit "^1.1.0" - -unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz#3f37fcf351279dcbca7480ab5889bb8a832ee1c6" - integrity sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ== - -unist-util-stringify-position@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" - integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== - dependencies: - "@types/unist" "^2.0.2" - -unist-util-visit-parents@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz#25e43e55312166f3348cae6743588781d112c1e9" - integrity sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g== - dependencies: - unist-util-is "^3.0.0" - -unist-util-visit@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.4.1.tgz#4724aaa8486e6ee6e26d7ff3c8685960d560b1e3" - integrity sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw== - dependencies: - unist-util-visit-parents "^2.0.0" - universal-user-agent@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" @@ -14592,6 +14172,14 @@ upath@^2.0.1: resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + update-notifier@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.3.tgz#be86ee13e8ce48fb50043ff72057b5bd598e1ea3" @@ -14717,7 +14305,7 @@ uuid@~3.1.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== -v8-compile-cache@^2.0.3, v8-compile-cache@^2.1.0, v8-compile-cache@^2.2.0, v8-compile-cache@^2.3.0: +v8-compile-cache@^2.0.3, v8-compile-cache@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== @@ -14765,46 +14353,6 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -vfile-location@^2.0.0: - version "2.0.6" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.6.tgz#8a274f39411b8719ea5728802e10d9e0dff1519e" - integrity sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA== - -vfile-message@*, vfile-message@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" - integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== - dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^2.0.0" - -vfile-message@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-1.1.1.tgz#5833ae078a1dfa2d96e9647886cd32993ab313e1" - integrity sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA== - dependencies: - unist-util-stringify-position "^1.1.1" - -vfile@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-3.0.1.tgz#47331d2abe3282424f4a4bb6acd20a44c4121803" - integrity sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ== - dependencies: - is-buffer "^2.0.0" - replace-ext "1.0.0" - unist-util-stringify-position "^1.0.0" - vfile-message "^1.0.0" - -vfile@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" - integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^2.0.0" - vfile-message "^2.0.0" - w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" @@ -15192,6 +14740,14 @@ write-file-atomic@^3.0.0, write-file-atomic@^3.0.3: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" +write-file-atomic@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7" + integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^4.0.1" + write-json-file@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-3.2.0.tgz#65bbdc9ecd8a1458e15952770ccbadfcff5fe62a" @@ -15225,13 +14781,6 @@ write-pkg@^4.0.0: type-fest "^0.4.1" write-json-file "^3.2.0" -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - ws@^6.2.1: version "6.2.2" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" @@ -15244,11 +14793,6 @@ ws@^7.4.4: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw== -x-is-string@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" - integrity sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI= - xdg-basedir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" @@ -15314,7 +14858,7 @@ xstate@^4.13.0: resolved "https://registry.yarnpkg.com/xstate/-/xstate-4.13.0.tgz#0be22ceb8bae2bc6a025fab330fe44204d76771c" integrity sha512-UnUJJzP2KTPqnmxIoD/ymXtpy/hehZnUlO6EXqWC/72XkPb15p9Oz/X4WhS3QE+by7NP+6b5bCi/GTGFzm5D+A== -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: +xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== @@ -15334,6 +14878,11 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= +yallist@^3.0.0, yallist@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" @@ -15349,13 +14898,6 @@ yargs-parser@20.2.4: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== -yargs-parser@^10.0.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" - integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== - dependencies: - camelcase "^4.1.0" - yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" @@ -15377,6 +14919,11 @@ yargs-parser@^20.2.2, yargs-parser@^20.2.3: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== +yargs-parser@^20.2.9: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" @@ -15441,7 +14988,7 @@ yargs@^17.2.1: y18n "^5.0.5" yargs-parser "^21.1.1" -zwitch@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" - integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From c05c9c47926ffc1663af8f1134ad7431815fe2a6 Mon Sep 17 00:00:00 2001 From: Brandon Stull Date: Wed, 23 Aug 2023 09:27:34 -0400 Subject: [PATCH 23/25] #2104 Merged changes from dev branch, saving automatic dependency changes. --- yarn.lock | 101 ++++-------------------------------------------------- 1 file changed, 6 insertions(+), 95 deletions(-) diff --git a/yarn.lock b/yarn.lock index c8b475dab2..38f0f95654 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4685,7 +4685,7 @@ chokidar@^3.2.2: optionalDependencies: fsevents "~2.3.1" -chownr@^1.1.1, chownr@^1.1.4: +chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== @@ -6937,13 +6937,6 @@ fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -7335,7 +7328,7 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.3, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -9810,14 +9803,6 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" -minipass@^2.6.0, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" @@ -9839,13 +9824,6 @@ minipass@^4.0.0: dependencies: yallist "^4.0.0" -minizlib@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -10090,40 +10068,7 @@ node-fs@~0.1.5: resolved "https://registry.yarnpkg.com/node-fs/-/node-fs-0.1.7.tgz#32323cccb46c9fbf0fc11812d45021cc31d325bb" integrity sha1-MjI8zLRsn78PwRgS1FAhzDHTJbs= -node-gyp@^5.0.2: - version "5.1.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e" - integrity sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.2" - mkdirp "^0.5.1" - nopt "^4.0.1" - npmlog "^4.1.2" - request "^2.88.0" - rimraf "^2.6.3" - semver "^5.7.1" - tar "^4.4.12" - which "^1.3.1" - -node-gyp@^7.1.0: - version "7.1.2" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae" - integrity sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.3" - nopt "^5.0.0" - npmlog "^4.1.2" - request "^2.88.2" - rimraf "^3.0.2" - semver "^7.3.2" - tar "^6.0.2" - which "^2.0.2" - -node-gyp@^8.4.1: +node-gyp@^5.0.2, node-gyp@^7.1.0, node-gyp@^8.0.0, node-gyp@^8.4.1: version "8.4.1" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== @@ -10207,14 +10152,6 @@ nodemon@^2.0.4: undefsafe "^2.0.3" update-notifier "^4.1.0" -nopt@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" - integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== - dependencies: - abbrev "1" - osenv "^0.1.4" - nopt@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" @@ -10619,19 +10556,11 @@ os-homedir@^1.0.0: resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - p-cancelable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" @@ -12069,7 +11998,7 @@ request-promise-native@^1.0.9: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.88.0, request@^2.88.2: +request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -12255,7 +12184,7 @@ rxjs@^6.6.0, rxjs@^6.6.6: dependencies: tslib "^1.9.0" -safe-buffer@*, safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.1, safe-buffer@~5.2.0: +safe-buffer@*, safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -13629,19 +13558,6 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" -tar@^4.4.12: - version "4.4.19" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" - integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== - dependencies: - chownr "^1.1.4" - fs-minipass "^1.2.7" - minipass "^2.9.0" - minizlib "^1.3.3" - mkdirp "^0.5.5" - safe-buffer "^5.2.1" - yallist "^3.1.1" - tar@^6.0.2, tar@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" @@ -14878,11 +14794,6 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yallist@^3.0.0, yallist@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" From 8b02836f927be3111a02573c52761f9a39ed635f Mon Sep 17 00:00:00 2001 From: Brandon Stull Date: Tue, 5 Sep 2023 09:30:09 -0400 Subject: [PATCH 24/25] v17.0.0-alpha.1 --- docker/obojobo-pm2-server-src/package.json | 2 +- lerna.json | 2 +- packages/app/obojobo-document-engine/package.json | 2 +- packages/app/obojobo-document-json-parser/package.json | 6 +++--- packages/app/obojobo-document-xml-parser/package.json | 4 ++-- packages/app/obojobo-express/package.json | 8 ++++---- packages/app/obojobo-module-selector/package.json | 8 ++++---- packages/app/obojobo-repository/package.json | 6 +++--- .../obojobo-chunks-abstract-assessment/package.json | 6 +++--- .../obonode/obojobo-chunks-action-button/package.json | 4 ++-- packages/obonode/obojobo-chunks-break/package.json | 4 ++-- packages/obonode/obojobo-chunks-code/package.json | 4 ++-- packages/obonode/obojobo-chunks-excerpt/package.json | 4 ++-- packages/obonode/obojobo-chunks-figure/package.json | 4 ++-- packages/obonode/obojobo-chunks-heading/package.json | 4 ++-- packages/obonode/obojobo-chunks-html/package.json | 4 ++-- packages/obonode/obojobo-chunks-iframe/package.json | 4 ++-- packages/obonode/obojobo-chunks-list/package.json | 4 ++-- packages/obonode/obojobo-chunks-materia/package.json | 8 ++++---- .../obonode/obojobo-chunks-math-equation/package.json | 4 ++-- .../package.json | 6 +++--- .../obojobo-chunks-numeric-assessment/package.json | 6 +++--- .../obonode/obojobo-chunks-question-bank/package.json | 4 ++-- packages/obonode/obojobo-chunks-question/package.json | 4 ++-- packages/obonode/obojobo-chunks-table/package.json | 4 ++-- packages/obonode/obojobo-chunks-text/package.json | 4 ++-- packages/obonode/obojobo-chunks-youtube/package.json | 4 ++-- packages/obonode/obojobo-modules-module/package.json | 4 ++-- packages/obonode/obojobo-pages-page/package.json | 6 +++--- packages/obonode/obojobo-sections-assessment/package.json | 6 +++--- packages/obonode/obojobo-sections-content/package.json | 4 ++-- packages/util/eslint-config-obojobo/package.json | 2 +- packages/util/obojobo-lib-utils/package.json | 2 +- packages/util/stylelint-config-obojobo/package.json | 2 +- 34 files changed, 75 insertions(+), 75 deletions(-) diff --git a/docker/obojobo-pm2-server-src/package.json b/docker/obojobo-pm2-server-src/package.json index c4e622d341..1db0bf2c9c 100644 --- a/docker/obojobo-pm2-server-src/package.json +++ b/docker/obojobo-pm2-server-src/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-pm2-server-app", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "description": "Reference project for deploying and customizing an Obojobo Next server", "main": "./index.js", "private": true, diff --git a/lerna.json b/lerna.json index a8cd6b935c..c83eb94dbf 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "packages/**/*" ], - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "command": { "command": { "run": { diff --git a/packages/app/obojobo-document-engine/package.json b/packages/app/obojobo-document-engine/package.json index c02d9e49b6..25f21cc63e 100644 --- a/packages/app/obojobo-document-engine/package.json +++ b/packages/app/obojobo-document-engine/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-document-engine", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "", "engines": { diff --git a/packages/app/obojobo-document-json-parser/package.json b/packages/app/obojobo-document-json-parser/package.json index 1ec92e0510..5ee132ac47 100644 --- a/packages/app/obojobo-document-json-parser/package.json +++ b/packages/app/obojobo-document-json-parser/package.json @@ -3,11 +3,11 @@ "xml-formatter": "^2.4.0" }, "peerDependencies": { - "obojobo-document-engine": "^17.0.0-alpha.0", - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-document-engine": "^17.0.0-alpha.1", + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "name": "obojobo-document-json-parser", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "main": "", "scripts": { diff --git a/packages/app/obojobo-document-xml-parser/package.json b/packages/app/obojobo-document-xml-parser/package.json index b0d5602663..1e9707e044 100644 --- a/packages/app/obojobo-document-xml-parser/package.json +++ b/packages/app/obojobo-document-xml-parser/package.json @@ -4,10 +4,10 @@ "xml-js": "^1.0.2" }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "name": "obojobo-document-xml-parser", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "main": "xml2draft.js", "scripts": { diff --git a/packages/app/obojobo-express/package.json b/packages/app/obojobo-express/package.json index 0f35a7e81c..f18c20f1b3 100644 --- a/packages/app/obojobo-express/package.json +++ b/packages/app/obojobo-express/package.json @@ -1,7 +1,7 @@ { "name": "obojobo-express", "license": "AGPL-3.0-only", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "repository": "https://github.com/ucfopen/Obojobo.git", "homepage": "https://ucfopen.github.io/Obojobo-Docs/", "description": "Obojobo express server middleware.", @@ -69,9 +69,9 @@ "uuid": "^8.3.2" }, "peerDependencies": { - "obojobo-document-engine": "^17.0.0-alpha.0", - "obojobo-document-xml-parser": "^17.0.0-alpha.0", - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-document-engine": "^17.0.0-alpha.1", + "obojobo-document-xml-parser": "^17.0.0-alpha.1", + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "devDependencies": { "@svgr/webpack": "^5.5.0", diff --git a/packages/app/obojobo-module-selector/package.json b/packages/app/obojobo-module-selector/package.json index 231edc463d..b575b1ebc8 100644 --- a/packages/app/obojobo-module-selector/package.json +++ b/packages/app/obojobo-module-selector/package.json @@ -1,7 +1,7 @@ { "name": "obojobo-module-selector", "license": "AGPL-3.0-only", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "repository": "https://github.com/ucfopen/Obojobo.git", "homepage": "https://ucfopen.github.io/Obojobo-Docs/", "description": "Obojobo package responsible for selecting which module you use in a course.", @@ -29,8 +29,8 @@ "express": "~4.18.2" }, "peerDependencies": { - "obojobo-express": "^17.0.0-alpha.0", - "obojobo-lib-utils": "^17.0.0-alpha.0", - "obojobo-repository": "^17.0.0-alpha.0" + "obojobo-express": "^17.0.0-alpha.1", + "obojobo-lib-utils": "^17.0.0-alpha.1", + "obojobo-repository": "^17.0.0-alpha.1" } } diff --git a/packages/app/obojobo-repository/package.json b/packages/app/obojobo-repository/package.json index 2c72365f38..bd109de60f 100644 --- a/packages/app/obojobo-repository/package.json +++ b/packages/app/obojobo-repository/package.json @@ -1,7 +1,7 @@ { "name": "obojobo-repository", "license": "AGPL-3.0-only", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "repository": "https://github.com/ucfopen/Obojobo.git", "homepage": "https://ucfopen.github.io/Obojobo-Docs/", "description": "Obojobo express server middleware.", @@ -46,8 +46,8 @@ "use-debounce": "^7.0.0" }, "peerDependencies": { - "obojobo-express": "^17.0.0-alpha.0", - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-express": "^17.0.0-alpha.1", + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "setupFilesAfterEnv": [ diff --git a/packages/obonode/obojobo-chunks-abstract-assessment/package.json b/packages/obonode/obojobo-chunks-abstract-assessment/package.json index 762e6b161a..821ca15308 100644 --- a/packages/obonode/obojobo-chunks-abstract-assessment/package.json +++ b/packages/obonode/obojobo-chunks-abstract-assessment/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-abstract-assessment", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "AbstractAssessment chunk for Obojobo", "scripts": { @@ -28,8 +28,8 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-chunks-question": "^17.0.0-alpha.0", - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-chunks-question": "^17.0.0-alpha.1", + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "devDependencies": { "lint-staged": "^10.2.2" diff --git a/packages/obonode/obojobo-chunks-action-button/package.json b/packages/obonode/obojobo-chunks-action-button/package.json index d4c0c186a8..6c2f923ea0 100644 --- a/packages/obonode/obojobo-chunks-action-button/package.json +++ b/packages/obonode/obojobo-chunks-action-button/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-action-button", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "scripts": { "test": "TZ='America/New_York' jest --verbose", @@ -20,7 +20,7 @@ ] }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-break/package.json b/packages/obonode/obojobo-chunks-break/package.json index 856e4e9922..cf28bb93c5 100644 --- a/packages/obonode/obojobo-chunks-break/package.json +++ b/packages/obonode/obojobo-chunks-break/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-break", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Break content chunk for Obojobo", "scripts": { @@ -21,7 +21,7 @@ ] }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-code/package.json b/packages/obonode/obojobo-chunks-code/package.json index 3ba905c67d..c71bf3ccd8 100644 --- a/packages/obonode/obojobo-chunks-code/package.json +++ b/packages/obonode/obojobo-chunks-code/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-code", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Code content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-excerpt/package.json b/packages/obonode/obojobo-chunks-excerpt/package.json index c940ceeec2..367423425e 100644 --- a/packages/obonode/obojobo-chunks-excerpt/package.json +++ b/packages/obonode/obojobo-chunks-excerpt/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-excerpt", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Excerpt content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-figure/package.json b/packages/obonode/obojobo-chunks-figure/package.json index b25036012c..095fdcbdd0 100644 --- a/packages/obonode/obojobo-chunks-figure/package.json +++ b/packages/obonode/obojobo-chunks-figure/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-figure", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Figure content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-heading/package.json b/packages/obonode/obojobo-chunks-heading/package.json index f2a69b2b14..3bade5d24a 100644 --- a/packages/obonode/obojobo-chunks-heading/package.json +++ b/packages/obonode/obojobo-chunks-heading/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-heading", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Heading content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-html/package.json b/packages/obonode/obojobo-chunks-html/package.json index a9c56b0243..28dd822dae 100644 --- a/packages/obonode/obojobo-chunks-html/package.json +++ b/packages/obonode/obojobo-chunks-html/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-html", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "HTML content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-iframe/package.json b/packages/obonode/obojobo-chunks-iframe/package.json index 392c9676f2..0dcb9821e2 100644 --- a/packages/obonode/obojobo-chunks-iframe/package.json +++ b/packages/obonode/obojobo-chunks-iframe/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-iframe", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "IFrame content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-list/package.json b/packages/obonode/obojobo-chunks-list/package.json index 0c7faf0083..7c54b93bfe 100644 --- a/packages/obonode/obojobo-chunks-list/package.json +++ b/packages/obonode/obojobo-chunks-list/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-list", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "List content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-materia/package.json b/packages/obonode/obojobo-chunks-materia/package.json index 160fc2cdca..5bde3aea95 100644 --- a/packages/obonode/obojobo-chunks-materia/package.json +++ b/packages/obonode/obojobo-chunks-materia/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-materia", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Materia content chunk for Obojobo", "scripts": { @@ -35,9 +35,9 @@ "lint-staged": "^10.5.4" }, "peerDependencies": { - "obojobo-chunks-iframe": "^17.0.0-alpha.0", - "obojobo-document-engine": "^17.0.0-alpha.0", - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-chunks-iframe": "^17.0.0-alpha.1", + "obojobo-document-engine": "^17.0.0-alpha.1", + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-math-equation/package.json b/packages/obonode/obojobo-chunks-math-equation/package.json index 0e2e91a41c..a593c3ef63 100644 --- a/packages/obonode/obojobo-chunks-math-equation/package.json +++ b/packages/obonode/obojobo-chunks-math-equation/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-math-equation", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "MathEquation content chunk for Obojobo", "scripts": { @@ -30,7 +30,7 @@ "katex": "^0.13.1" }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json b/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json index 19f86cf7c7..59801c1955 100644 --- a/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json +++ b/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-multiple-choice-assessment", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "MCAssessment chunk for Obojobo", "scripts": { @@ -27,8 +27,8 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-chunks-question": "^17.0.0-alpha.0", - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-chunks-question": "^17.0.0-alpha.1", + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-numeric-assessment/package.json b/packages/obonode/obojobo-chunks-numeric-assessment/package.json index a50e83eea5..2c94ab37cf 100644 --- a/packages/obonode/obojobo-chunks-numeric-assessment/package.json +++ b/packages/obonode/obojobo-chunks-numeric-assessment/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-numeric-assessment", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "NumericAssessment chunk for Obojobo", "scripts": { @@ -30,8 +30,8 @@ "big.js": "^6.1.1" }, "peerDependencies": { - "obojobo-chunks-question": "^17.0.0-alpha.0", - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-chunks-question": "^17.0.0-alpha.1", + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-question-bank/package.json b/packages/obonode/obojobo-chunks-question-bank/package.json index a8d969e289..150409bcca 100644 --- a/packages/obonode/obojobo-chunks-question-bank/package.json +++ b/packages/obonode/obojobo-chunks-question-bank/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-question-bank", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "QuestionBank chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-question/package.json b/packages/obonode/obojobo-chunks-question/package.json index 4b40db0d60..05f50646c5 100644 --- a/packages/obonode/obojobo-chunks-question/package.json +++ b/packages/obonode/obojobo-chunks-question/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-question", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Question content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-table/package.json b/packages/obonode/obojobo-chunks-table/package.json index 19d25e079b..52fa185650 100644 --- a/packages/obonode/obojobo-chunks-table/package.json +++ b/packages/obonode/obojobo-chunks-table/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-table", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Table content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-text/package.json b/packages/obonode/obojobo-chunks-text/package.json index 53cf1a95d5..80d3ba32db 100644 --- a/packages/obonode/obojobo-chunks-text/package.json +++ b/packages/obonode/obojobo-chunks-text/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-text", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Text content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-youtube/package.json b/packages/obonode/obojobo-chunks-youtube/package.json index cf257e2eaf..6fc20676b9 100644 --- a/packages/obonode/obojobo-chunks-youtube/package.json +++ b/packages/obonode/obojobo-chunks-youtube/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-youtube", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Youtube content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-modules-module/package.json b/packages/obonode/obojobo-modules-module/package.json index c880c04cdf..402518ca72 100644 --- a/packages/obonode/obojobo-modules-module/package.json +++ b/packages/obonode/obojobo-modules-module/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-modules-module", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Default Module node for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-pages-page/package.json b/packages/obonode/obojobo-pages-page/package.json index 59876685db..7d6f80ef1a 100644 --- a/packages/obonode/obojobo-pages-page/package.json +++ b/packages/obonode/obojobo-pages-page/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-pages-page", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Page chunk for Obojobo", "scripts": { @@ -27,8 +27,8 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-document-engine": "^17.0.0-alpha.0", - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-document-engine": "^17.0.0-alpha.1", + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-sections-assessment/package.json b/packages/obonode/obojobo-sections-assessment/package.json index 6d25c9a738..9066223171 100644 --- a/packages/obonode/obojobo-sections-assessment/package.json +++ b/packages/obonode/obojobo-sections-assessment/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-sections-assessment", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Assessment section for Obojobo", "scripts": { @@ -27,8 +27,8 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-document-engine": "^17.0.0-alpha.0", - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-document-engine": "^17.0.0-alpha.1", + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-sections-content/package.json b/packages/obonode/obojobo-sections-content/package.json index d93cf9f052..1905c5e61a 100644 --- a/packages/obonode/obojobo-sections-content/package.json +++ b/packages/obonode/obojobo-sections-content/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-sections-content", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Content section chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.0" + "obojobo-lib-utils": "^17.0.0-alpha.1" }, "jest": { "testMatch": [ diff --git a/packages/util/eslint-config-obojobo/package.json b/packages/util/eslint-config-obojobo/package.json index 4b1c396f4f..603ba3af49 100644 --- a/packages/util/eslint-config-obojobo/package.json +++ b/packages/util/eslint-config-obojobo/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-obojobo", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "scripts": { "lint": "echo 'not implemented'", diff --git a/packages/util/obojobo-lib-utils/package.json b/packages/util/obojobo-lib-utils/package.json index 43c713c4fe..ac15c263c0 100644 --- a/packages/util/obojobo-lib-utils/package.json +++ b/packages/util/obojobo-lib-utils/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-lib-utils", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "description": "Assortment of reusable parts for obojobo libraries.", "scripts": { diff --git a/packages/util/stylelint-config-obojobo/package.json b/packages/util/stylelint-config-obojobo/package.json index 08182630d8..f8aac2441c 100644 --- a/packages/util/stylelint-config-obojobo/package.json +++ b/packages/util/stylelint-config-obojobo/package.json @@ -1,6 +1,6 @@ { "name": "stylelint-config-obojobo", - "version": "17.0.0-alpha.0", + "version": "17.0.0-alpha.1", "license": "AGPL-3.0-only", "scripts": { "lint": "echo 'not implemented'", From a785647f8f8de78bf68060fde9e84ebf6a2e5ae9 Mon Sep 17 00:00:00 2001 From: Brandon Stull Date: Wed, 13 Sep 2023 13:33:29 -0400 Subject: [PATCH 25/25] v17.0.0 --- docker/obojobo-pm2-server-src/package.json | 2 +- lerna.json | 2 +- package.json | 2 +- packages/app/obojobo-document-engine/package.json | 2 +- packages/app/obojobo-document-json-parser/package.json | 6 +++--- packages/app/obojobo-document-xml-parser/package.json | 4 ++-- packages/app/obojobo-express/package.json | 8 ++++---- packages/app/obojobo-module-selector/package.json | 8 ++++---- packages/app/obojobo-repository/package.json | 6 +++--- .../obojobo-chunks-abstract-assessment/package.json | 6 +++--- .../obonode/obojobo-chunks-action-button/package.json | 4 ++-- packages/obonode/obojobo-chunks-break/package.json | 4 ++-- packages/obonode/obojobo-chunks-code/package.json | 4 ++-- packages/obonode/obojobo-chunks-excerpt/package.json | 4 ++-- packages/obonode/obojobo-chunks-figure/package.json | 4 ++-- packages/obonode/obojobo-chunks-heading/package.json | 4 ++-- packages/obonode/obojobo-chunks-html/package.json | 4 ++-- packages/obonode/obojobo-chunks-iframe/package.json | 4 ++-- packages/obonode/obojobo-chunks-list/package.json | 4 ++-- packages/obonode/obojobo-chunks-materia/package.json | 8 ++++---- .../obonode/obojobo-chunks-math-equation/package.json | 4 ++-- .../package.json | 6 +++--- .../obojobo-chunks-numeric-assessment/package.json | 6 +++--- .../obonode/obojobo-chunks-question-bank/package.json | 4 ++-- packages/obonode/obojobo-chunks-question/package.json | 4 ++-- packages/obonode/obojobo-chunks-table/package.json | 4 ++-- packages/obonode/obojobo-chunks-text/package.json | 4 ++-- packages/obonode/obojobo-chunks-youtube/package.json | 4 ++-- packages/obonode/obojobo-modules-module/package.json | 4 ++-- packages/obonode/obojobo-pages-page/package.json | 6 +++--- packages/obonode/obojobo-sections-assessment/package.json | 6 +++--- packages/obonode/obojobo-sections-content/package.json | 4 ++-- packages/util/eslint-config-obojobo/package.json | 2 +- packages/util/obojobo-lib-utils/package.json | 2 +- packages/util/stylelint-config-obojobo/package.json | 2 +- 35 files changed, 76 insertions(+), 76 deletions(-) diff --git a/docker/obojobo-pm2-server-src/package.json b/docker/obojobo-pm2-server-src/package.json index 1db0bf2c9c..4a18f79834 100644 --- a/docker/obojobo-pm2-server-src/package.json +++ b/docker/obojobo-pm2-server-src/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-pm2-server-app", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "description": "Reference project for deploying and customizing an Obojobo Next server", "main": "./index.js", "private": true, diff --git a/lerna.json b/lerna.json index c83eb94dbf..1609246001 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "packages/**/*" ], - "version": "17.0.0-alpha.1", + "version": "17.0.0", "command": { "command": { "run": { diff --git a/package.json b/package.json index 773cda6b26..9cb61c894f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "obojobo-next", - "version": "16.0.1", + "version": "17.0.0", "repository": "https://github.com/ucfopen/Obojobo.git", "homepage": "https://ucfopen.github.io/Obojobo-Docs/", "license": "AGPL-3.0-only", diff --git a/packages/app/obojobo-document-engine/package.json b/packages/app/obojobo-document-engine/package.json index 25f21cc63e..1bf2824f2a 100644 --- a/packages/app/obojobo-document-engine/package.json +++ b/packages/app/obojobo-document-engine/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-document-engine", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "", "engines": { diff --git a/packages/app/obojobo-document-json-parser/package.json b/packages/app/obojobo-document-json-parser/package.json index 5ee132ac47..3de200495e 100644 --- a/packages/app/obojobo-document-json-parser/package.json +++ b/packages/app/obojobo-document-json-parser/package.json @@ -3,11 +3,11 @@ "xml-formatter": "^2.4.0" }, "peerDependencies": { - "obojobo-document-engine": "^17.0.0-alpha.1", - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-document-engine": "^17.0.0", + "obojobo-lib-utils": "^17.0.0" }, "name": "obojobo-document-json-parser", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "main": "", "scripts": { diff --git a/packages/app/obojobo-document-xml-parser/package.json b/packages/app/obojobo-document-xml-parser/package.json index 1e9707e044..f9a4d34a39 100644 --- a/packages/app/obojobo-document-xml-parser/package.json +++ b/packages/app/obojobo-document-xml-parser/package.json @@ -4,10 +4,10 @@ "xml-js": "^1.0.2" }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "name": "obojobo-document-xml-parser", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "main": "xml2draft.js", "scripts": { diff --git a/packages/app/obojobo-express/package.json b/packages/app/obojobo-express/package.json index f18c20f1b3..79ccf75012 100644 --- a/packages/app/obojobo-express/package.json +++ b/packages/app/obojobo-express/package.json @@ -1,7 +1,7 @@ { "name": "obojobo-express", "license": "AGPL-3.0-only", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "repository": "https://github.com/ucfopen/Obojobo.git", "homepage": "https://ucfopen.github.io/Obojobo-Docs/", "description": "Obojobo express server middleware.", @@ -69,9 +69,9 @@ "uuid": "^8.3.2" }, "peerDependencies": { - "obojobo-document-engine": "^17.0.0-alpha.1", - "obojobo-document-xml-parser": "^17.0.0-alpha.1", - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-document-engine": "^17.0.0", + "obojobo-document-xml-parser": "^17.0.0", + "obojobo-lib-utils": "^17.0.0" }, "devDependencies": { "@svgr/webpack": "^5.5.0", diff --git a/packages/app/obojobo-module-selector/package.json b/packages/app/obojobo-module-selector/package.json index b575b1ebc8..384a980e81 100644 --- a/packages/app/obojobo-module-selector/package.json +++ b/packages/app/obojobo-module-selector/package.json @@ -1,7 +1,7 @@ { "name": "obojobo-module-selector", "license": "AGPL-3.0-only", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "repository": "https://github.com/ucfopen/Obojobo.git", "homepage": "https://ucfopen.github.io/Obojobo-Docs/", "description": "Obojobo package responsible for selecting which module you use in a course.", @@ -29,8 +29,8 @@ "express": "~4.18.2" }, "peerDependencies": { - "obojobo-express": "^17.0.0-alpha.1", - "obojobo-lib-utils": "^17.0.0-alpha.1", - "obojobo-repository": "^17.0.0-alpha.1" + "obojobo-express": "^17.0.0", + "obojobo-lib-utils": "^17.0.0", + "obojobo-repository": "^17.0.0" } } diff --git a/packages/app/obojobo-repository/package.json b/packages/app/obojobo-repository/package.json index bd109de60f..2215c3ecc3 100644 --- a/packages/app/obojobo-repository/package.json +++ b/packages/app/obojobo-repository/package.json @@ -1,7 +1,7 @@ { "name": "obojobo-repository", "license": "AGPL-3.0-only", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "repository": "https://github.com/ucfopen/Obojobo.git", "homepage": "https://ucfopen.github.io/Obojobo-Docs/", "description": "Obojobo express server middleware.", @@ -46,8 +46,8 @@ "use-debounce": "^7.0.0" }, "peerDependencies": { - "obojobo-express": "^17.0.0-alpha.1", - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-express": "^17.0.0", + "obojobo-lib-utils": "^17.0.0" }, "jest": { "setupFilesAfterEnv": [ diff --git a/packages/obonode/obojobo-chunks-abstract-assessment/package.json b/packages/obonode/obojobo-chunks-abstract-assessment/package.json index 821ca15308..6c7aee920f 100644 --- a/packages/obonode/obojobo-chunks-abstract-assessment/package.json +++ b/packages/obonode/obojobo-chunks-abstract-assessment/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-abstract-assessment", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "AbstractAssessment chunk for Obojobo", "scripts": { @@ -28,8 +28,8 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-chunks-question": "^17.0.0-alpha.1", - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-chunks-question": "^17.0.0", + "obojobo-lib-utils": "^17.0.0" }, "devDependencies": { "lint-staged": "^10.2.2" diff --git a/packages/obonode/obojobo-chunks-action-button/package.json b/packages/obonode/obojobo-chunks-action-button/package.json index 6c2f923ea0..930d71c513 100644 --- a/packages/obonode/obojobo-chunks-action-button/package.json +++ b/packages/obonode/obojobo-chunks-action-button/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-action-button", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "scripts": { "test": "TZ='America/New_York' jest --verbose", @@ -20,7 +20,7 @@ ] }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-break/package.json b/packages/obonode/obojobo-chunks-break/package.json index cf28bb93c5..19805c1fb2 100644 --- a/packages/obonode/obojobo-chunks-break/package.json +++ b/packages/obonode/obojobo-chunks-break/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-break", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Break content chunk for Obojobo", "scripts": { @@ -21,7 +21,7 @@ ] }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-code/package.json b/packages/obonode/obojobo-chunks-code/package.json index c71bf3ccd8..d97bb24cf8 100644 --- a/packages/obonode/obojobo-chunks-code/package.json +++ b/packages/obonode/obojobo-chunks-code/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-code", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Code content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-excerpt/package.json b/packages/obonode/obojobo-chunks-excerpt/package.json index 367423425e..4b2d465251 100644 --- a/packages/obonode/obojobo-chunks-excerpt/package.json +++ b/packages/obonode/obojobo-chunks-excerpt/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-excerpt", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Excerpt content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-figure/package.json b/packages/obonode/obojobo-chunks-figure/package.json index 095fdcbdd0..72635b0c06 100644 --- a/packages/obonode/obojobo-chunks-figure/package.json +++ b/packages/obonode/obojobo-chunks-figure/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-figure", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Figure content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-heading/package.json b/packages/obonode/obojobo-chunks-heading/package.json index 3bade5d24a..bf3d841ff3 100644 --- a/packages/obonode/obojobo-chunks-heading/package.json +++ b/packages/obonode/obojobo-chunks-heading/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-heading", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Heading content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-html/package.json b/packages/obonode/obojobo-chunks-html/package.json index 28dd822dae..656f2198e4 100644 --- a/packages/obonode/obojobo-chunks-html/package.json +++ b/packages/obonode/obojobo-chunks-html/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-html", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "HTML content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-iframe/package.json b/packages/obonode/obojobo-chunks-iframe/package.json index 0dcb9821e2..31738d98e7 100644 --- a/packages/obonode/obojobo-chunks-iframe/package.json +++ b/packages/obonode/obojobo-chunks-iframe/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-iframe", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "IFrame content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-list/package.json b/packages/obonode/obojobo-chunks-list/package.json index 7c54b93bfe..df92a3c006 100644 --- a/packages/obonode/obojobo-chunks-list/package.json +++ b/packages/obonode/obojobo-chunks-list/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-list", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "List content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-materia/package.json b/packages/obonode/obojobo-chunks-materia/package.json index 5bde3aea95..e1f5dc0fde 100644 --- a/packages/obonode/obojobo-chunks-materia/package.json +++ b/packages/obonode/obojobo-chunks-materia/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-materia", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Materia content chunk for Obojobo", "scripts": { @@ -35,9 +35,9 @@ "lint-staged": "^10.5.4" }, "peerDependencies": { - "obojobo-chunks-iframe": "^17.0.0-alpha.1", - "obojobo-document-engine": "^17.0.0-alpha.1", - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-chunks-iframe": "^17.0.0", + "obojobo-document-engine": "^17.0.0", + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-math-equation/package.json b/packages/obonode/obojobo-chunks-math-equation/package.json index a593c3ef63..098fe4ed1b 100644 --- a/packages/obonode/obojobo-chunks-math-equation/package.json +++ b/packages/obonode/obojobo-chunks-math-equation/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-math-equation", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "MathEquation content chunk for Obojobo", "scripts": { @@ -30,7 +30,7 @@ "katex": "^0.13.1" }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json b/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json index 59801c1955..d2dc7c845d 100644 --- a/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json +++ b/packages/obonode/obojobo-chunks-multiple-choice-assessment/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-multiple-choice-assessment", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "MCAssessment chunk for Obojobo", "scripts": { @@ -27,8 +27,8 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-chunks-question": "^17.0.0-alpha.1", - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-chunks-question": "^17.0.0", + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-numeric-assessment/package.json b/packages/obonode/obojobo-chunks-numeric-assessment/package.json index 2c94ab37cf..7326fa972a 100644 --- a/packages/obonode/obojobo-chunks-numeric-assessment/package.json +++ b/packages/obonode/obojobo-chunks-numeric-assessment/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-numeric-assessment", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "NumericAssessment chunk for Obojobo", "scripts": { @@ -30,8 +30,8 @@ "big.js": "^6.1.1" }, "peerDependencies": { - "obojobo-chunks-question": "^17.0.0-alpha.1", - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-chunks-question": "^17.0.0", + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-question-bank/package.json b/packages/obonode/obojobo-chunks-question-bank/package.json index 150409bcca..42e275a02b 100644 --- a/packages/obonode/obojobo-chunks-question-bank/package.json +++ b/packages/obonode/obojobo-chunks-question-bank/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-question-bank", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "QuestionBank chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-question/package.json b/packages/obonode/obojobo-chunks-question/package.json index 05f50646c5..cc18cfd8ae 100644 --- a/packages/obonode/obojobo-chunks-question/package.json +++ b/packages/obonode/obojobo-chunks-question/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-question", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Question content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-table/package.json b/packages/obonode/obojobo-chunks-table/package.json index 52fa185650..f908b95153 100644 --- a/packages/obonode/obojobo-chunks-table/package.json +++ b/packages/obonode/obojobo-chunks-table/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-table", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Table content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-text/package.json b/packages/obonode/obojobo-chunks-text/package.json index 80d3ba32db..ce44221daa 100644 --- a/packages/obonode/obojobo-chunks-text/package.json +++ b/packages/obonode/obojobo-chunks-text/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-text", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Text content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-chunks-youtube/package.json b/packages/obonode/obojobo-chunks-youtube/package.json index 6fc20676b9..a9980db228 100644 --- a/packages/obonode/obojobo-chunks-youtube/package.json +++ b/packages/obonode/obojobo-chunks-youtube/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-chunks-youtube", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Youtube content chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-modules-module/package.json b/packages/obonode/obojobo-modules-module/package.json index 402518ca72..81502c46f4 100644 --- a/packages/obonode/obojobo-modules-module/package.json +++ b/packages/obonode/obojobo-modules-module/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-modules-module", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Default Module node for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-pages-page/package.json b/packages/obonode/obojobo-pages-page/package.json index 7d6f80ef1a..a65e66fed9 100644 --- a/packages/obonode/obojobo-pages-page/package.json +++ b/packages/obonode/obojobo-pages-page/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-pages-page", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Page chunk for Obojobo", "scripts": { @@ -27,8 +27,8 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-document-engine": "^17.0.0-alpha.1", - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-document-engine": "^17.0.0", + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-sections-assessment/package.json b/packages/obonode/obojobo-sections-assessment/package.json index 9066223171..002ccedbb7 100644 --- a/packages/obonode/obojobo-sections-assessment/package.json +++ b/packages/obonode/obojobo-sections-assessment/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-sections-assessment", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Assessment section for Obojobo", "scripts": { @@ -27,8 +27,8 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-document-engine": "^17.0.0-alpha.1", - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-document-engine": "^17.0.0", + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/obonode/obojobo-sections-content/package.json b/packages/obonode/obojobo-sections-content/package.json index 1905c5e61a..965bddbff4 100644 --- a/packages/obonode/obojobo-sections-content/package.json +++ b/packages/obonode/obojobo-sections-content/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-sections-content", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Content section chunk for Obojobo", "scripts": { @@ -27,7 +27,7 @@ "singleQuote": true }, "peerDependencies": { - "obojobo-lib-utils": "^17.0.0-alpha.1" + "obojobo-lib-utils": "^17.0.0" }, "jest": { "testMatch": [ diff --git a/packages/util/eslint-config-obojobo/package.json b/packages/util/eslint-config-obojobo/package.json index 603ba3af49..6e813cffc1 100644 --- a/packages/util/eslint-config-obojobo/package.json +++ b/packages/util/eslint-config-obojobo/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-obojobo", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "scripts": { "lint": "echo 'not implemented'", diff --git a/packages/util/obojobo-lib-utils/package.json b/packages/util/obojobo-lib-utils/package.json index ac15c263c0..b6f5ddd8bc 100644 --- a/packages/util/obojobo-lib-utils/package.json +++ b/packages/util/obojobo-lib-utils/package.json @@ -1,6 +1,6 @@ { "name": "obojobo-lib-utils", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "description": "Assortment of reusable parts for obojobo libraries.", "scripts": { diff --git a/packages/util/stylelint-config-obojobo/package.json b/packages/util/stylelint-config-obojobo/package.json index f8aac2441c..76efdb2cd8 100644 --- a/packages/util/stylelint-config-obojobo/package.json +++ b/packages/util/stylelint-config-obojobo/package.json @@ -1,6 +1,6 @@ { "name": "stylelint-config-obojobo", - "version": "17.0.0-alpha.1", + "version": "17.0.0", "license": "AGPL-3.0-only", "scripts": { "lint": "echo 'not implemented'",