From 147dc6256ddd861f30238cca1559ff7d1644dbd1 Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Fri, 3 Jun 2022 15:21:23 -0700 Subject: [PATCH 01/16] Moved package selectors and version pickers To be consistent with DebianSelector and DebianVersionPicker Test cases: -tested package searching for all affected providers in the harvest page. -SourcePicker (using GitHubSelector and GitHubCommitPicker) is also tested via definition page (http://localhost:3000/definitions/pod/cocoapods/-/SoftButton/0.1.0) by editting Described.Source. --- .../Selectors}/CocoaPodsSelector.js | 4 +-- .../Selectors}/ComposerSelector.js | 4 +-- .../Selectors}/CrateSelector.js | 4 +-- .../Selectors}/GitHubSelector.js | 4 +-- .../Selectors}/MavenSelector.js | 4 +-- .../{ => Providers/Selectors}/NpmSelector.js | 4 +-- .../Selectors}/NuGetSelector.js | 4 +-- .../{ => Providers/Selectors}/PyPiSelector.js | 4 +-- .../Selectors}/RubyGemsSelector.js | 4 +-- .../VersionPickers}/CocoaPodsVersionPicker.js | 6 ++-- .../VersionPickers}/ComposerVersionPicker.js | 6 ++-- .../VersionPickers}/CrateVersionPicker.js | 6 ++-- .../VersionPickers}/GitHubCommitPicker.js | 4 +-- .../VersionPickers}/MavenVersionPicker.js | 6 ++-- .../VersionPickers}/NpmVersionPicker.js | 6 ++-- .../VersionPickers}/NuGetVersionPicker.js | 6 ++-- .../VersionPickers}/PyPiVersionPicker.js | 6 ++-- .../VersionPickers}/RubyGemsVersionPicker.js | 6 ++-- src/components/index.js | 36 +++++++++---------- 19 files changed, 62 insertions(+), 62 deletions(-) rename src/components/{ => Providers/Selectors}/CocoaPodsSelector.js (94%) rename src/components/{ => Providers/Selectors}/ComposerSelector.js (94%) rename src/components/{ => Providers/Selectors}/CrateSelector.js (94%) rename src/components/{ => Providers/Selectors}/GitHubSelector.js (97%) rename src/components/{ => Providers/Selectors}/MavenSelector.js (95%) rename src/components/{ => Providers/Selectors}/NpmSelector.js (94%) rename src/components/{ => Providers/Selectors}/NuGetSelector.js (94%) rename src/components/{ => Providers/Selectors}/PyPiSelector.js (94%) rename src/components/{ => Providers/Selectors}/RubyGemsSelector.js (94%) rename src/components/{ => Providers/VersionPickers}/CocoaPodsVersionPicker.js (93%) rename src/components/{ => Providers/VersionPickers}/ComposerVersionPicker.js (93%) rename src/components/{ => Providers/VersionPickers}/CrateVersionPicker.js (92%) rename src/components/{ => Providers/VersionPickers}/GitHubCommitPicker.js (97%) rename src/components/{ => Providers/VersionPickers}/MavenVersionPicker.js (93%) rename src/components/{ => Providers/VersionPickers}/NpmVersionPicker.js (93%) rename src/components/{ => Providers/VersionPickers}/NuGetVersionPicker.js (93%) rename src/components/{ => Providers/VersionPickers}/PyPiVersionPicker.js (93%) rename src/components/{ => Providers/VersionPickers}/RubyGemsVersionPicker.js (93%) diff --git a/src/components/CocoaPodsSelector.js b/src/components/Providers/Selectors/CocoaPodsSelector.js similarity index 94% rename from src/components/CocoaPodsSelector.js rename to src/components/Providers/Selectors/CocoaPodsSelector.js index ca1bb6f31..0a863172b 100644 --- a/src/components/CocoaPodsSelector.js +++ b/src/components/Providers/Selectors/CocoaPodsSelector.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getCocoaPodsSearch } from '../api/clearlyDefined' +import { getCocoaPodsSearch } from '../../../api/clearlyDefined' import { AsyncTypeahead } from 'react-bootstrap-typeahead' -import searchSvg from '../images/icons/searchSvg.svg' +import searchSvg from '../../../images/icons/searchSvg.svg' import 'react-bootstrap-typeahead/css/Typeahead.css' export default class CocoaPodsSelector extends Component { diff --git a/src/components/ComposerSelector.js b/src/components/Providers/Selectors/ComposerSelector.js similarity index 94% rename from src/components/ComposerSelector.js rename to src/components/Providers/Selectors/ComposerSelector.js index f2d48ce54..9aa8af3e0 100644 --- a/src/components/ComposerSelector.js +++ b/src/components/Providers/Selectors/ComposerSelector.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getComposerSearch } from '../api/clearlyDefined' +import { getComposerSearch } from '../../../api/clearlyDefined' import { AsyncTypeahead } from 'react-bootstrap-typeahead' -import searchSvg from '../images/icons/searchSvg.svg' +import searchSvg from '../../../images/icons/searchSvg.svg' export default class ComposerSelector extends Component { static propTypes = { diff --git a/src/components/CrateSelector.js b/src/components/Providers/Selectors/CrateSelector.js similarity index 94% rename from src/components/CrateSelector.js rename to src/components/Providers/Selectors/CrateSelector.js index 33635e79e..a5ab93e50 100644 --- a/src/components/CrateSelector.js +++ b/src/components/Providers/Selectors/CrateSelector.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getCrateSearch } from '../api/clearlyDefined' +import { getCrateSearch } from '../../../api/clearlyDefined' import { AsyncTypeahead } from 'react-bootstrap-typeahead' -import searchSvg from '../images/icons/searchSvg.svg' +import searchSvg from '../../../images/icons/searchSvg.svg' export default class CrateSelector extends Component { static propTypes = { diff --git a/src/components/GitHubSelector.js b/src/components/Providers/Selectors/GitHubSelector.js similarity index 97% rename from src/components/GitHubSelector.js rename to src/components/Providers/Selectors/GitHubSelector.js index a1d2bd8f7..3b480ca3f 100644 --- a/src/components/GitHubSelector.js +++ b/src/components/Providers/Selectors/GitHubSelector.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getGitHubSearch } from '../api/clearlyDefined' +import { getGitHubSearch } from '../../../api/clearlyDefined' import { AsyncTypeahead } from 'react-bootstrap-typeahead' -import searchSvg from '../images/icons/searchSvg.svg' +import searchSvg from '../../../images/icons/searchSvg.svg' import 'react-bootstrap-typeahead/css/Typeahead.css' export default class GitHubSelector extends Component { diff --git a/src/components/MavenSelector.js b/src/components/Providers/Selectors/MavenSelector.js similarity index 95% rename from src/components/MavenSelector.js rename to src/components/Providers/Selectors/MavenSelector.js index 79df96e16..32e5e8356 100644 --- a/src/components/MavenSelector.js +++ b/src/components/Providers/Selectors/MavenSelector.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getMavenSearch } from '../api/clearlyDefined' +import { getMavenSearch } from '../../../api/clearlyDefined' import { AsyncTypeahead } from 'react-bootstrap-typeahead' -import searchSvg from '../images/icons/searchSvg.svg' +import searchSvg from '../../../images/icons/searchSvg.svg' import 'react-bootstrap-typeahead/css/Typeahead.css' export default class MavenSelector extends Component { diff --git a/src/components/NpmSelector.js b/src/components/Providers/Selectors/NpmSelector.js similarity index 94% rename from src/components/NpmSelector.js rename to src/components/Providers/Selectors/NpmSelector.js index 4a503066d..b8612984e 100644 --- a/src/components/NpmSelector.js +++ b/src/components/Providers/Selectors/NpmSelector.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getNpmSearch } from '../api/clearlyDefined' +import { getNpmSearch } from '../../../api/clearlyDefined' import { AsyncTypeahead } from 'react-bootstrap-typeahead' -import searchSvg from '../images/icons/searchSvg.svg' +import searchSvg from '../../../images/icons/searchSvg.svg' import 'react-bootstrap-typeahead/css/Typeahead.css' export default class NpmSelector extends Component { diff --git a/src/components/NuGetSelector.js b/src/components/Providers/Selectors/NuGetSelector.js similarity index 94% rename from src/components/NuGetSelector.js rename to src/components/Providers/Selectors/NuGetSelector.js index d84a6fe75..dae42b460 100644 --- a/src/components/NuGetSelector.js +++ b/src/components/Providers/Selectors/NuGetSelector.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getNugetSearch } from '../api/clearlyDefined' +import { getNugetSearch } from '../../../api/clearlyDefined' import { AsyncTypeahead } from 'react-bootstrap-typeahead' -import searchSvg from '../images/icons/searchSvg.svg' +import searchSvg from '../../../images/icons/searchSvg.svg' export default class NuGetSelector extends Component { static propTypes = { diff --git a/src/components/PyPiSelector.js b/src/components/Providers/Selectors/PyPiSelector.js similarity index 94% rename from src/components/PyPiSelector.js rename to src/components/Providers/Selectors/PyPiSelector.js index 28c81dac8..2a89e3965 100644 --- a/src/components/PyPiSelector.js +++ b/src/components/Providers/Selectors/PyPiSelector.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getPyPiSearch } from '../api/clearlyDefined' +import { getPyPiSearch } from '../../../api/clearlyDefined' import { AsyncTypeahead } from 'react-bootstrap-typeahead' -import searchSvg from '../images/icons/searchSvg.svg' +import searchSvg from '../../../images/icons/searchSvg.svg' import 'react-bootstrap-typeahead/css/Typeahead.css' export default class PyPiSelector extends Component { diff --git a/src/components/RubyGemsSelector.js b/src/components/Providers/Selectors/RubyGemsSelector.js similarity index 94% rename from src/components/RubyGemsSelector.js rename to src/components/Providers/Selectors/RubyGemsSelector.js index 7ea08a0cb..0cd453ff6 100644 --- a/src/components/RubyGemsSelector.js +++ b/src/components/Providers/Selectors/RubyGemsSelector.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getRubyGemsSearch } from '../api/clearlyDefined' +import { getRubyGemsSearch } from '../../../api/clearlyDefined' import { AsyncTypeahead } from 'react-bootstrap-typeahead' -import searchSvg from '../images/icons/searchSvg.svg' +import searchSvg from '../../../images/icons/searchSvg.svg' import 'react-bootstrap-typeahead/css/Typeahead.css' export default class RubyGemsSelector extends Component { diff --git a/src/components/CocoaPodsVersionPicker.js b/src/components/Providers/VersionPickers/CocoaPodsVersionPicker.js similarity index 93% rename from src/components/CocoaPodsVersionPicker.js rename to src/components/Providers/VersionPickers/CocoaPodsVersionPicker.js index 4b0836df5..8792d0297 100644 --- a/src/components/CocoaPodsVersionPicker.js +++ b/src/components/Providers/VersionPickers/CocoaPodsVersionPicker.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getCocoaPodsRevisions } from '../api/clearlyDefined' -import Autocomplete from './Navigation/Ui/Autocomplete' -import searchSvg from '../images/icons/searchSvg.svg' +import { getCocoaPodsRevisions } from '../../../api/clearlyDefined' +import Autocomplete from '../../Navigation/Ui/Autocomplete' +import searchSvg from '../../../images/icons/searchSvg.svg' export default class CocoaPodsVersionPicker extends Component { static propTypes = { diff --git a/src/components/ComposerVersionPicker.js b/src/components/Providers/VersionPickers/ComposerVersionPicker.js similarity index 93% rename from src/components/ComposerVersionPicker.js rename to src/components/Providers/VersionPickers/ComposerVersionPicker.js index 74f7b95d0..28ffbfcf8 100644 --- a/src/components/ComposerVersionPicker.js +++ b/src/components/Providers/VersionPickers/ComposerVersionPicker.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getComposerRevisions } from '../api/clearlyDefined' -import Autocomplete from './Navigation/Ui/Autocomplete' -import searchSvg from '../images/icons/searchSvg.svg' +import { getComposerRevisions } from '../../../api/clearlyDefined' +import Autocomplete from '../../Navigation/Ui/Autocomplete' +import searchSvg from '../../../images/icons/searchSvg.svg' export default class ComposerVersionPicker extends Component { static propTypes = { diff --git a/src/components/CrateVersionPicker.js b/src/components/Providers/VersionPickers/CrateVersionPicker.js similarity index 92% rename from src/components/CrateVersionPicker.js rename to src/components/Providers/VersionPickers/CrateVersionPicker.js index 2bdfa2130..c9f1eb114 100644 --- a/src/components/CrateVersionPicker.js +++ b/src/components/Providers/VersionPickers/CrateVersionPicker.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getCrateRevisions } from '../api/clearlyDefined' -import Autocomplete from './Navigation/Ui/Autocomplete' -import searchSvg from '../images/icons/searchSvg.svg' +import { getCrateRevisions } from '../../../api/clearlyDefined' +import Autocomplete from '../../Navigation/Ui/Autocomplete' +import searchSvg from '../../../images/icons/searchSvg.svg' export default class CrateVersionPicker extends Component { static propTypes = { diff --git a/src/components/GitHubCommitPicker.js b/src/components/Providers/VersionPickers/GitHubCommitPicker.js similarity index 97% rename from src/components/GitHubCommitPicker.js rename to src/components/Providers/VersionPickers/GitHubCommitPicker.js index e82cff624..c97146e7a 100644 --- a/src/components/GitHubCommitPicker.js +++ b/src/components/Providers/VersionPickers/GitHubCommitPicker.js @@ -4,8 +4,8 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { Highlighter } from 'react-bootstrap-typeahead' -import searchSvg from '../images/icons/searchSvg.svg' -import Autocomplete from './Navigation/Ui/Autocomplete' +import searchSvg from '../../../images/icons/searchSvg.svg' +import Autocomplete from '../../Navigation/Ui/Autocomplete' export default class GitHubCommitPicker extends Component { static propTypes = { diff --git a/src/components/MavenVersionPicker.js b/src/components/Providers/VersionPickers/MavenVersionPicker.js similarity index 93% rename from src/components/MavenVersionPicker.js rename to src/components/Providers/VersionPickers/MavenVersionPicker.js index 55c2a372d..aa06675e2 100644 --- a/src/components/MavenVersionPicker.js +++ b/src/components/Providers/VersionPickers/MavenVersionPicker.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getMavenRevisions } from '../api/clearlyDefined' -import Autocomplete from './Navigation/Ui/Autocomplete' -import searchSvg from '../images/icons/searchSvg.svg' +import { getMavenRevisions } from '../../../api/clearlyDefined' +import Autocomplete from '../../Navigation/Ui/Autocomplete' +import searchSvg from '../../../images/icons/searchSvg.svg' export default class MavenVersionPicker extends Component { static propTypes = { diff --git a/src/components/NpmVersionPicker.js b/src/components/Providers/VersionPickers/NpmVersionPicker.js similarity index 93% rename from src/components/NpmVersionPicker.js rename to src/components/Providers/VersionPickers/NpmVersionPicker.js index 3c4f5cd47..b417d1449 100644 --- a/src/components/NpmVersionPicker.js +++ b/src/components/Providers/VersionPickers/NpmVersionPicker.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getNpmRevisions } from '../api/clearlyDefined' -import Autocomplete from './Navigation/Ui/Autocomplete' -import searchSvg from '../images/icons/searchSvg.svg' +import { getNpmRevisions } from '../../../api/clearlyDefined' +import Autocomplete from '../../Navigation/Ui/Autocomplete' +import searchSvg from '../../../images/icons/searchSvg.svg' export default class NpmVersionPicker extends Component { static propTypes = { diff --git a/src/components/NuGetVersionPicker.js b/src/components/Providers/VersionPickers/NuGetVersionPicker.js similarity index 93% rename from src/components/NuGetVersionPicker.js rename to src/components/Providers/VersionPickers/NuGetVersionPicker.js index edf0b8908..58ba6e3d9 100644 --- a/src/components/NuGetVersionPicker.js +++ b/src/components/Providers/VersionPickers/NuGetVersionPicker.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getNugetRevisions } from '../api/clearlyDefined' -import Autocomplete from './Navigation/Ui/Autocomplete' -import searchSvg from '../images/icons/searchSvg.svg' +import { getNugetRevisions } from '../../../api/clearlyDefined' +import Autocomplete from '../../Navigation/Ui/Autocomplete' +import searchSvg from '../../../images/icons/searchSvg.svg' export default class NuGetVersionPicker extends Component { static propTypes = { diff --git a/src/components/PyPiVersionPicker.js b/src/components/Providers/VersionPickers/PyPiVersionPicker.js similarity index 93% rename from src/components/PyPiVersionPicker.js rename to src/components/Providers/VersionPickers/PyPiVersionPicker.js index 33bbefb89..b147e095a 100644 --- a/src/components/PyPiVersionPicker.js +++ b/src/components/Providers/VersionPickers/PyPiVersionPicker.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getPyPiRevisions } from '../api/clearlyDefined' -import Autocomplete from './Navigation/Ui/Autocomplete' -import searchSvg from '../images/icons/searchSvg.svg' +import { getPyPiRevisions } from '../../../api/clearlyDefined' +import Autocomplete from '../../Navigation/Ui/Autocomplete' +import searchSvg from '../../../images/icons/searchSvg.svg' export default class PyPiVersionPicker extends Component { static propTypes = { diff --git a/src/components/RubyGemsVersionPicker.js b/src/components/Providers/VersionPickers/RubyGemsVersionPicker.js similarity index 93% rename from src/components/RubyGemsVersionPicker.js rename to src/components/Providers/VersionPickers/RubyGemsVersionPicker.js index 88e57dbe7..249e9eb90 100644 --- a/src/components/RubyGemsVersionPicker.js +++ b/src/components/Providers/VersionPickers/RubyGemsVersionPicker.js @@ -3,9 +3,9 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { getRubyGemsRevisions } from '../api/clearlyDefined' -import Autocomplete from './Navigation/Ui/Autocomplete' -import searchSvg from '../images/icons/searchSvg.svg' +import { getRubyGemsRevisions } from '../../../api/clearlyDefined' +import Autocomplete from '../../Navigation/Ui/Autocomplete' +import searchSvg from '../../../images/icons/searchSvg.svg' export default class RubyGemsVersionPicker extends Component { static propTypes = { diff --git a/src/components/index.js b/src/components/index.js index 7f192105c..d4bd01362 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -12,17 +12,17 @@ from './ContributePrompt' export { default as CopyUrlButton } from './CopyUrlButton' export { default as CrateSelector } -from './CrateSelector' +from './Providers/Selectors/CrateSelector' export { default as CrateVersionPicker } -from './CrateVersionPicker' +from './Providers/VersionPickers/CrateVersionPicker' export { default as DebianSelector } from './Providers/Selectors/DebianSelector' export { default as DebianVersionPicker } from './Providers/VersionPickers/DebianVersionPicker' export { default as ComposerSelector } -from './ComposerSelector' +from './Providers/Selectors/ComposerSelector' export { default as ComposerVersionPicker } -from './ComposerVersionPicker' +from './Providers/VersionPickers/ComposerVersionPicker' export { default as DefinitionEntry } from './DefinitionEntry' export { default as FieldGroup } @@ -34,9 +34,9 @@ from './FilterBar' export { default as Footer } from './Footer' export { default as GitHubCommitPicker } -from './GitHubCommitPicker' +from './Providers/VersionPickers/GitHubCommitPicker' export { default as GitHubSelector } -from './GitHubSelector' +from './Providers/Selectors/GitHubSelector' export { default as HarvestQueueList } from './HarvestQueueList' export { default as Header } @@ -50,31 +50,31 @@ from './ModalEditor' export { default as SourcePicker } from './SourcePicker' export { default as MavenSelector } -from './MavenSelector' +from './Providers/Selectors/MavenSelector' export { default as MavenVersionPicker } -from './MavenVersionPicker' +from './Providers/VersionPickers/MavenVersionPicker' export { default as NotificationList } from './NotificationList' export { default as NpmSelector } -from './NpmSelector' +from './Providers/Selectors/NpmSelector' export { default as NpmVersionPicker } -from './NpmVersionPicker' +from './Providers/VersionPickers/NpmVersionPicker' export { default as NuGetSelector } -from './NuGetSelector' +from './Providers/Selectors/NuGetSelector' export { default as NuGetVersionPicker } -from './NuGetVersionPicker' +from './Providers/VersionPickers/NuGetVersionPicker' export { default as PyPiSelector } -from './PyPiSelector' +from './Providers/Selectors/PyPiSelector' export { default as PyPiVersionPicker } -from './PyPiVersionPicker' +from './Providers/VersionPickers/PyPiVersionPicker' export { default as RubyGemsSelector } -from './RubyGemsSelector' +from './Providers/Selectors/RubyGemsSelector' export { default as RubyGemsVersionPicker } -from './RubyGemsVersionPicker' +from './Providers/VersionPickers/RubyGemsVersionPicker' export { default as CocoaPodsSelector } -from './CocoaPodsSelector' +from './Providers/Selectors/CocoaPodsSelector' export { default as CocoaPodsVersionPicker } -from './CocoaPodsVersionPicker' +from './Providers/VersionPickers/CocoaPodsVersionPicker' export { default as PageAbout } from './PageAbout' export { default as RehydrationProvider } From ad14952398d8fb9e45f0925e034f6709de24806c Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Fri, 10 Jun 2022 08:41:40 -0700 Subject: [PATCH 02/16] Allow editing declared license and release date in Quick Edit -add handleSaveEdit -display the changes correctly with original values in tool tip Task: https://github.com/clearlydefined/website/issues/956 --- src/components/DefinitionEntry.js | 85 +++++++++++-------- .../{QuickEditModel.jsx => QuickEditModel.js} | 49 ++++++++--- src/styles/_Popover.scss | 2 +- 3 files changed, 90 insertions(+), 46 deletions(-) rename src/components/{QuickEditModel.jsx => QuickEditModel.js} (67%) diff --git a/src/components/DefinitionEntry.js b/src/components/DefinitionEntry.js index bc24e603a..11e5c8e58 100644 --- a/src/components/DefinitionEntry.js +++ b/src/components/DefinitionEntry.js @@ -90,10 +90,10 @@ class DefinitionEntry extends React.Component { ) : null - const releasedDate = definition?.described?.releaseDate ? ( - {definition.described.releaseDate} - ) : ( - -- -- -- + const releasedDate = ( + + {this.renderFieldWithToolTipIfDifferent('described.releaseDate', a => a || '-- -- --')} + ) const curationTag = isCurationPending ? ( @@ -125,7 +125,7 @@ class DefinitionEntry extends React.Component { renderWithToolTipIfDifferent(field, content, placement = 'right', transform = x => x) { const toolTip = ( - Original: {transform(get(this.props.otherDefinition, field))} + Original: {transform(this.getOriginalValue(field))} ) return this.ifDifferent( @@ -137,14 +137,19 @@ class DefinitionEntry extends React.Component { ) } + renderFieldWithToolTipIfDifferent(field, transform = a => a) { + const displayValue = transform(this.getValue(field)) + return this.renderWithToolTipIfDifferent( + field, + {displayValue}, + undefined, + transform + ) + } + renderMessage(definition) { const licenseExpression = definition ? this.getValue('licensed.declared') : null - return licenseExpression - ? this.renderWithToolTipIfDifferent( - 'licensed.declared', - {licenseExpression} - ) - : null + return licenseExpression ? this.renderFieldWithToolTipIfDifferent('licensed.declared') : null } getPercentage(count, total) { @@ -190,6 +195,30 @@ class DefinitionEntry extends React.Component { this.setState({ modelOpen: !this.state.modelOpen }) } + handleSaveEdit = updates => { + const { onChange, definition, component } = this.props + + const newChanges = Object.entries(updates).reduce((changes, [key, value]) => { + if (key === 'declared') return Contribution.applyChanges(definition, changes, 'licensed.declared', value) + if (key === 'source') + return Contribution.applyChanges( + definition, + changes, + 'described.sourceLocation', + value, + undefined, + Contribution.toSourceLocation + ) + if (key === 'release') return Contribution.applyChanges(definition, changes, 'described.releaseDate', value) + return changes + }, {}) + + if (Object.keys(newChanges).length !== 0) { + const combinedChanges = { ...component.changes, ...newChanges } + onChange && onChange(component, combinedChanges) + } + } + renderPanel(rawDefinition) { if (!rawDefinition) return ( @@ -201,13 +230,12 @@ class DefinitionEntry extends React.Component { // TODO: find a way of calling this method less frequently. It's relatively expensive. const definition = this.foldFacets(rawDefinition, this.props.activeFacets) const { licensed } = definition - const { readOnly, onRevert } = this.props return (
{this.renderLabel('Declared')}:
-

{this.getValue('licensed.declared')}

+ {this.renderFieldWithToolTipIfDifferent('licensed.declared')} {/* {this.renderWithToolTipIfDifferent( 'licensed.declared', {this.renderLabel('Source')}:
-

{Contribution.printCoordinates(this.getValue('described.sourceLocation'))}

+ {this.renderFieldWithToolTipIfDifferent('described.sourceLocation', a => Contribution.printCoordinates(a))} {/* {this.renderWithToolTipIfDifferent( 'described.sourceLocation', {this.renderLabel('Release')}:
-

{Contribution.printDate(this.getValue('described.releaseDate'))}

+ {this.renderFieldWithToolTipIfDifferent( + 'described.releaseDate', + a => Contribution.printDate(a) || '-- -- --' + )} {/* {this.renderWithToolTipIfDifferent( 'described.releaseDate', true} - placeholder={'Source location'} - revertable - onRevert={() => onRevert('described.sourceLocation')} /> -
@@ -83,4 +105,11 @@ const QuickEditModel = props => { ) } +QuickEditModel.propsType = { + open: PropTypes.bool.isRequired, + closeModel: PropTypes.func.isRequired, + initialValues: PropTypes.object.isRequired, + onSave: PropTypes.object.isRequired +} + export default QuickEditModel diff --git a/src/styles/_Popover.scss b/src/styles/_Popover.scss index c10df30b2..ca7a2b8ec 100644 --- a/src/styles/_Popover.scss +++ b/src/styles/_Popover.scss @@ -219,7 +219,7 @@ button.modal__btn--secondary, } } - +.fade.in.definition__tooltip.tooltip, .fade.in.modal { opacity: 1 !important; } \ No newline at end of file From b61e63d61bfd9833210417b659a876a9e5bcc0a8 Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Thu, 9 Jun 2022 09:08:50 -0700 Subject: [PATCH 03/16] Refactor SourcePicker -SourceLocationPicker is the presentation UI -SourcePicker is the container, containing the state and on change handlers --- src/components/SourceLocationPicker.js | 86 ++++++++++++++++++++++++++ src/components/SourcePicker.js | 75 ++++++---------------- 2 files changed, 105 insertions(+), 56 deletions(-) create mode 100644 src/components/SourceLocationPicker.js diff --git a/src/components/SourceLocationPicker.js b/src/components/SourceLocationPicker.js new file mode 100644 index 000000000..bdce41044 --- /dev/null +++ b/src/components/SourceLocationPicker.js @@ -0,0 +1,86 @@ +// Copyright (c) Codescoop Oy and others. Licensed under the MIT license. +// SPDX-License-Identifier: MIT + +import React, { Component } from 'react' +import { Button, ButtonGroup } from 'react-bootstrap' +import { GitHubSelector, GitHubCommitPicker } from './' +import { getGitHubRevisions } from '../api/clearlyDefined' +import EntitySpec from '../utils/entitySpec' +import { clone } from 'lodash' +import { PropTypes } from 'prop-types' + +class SourceLocationPicker extends Component { + constructor(props) { + super(props) + this.state = { activeProvider: 'github' } + this.onSelectComponent = this.onSelectComponent.bind(this) + this.onProviderClick = this.onProviderClick.bind(this) + } + + static propTypes = { + token: PropTypes.string, + value: PropTypes.string, + selectedComponent: PropTypes.object, + onChangeComponent: PropTypes.func.isRequired + } + + onSelectComponent(value, tool) { + const { onChangeComponent } = this.props + const [namespace, name] = value.name.split('/') + const component = new EntitySpec(value.type, value.provider, namespace, name) + component.tool = tool + onChangeComponent(component) + } + + onProviderClick(event) { + const activeProvider = event.target.name + this.setState({ activeProvider }) + } + + renderProviderButtons() { + const { activeProvider } = this.state + return ( + + + + ) + } + + commitChanged(component, value) { + const { onChangeComponent } = this.props + const newComponent = clone(component) + newComponent.revision = value ? value.sha : null + onChangeComponent(newComponent) + } + + render() { + const { activeProvider } = this.state + const { token, selectedComponent, value } = this.props + + return ( + <> +
{this.renderProviderButtons()}
+
{activeProvider === 'github' && }
+
+ {selectedComponent && activeProvider === 'github' && ( + getGitHubRevisions(token, path)} + onChange={this.commitChanged.bind(this, selectedComponent)} + /> + )} +
+ + + ) + } +} + +export default SourceLocationPicker diff --git a/src/components/SourcePicker.js b/src/components/SourcePicker.js index 5111a45ea..6f6a580af 100644 --- a/src/components/SourcePicker.js +++ b/src/components/SourcePicker.js @@ -3,48 +3,28 @@ import React, { Component } from 'react' import { connect } from 'react-redux' -import { Grid, Button, ButtonGroup, FormGroup } from 'react-bootstrap' -import { GitHubSelector, GitHubCommitPicker } from './' -import { getGitHubRevisions } from '../api/clearlyDefined' -import EntitySpec from '../utils/entitySpec' -import { clone } from 'lodash' +import { Grid, Button, FormGroup } from 'react-bootstrap' +import SourceLocationPicker from './SourceLocationPicker' +import { PropTypes } from 'prop-types' class SourcePicker extends Component { constructor(props) { super(props) - this.state = { activeProvider: 'github' } - this.onSelectComponent = this.onSelectComponent.bind(this) + this.state = {} this.onChangeComponent = this.onChangeComponent.bind(this) - this.onClick = this.onClick.bind(this) } - onSelectComponent(value, tool) { - const [namespace, name] = value.name.split('/') - const component = new EntitySpec(value.type, value.provider, namespace, name) - component.tool = tool - this.setState({ selectedComponent: component }) + static propTypes = { + token: PropTypes.string, + value: PropTypes.string, + onChange: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired } - onChangeComponent(component, newComponent) { + onChangeComponent(newComponent) { this.setState({ selectedComponent: newComponent }) } - onClick(event) { - const activeProvider = event.target.name - this.setState({ activeProvider }) - } - - renderProviderButtons() { - const { activeProvider } = this.state - return ( - - - - ) - } - renderActionButton() { const { onChange, onClose } = this.props return ( @@ -60,35 +40,18 @@ class SourcePicker extends Component { ) } - commitChanged(component, value) { - const newComponent = clone(component) - newComponent.revision = value ? value.sha : null - this.onChangeComponent(component, newComponent) - } - render() { - const { activeProvider, selectedComponent } = this.state - const { value } = this.props + const { selectedComponent } = this.state + const { value, token } = this.props return ( -
{this.renderProviderButtons()}
-
{activeProvider === 'github' && }
-
- {selectedComponent && activeProvider === 'github' && ( - getGitHubRevisions(this.props.token, path)} - onChange={this.commitChanged.bind(this, selectedComponent)} - /> - )} -
- + + {this.renderActionButton()}
) } From fbdbe94433299a4fee7236a7ec3f613aa6ba4ead Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Fri, 10 Jun 2022 09:58:04 -0700 Subject: [PATCH 04/16] Support source location edit in QuickEditModel SourceLocationPicker -sync activeProvider with props to handle display of non github source location -add an internal state of selected component. No need to pass in selected component from props (to simplify the interface with containers). Integrate SourceLocationPicker in QuickEditModel -also adjust styling so SourceLocationPicker looks ok inside QuickEditModel -support saving source location edit --- src/components/DefinitionEntry.js | 26 +++++--------- src/components/QuickEditModel.js | 49 ++++++++++++-------------- src/components/SourceLocationPicker.js | 24 +++++++++---- src/components/SourcePicker.js | 8 +---- src/styles/_FullDetailComponent.scss | 7 ++++ 5 files changed, 56 insertions(+), 58 deletions(-) diff --git a/src/components/DefinitionEntry.js b/src/components/DefinitionEntry.js index 11e5c8e58..90025cf08 100644 --- a/src/components/DefinitionEntry.js +++ b/src/components/DefinitionEntry.js @@ -3,7 +3,7 @@ import React from 'react' import PropTypes from 'prop-types' -import { TwoLineEntry, QuickEditModel, SourcePicker, FileCountRenderer } from './' +import { TwoLineEntry, QuickEditModel, FileCountRenderer } from './' import { Checkbox, OverlayTrigger, Tooltip, Popover } from 'react-bootstrap' import { Tag } from 'antd' import { get, isEqual, union } from 'lodash' @@ -199,18 +199,11 @@ class DefinitionEntry extends React.Component { const { onChange, definition, component } = this.props const newChanges = Object.entries(updates).reduce((changes, [key, value]) => { - if (key === 'declared') return Contribution.applyChanges(definition, changes, 'licensed.declared', value) - if (key === 'source') - return Contribution.applyChanges( - definition, - changes, - 'described.sourceLocation', - value, - undefined, - Contribution.toSourceLocation - ) - if (key === 'release') return Contribution.applyChanges(definition, changes, 'described.releaseDate', value) - return changes + let field + if (key === 'declared') field = 'licensed.declared' + if (key === 'sourceComponent') field = 'described.sourceLocation' + if (key === 'release') field = 'described.releaseDate' + return field ? Contribution.applyChanges(definition, changes, field, value) : changes }, {}) if (Object.keys(newChanges).length !== 0) { @@ -325,13 +318,10 @@ class DefinitionEntry extends React.Component { closeModel={this.handleModel} initialValues={{ declared: this.getValue('licensed.declared'), - source: Contribution.printCoordinates(this.getValue('described.sourceLocation')), - release: Contribution.printDate(this.getValue('described.releaseDate')), - repo: '' + sourceComponent: this.getValue('described.sourceLocation'), + release: Contribution.printDate(this.getValue('described.releaseDate')) }} onSave={this.handleSaveEdit} - //TODO hook up SourcePicker - editor={SourcePicker} //TODO validation validator={value => true} /> diff --git a/src/components/QuickEditModel.js b/src/components/QuickEditModel.js index e820e871e..2b283fc03 100644 --- a/src/components/QuickEditModel.js +++ b/src/components/QuickEditModel.js @@ -1,26 +1,32 @@ import React, { useState, useEffect } from 'react' import { PropTypes } from 'prop-types' -import { Modal, Button } from 'react-bootstrap' +import { Grid, Modal, Button } from 'react-bootstrap' import closeSvg from '../images/icons/closeSvg.svg' +import SourceLocationPicker from './SourceLocationPicker' const QuickEditModel = props => { - const { open, closeModel, onSave } = props + const { initialValues, token, open, closeModel, onSave } = props const [values, setValues] = useState({ - declared: null, - source: null, - repo: null, - release: null + declared: initialValues.declared, + release: initialValues.release }) useEffect(() => { - setValues(props.initialValues) - }, [props.initialValues]) + setValues({ + declared: initialValues.declared, + release: initialValues.release + }) + }, [initialValues]) const handleChange = ({ target }) => { setValues({ ...values, [target.id]: target.value }) } + const handleComponentChange = newComponent => { + setValues({ ...values, sourceComponent: newComponent }) + } + const handleSave = () => { closeModel() onSave(values) @@ -57,23 +63,14 @@ const QuickEditModel = props => { Source
- -     - + + +
@@ -106,7 +103,7 @@ const QuickEditModel = props => { } QuickEditModel.propsType = { - open: PropTypes.bool.isRequired, + open: PropTypes.bool, closeModel: PropTypes.func.isRequired, initialValues: PropTypes.object.isRequired, onSave: PropTypes.object.isRequired diff --git a/src/components/SourceLocationPicker.js b/src/components/SourceLocationPicker.js index bdce41044..c740827b4 100644 --- a/src/components/SourceLocationPicker.js +++ b/src/components/SourceLocationPicker.js @@ -12,23 +12,34 @@ import { PropTypes } from 'prop-types' class SourceLocationPicker extends Component { constructor(props) { super(props) - this.state = { activeProvider: 'github' } + this.state = { activeProvider: this.props.activeProvider } this.onSelectComponent = this.onSelectComponent.bind(this) + this.onChangeComponent = this.onChangeComponent.bind(this) this.onProviderClick = this.onProviderClick.bind(this) } static propTypes = { token: PropTypes.string, value: PropTypes.string, - selectedComponent: PropTypes.object, + activeProvider: PropTypes.string, onChangeComponent: PropTypes.func.isRequired } + static defaultProps = { + value: '', + activeProvider: 'github' + } + onSelectComponent(value, tool) { - const { onChangeComponent } = this.props const [namespace, name] = value.name.split('/') const component = new EntitySpec(value.type, value.provider, namespace, name) component.tool = tool + this.onChangeComponent(component) + } + + onChangeComponent(component) { + const { onChangeComponent } = this.props + this.setState({ ...this.state, selectedComponent: component }) onChangeComponent(component) } @@ -49,15 +60,14 @@ class SourceLocationPicker extends Component { } commitChanged(component, value) { - const { onChangeComponent } = this.props const newComponent = clone(component) newComponent.revision = value ? value.sha : null - onChangeComponent(newComponent) + this.onChangeComponent(newComponent) } render() { - const { activeProvider } = this.state - const { token, selectedComponent, value } = this.props + const { activeProvider, selectedComponent } = this.state + const { token, value } = this.props return ( <> diff --git a/src/components/SourcePicker.js b/src/components/SourcePicker.js index 6f6a580af..6410b574a 100644 --- a/src/components/SourcePicker.js +++ b/src/components/SourcePicker.js @@ -41,16 +41,10 @@ class SourcePicker extends Component { } render() { - const { selectedComponent } = this.state const { value, token } = this.props return ( - + {this.renderActionButton()} ) diff --git a/src/styles/_FullDetailComponent.scss b/src/styles/_FullDetailComponent.scss index 587d7b8bc..4363fedad 100644 --- a/src/styles/_FullDetailComponent.scss +++ b/src/styles/_FullDetailComponent.scss @@ -348,6 +348,13 @@ } } +#source-picker.edit.container { + padding-top: 5px; + padding-left: 0px; + padding-right: 0px; + padding-bottom: 0px; +} + .source-picker__current-source { margin: 16px 0 0; From 9d531b27a7786e90ab8ddbc27b3d2de4fcbf7078 Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Fri, 10 Jun 2022 16:14:19 -0700 Subject: [PATCH 05/16] Integrate SpdxPicker in QuickEditModel --- src/components/DefinitionEntry.js | 2 -- src/components/QuickEditModel.js | 18 ++++++++---------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/components/DefinitionEntry.js b/src/components/DefinitionEntry.js index 90025cf08..9b79dc8bc 100644 --- a/src/components/DefinitionEntry.js +++ b/src/components/DefinitionEntry.js @@ -322,8 +322,6 @@ class DefinitionEntry extends React.Component { release: Contribution.printDate(this.getValue('described.releaseDate')) }} onSave={this.handleSaveEdit} - //TODO validation - validator={value => true} />
@@ -68,7 +66,7 @@ const QuickEditModel = props => { token={token} value={initialValues.sourceComponent?.url || ''} activeProvider={initialValues.sourceComponent?.provider} - onChangeComponent={handleComponentChange} + onChangeComponent={handleSourceComponentChange} />
From bd8bcf0a161bb0b68fd2c5322b1a19b8e0c5cb8c Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Wed, 15 Jun 2022 16:39:05 -0700 Subject: [PATCH 06/16] Display ButtonBar in PageBrowse To allow contribution from the main page after editting. --- src/components/Navigation/Pages/PageBrowse/ButtonsBar.js | 8 +++++--- src/components/Navigation/Pages/PageBrowse/PageBrowse.js | 7 ++----- .../Pages/PageBrowse/__tests__/ButtonsBar.test.js | 6 ++++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/components/Navigation/Pages/PageBrowse/ButtonsBar.js b/src/components/Navigation/Pages/PageBrowse/ButtonsBar.js index 533b937d9..ff0fa8d8f 100644 --- a/src/components/Navigation/Pages/PageBrowse/ButtonsBar.js +++ b/src/components/Navigation/Pages/PageBrowse/ButtonsBar.js @@ -21,9 +21,11 @@ export default class ButtonsBar extends Component {  Revert Changes - + {toggleCollapseExpandAll && ( + + )} diff --git a/src/components/Navigation/Pages/PageBrowse/PageBrowse.js b/src/components/Navigation/Pages/PageBrowse/PageBrowse.js index 1ebb79d24..0320e720f 100644 --- a/src/components/Navigation/Pages/PageBrowse/PageBrowse.js +++ b/src/components/Navigation/Pages/PageBrowse/PageBrowse.js @@ -156,7 +156,6 @@ class PageBrowse extends SystemManagedList { this.revertAll('browse')} - toggleCollapseExpandAll={this.toggleCollapseExpandAll} doPromptContribute={this.doPromptContribute} /> ) @@ -332,10 +331,8 @@ class PageBrowse extends SystemManagedList { />
-
-
+
+
{ }) it("checks if buttons are enabled when there aren't changes", async () => { - const wrapper = await shallow() + const wrapper = await shallow() const toggleCollapseButton = wrapper.find({ children: 'Toggle Collapse' }) expect(toggleCollapseButton.exists()).toBeTruthy() const contributeButton = wrapper.find({ children: 'Contribute' }) @@ -21,7 +21,9 @@ describe('ButtonsBar', () => { }) it('checks if buttons are disabled when there are changes', async () => { - const wrapper = await shallow() + const wrapper = await shallow( + + ) const toggleCollapseButton = wrapper.find({ children: 'Toggle Collapse' }) expect(toggleCollapseButton.exists()).toBeTruthy() const contributeButton = wrapper.find({ children: 'Contribute' }) From a59247b23c0933ebbbe83806ad7de4d4b5258dfb Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Thu, 16 Jun 2022 13:04:27 -0700 Subject: [PATCH 07/16] Refactor SourcePicker related css Moved source-picker id tag to inside SourceLocationPicker The container padding related css is moved outside the #source-picker block. --- src/components/QuickEditModel.js | 21 +++++++++++---------- src/components/SourceLocationPicker.js | 6 +++--- src/components/SourcePicker.js | 2 +- src/styles/_FullDetailComponent.scss | 16 +++++++++------- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/components/QuickEditModel.js b/src/components/QuickEditModel.js index beaf31419..25d950f72 100644 --- a/src/components/QuickEditModel.js +++ b/src/components/QuickEditModel.js @@ -1,6 +1,9 @@ +// (c) Copyright 2022, SAP SE and ClearlyDefined contributors. Licensed under the MIT license. +// SPDX-License-Identifier: MIT + import React, { useState, useEffect } from 'react' import { PropTypes } from 'prop-types' -import { Grid, Modal, Button } from 'react-bootstrap' +import { Modal, Button } from 'react-bootstrap' import closeSvg from '../images/icons/closeSvg.svg' import SourceLocationPicker from './SourceLocationPicker' import SpdxPicker from './SpdxPicker' @@ -60,15 +63,13 @@ const QuickEditModel = props => { -
- - - +
+
diff --git a/src/components/SourceLocationPicker.js b/src/components/SourceLocationPicker.js index c740827b4..58fe37047 100644 --- a/src/components/SourceLocationPicker.js +++ b/src/components/SourceLocationPicker.js @@ -1,4 +1,4 @@ -// Copyright (c) Codescoop Oy and others. Licensed under the MIT license. +// (c) Copyright 2022, SAP SE and ClearlyDefined contributors. Licensed under the MIT license. // SPDX-License-Identifier: MIT import React, { Component } from 'react' @@ -70,7 +70,7 @@ class SourceLocationPicker extends Component { const { token, value } = this.props return ( - <> +
{this.renderProviderButtons()}
{activeProvider === 'github' && }
@@ -88,7 +88,7 @@ class SourceLocationPicker extends Component { {selectedComponent ? selectedComponent.url : value}
- +
) } } diff --git a/src/components/SourcePicker.js b/src/components/SourcePicker.js index 6410b574a..a2a8b5627 100644 --- a/src/components/SourcePicker.js +++ b/src/components/SourcePicker.js @@ -43,7 +43,7 @@ class SourcePicker extends Component { render() { const { value, token } = this.props return ( - + {this.renderActionButton()} diff --git a/src/styles/_FullDetailComponent.scss b/src/styles/_FullDetailComponent.scss index 4363fedad..5f278a3bb 100644 --- a/src/styles/_FullDetailComponent.scss +++ b/src/styles/_FullDetailComponent.scss @@ -317,14 +317,16 @@ } } -#source-picker { +.source-picker.main-container { padding: 24px; border-radius: 8px; @include start-at($medium) { padding: 36px; } +} +#source-picker { button[name='github'] { @include no-btn; font-weight: 600 !important; @@ -340,15 +342,15 @@ border-radius: 4px; padding: 0 14px; } +} - .form-group { - display: flex; - align-items: center; - justify-content: space-between; - } +.source-picker .form-group { + display: flex; + align-items: center; + justify-content: space-between; } -#source-picker.edit.container { +.edit #source-picker { padding-top: 5px; padding-left: 0px; padding-right: 0px; From 5fbaadcc65155709b380894a6713bdef57338ac9 Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Mon, 20 Jun 2022 14:31:19 -0700 Subject: [PATCH 08/16] DefinitionEntry.onChange is now required --- src/components/DefinitionEntry.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/DefinitionEntry.js b/src/components/DefinitionEntry.js index 9b79dc8bc..c4bd4646e 100644 --- a/src/components/DefinitionEntry.js +++ b/src/components/DefinitionEntry.js @@ -34,7 +34,7 @@ class DefinitionEntry extends React.Component { } } static propTypes = { - onChange: PropTypes.func, + onChange: PropTypes.func.isRequired, onCurate: PropTypes.func, onInspect: PropTypes.func, activeFacets: PropTypes.array, @@ -60,7 +60,7 @@ class DefinitionEntry extends React.Component { const newChanges = { ...component.changes } if (isChanged && proposedValue !== null) newChanges[field] = proposedValue else delete newChanges[field] - onChange && onChange(component, newChanges, field) + onChange(component, newChanges, field) } } @@ -208,7 +208,7 @@ class DefinitionEntry extends React.Component { if (Object.keys(newChanges).length !== 0) { const combinedChanges = { ...component.changes, ...newChanges } - onChange && onChange(component, combinedChanges) + onChange(component, combinedChanges) } } From d9975dab88752424126031f23f45b26e8a58bb66 Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Mon, 22 Aug 2022 14:17:45 -0700 Subject: [PATCH 09/16] Fix removal of event handler in ListDataRenderer --- src/components/Navigation/Ui/ListDataRenderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Navigation/Ui/ListDataRenderer.js b/src/components/Navigation/Ui/ListDataRenderer.js index 8498ef8bd..fa887d1ed 100644 --- a/src/components/Navigation/Ui/ListDataRenderer.js +++ b/src/components/Navigation/Ui/ListDataRenderer.js @@ -30,7 +30,7 @@ export default class ListDataRenderer extends Component { document.body.addEventListener('showTooltip', this.handleShowTooltip) } - componentWillMount() { + componentWillUnmount() { document.body.removeEventListener('showTooltip', this.handleShowTooltip) } From 961d890da7ab3626737d74c11285e8a6b84a1188 Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Fri, 26 Aug 2022 10:15:10 -0700 Subject: [PATCH 10/16] Fix scrolling in ComponentList 1. The height on the clearly-table-body crops the scroll bar, so scrolling cannot reach the item at the end of the list. Moved the height styling to address this. 2. There is a blank space after components in the table even when there is not enough space to display all the components. This is because renderFilterBar, passed as props from the container components (e.g. PageDefinition), is not called in ComponentList. Padding to accommodate the FilterBar is added by the parent of the ComponentList, thus leaving a blank space after the ComponentList when FilterBar is not rendered inside ComponentList. Change the spacing from padding in the section (parent) to margin of the ComponentList (child), where showing filter bar is determined. Also add the conditional formatting to control the spacing based on whether filter bar is displayed. --- src/components/ComponentList.js | 3 ++- src/styles/_App.scss | 1 - src/styles/_List.scss | 4 ++++ src/styles/style.css | 3 +-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/ComponentList.js b/src/components/ComponentList.js index cb981d540..de9219dfa 100644 --- a/src/components/ComponentList.js +++ b/src/components/ComponentList.js @@ -145,8 +145,9 @@ class ComponentList extends React.Component { render() { const { loadMoreRows, noRowsRenderer, list, listLength } = this.props const { sortOrder, contentSeq } = this.state + const showFilterBar = false return ( -
+

Component

diff --git a/src/styles/_App.scss b/src/styles/_App.scss index 617637f06..4208e5a8b 100644 --- a/src/styles/_App.scss +++ b/src/styles/_App.scss @@ -240,7 +240,6 @@ main { box-shadow: 5px 5px 20px -10px lightgrey; display: flex; min-height: 200px; - padding-bottom: $height-filters-section; .fa-spinner { display: none; diff --git a/src/styles/_List.scss b/src/styles/_List.scss index 4ad413707..b65828e6c 100644 --- a/src/styles/_List.scss +++ b/src/styles/_List.scss @@ -373,6 +373,10 @@ height: $height-filters-list; } +.show-filter.clearly-table-body { + margin-bottom: $height-filters-section; +} + .filter-list, .list-filter, .section--filter-bar { diff --git a/src/styles/style.css b/src/styles/style.css index 6a151e402..230debb70 100644 --- a/src/styles/style.css +++ b/src/styles/style.css @@ -433,13 +433,12 @@ a:hover { /* min-height: 550px; */ /* max-height: 700px; */ overflow: hidden; - height: 60vh; position: relative; width: 100%; will-change: transform; } .clearly-table-body .form-group.flex-grow-column { - height: 100%; + height: 60vh; width: 100%; } .clearly-table .form-group.flex-grow-column .checkbox { From 660dbc280223462b216adbdc74fe867850d1383b Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Thu, 25 Aug 2022 09:38:34 -0700 Subject: [PATCH 11/16] Fix display of ShareButton dropdown in workspace view ShareButton uses DropdownButton from Bootstrap 3. Bootstrap 3 uses open class for expanded drop down. The imported bootstrap 5 styling uses show class for expanded drop down. Added the missing Bootstrap 3 styling necessary for the drop down to be correctly displayed. Also utilize the existing Bootstrap 5 styling class for the menu item to avoid copying over more styling classes --- .../Navigation/Pages/PageDefinitions/ButtonsBar.js | 5 +++++ src/components/Navigation/Ui/ShareButton.js | 10 +++++----- src/styles/_ShareButton.scss | 11 +++++++++++ src/styles/index.scss | 1 + 4 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 src/styles/_ShareButton.scss diff --git a/src/components/Navigation/Pages/PageDefinitions/ButtonsBar.js b/src/components/Navigation/Pages/PageDefinitions/ButtonsBar.js index cb8606963..f10fd0f27 100644 --- a/src/components/Navigation/Pages/PageDefinitions/ButtonsBar.js +++ b/src/components/Navigation/Pages/PageDefinitions/ButtonsBar.js @@ -5,6 +5,11 @@ import ButtonWithTooltip from '../../Ui/ButtonWithTooltip' import ShareButton from '../../Ui/ShareButton' export default class ButtonsBar extends Component { + constructor(props) { + super(props) + this.onSelect = this.onSelect.bind(this) + } + static propTypes = { components: PropTypes.object, hasChanges: PropTypes.bool, diff --git a/src/components/Navigation/Ui/ShareButton.js b/src/components/Navigation/Ui/ShareButton.js index 4c570939c..f82c783f7 100644 --- a/src/components/Navigation/Ui/ShareButton.js +++ b/src/components/Navigation/Ui/ShareButton.js @@ -13,18 +13,18 @@ export default class ShareButton extends Component { const disabled = !components || components.list.length === 0 return ( - onSelect('url')}> + onSelect('url')}> URL - onSelect('file')}> + onSelect('file')}> Coordinate list (JSON) - onSelect('notice')}> + onSelect('notice')}> Notice file - + {/* Definitions (Not implemented) - SPDX (Not implemented) + SPDX (Not implemented) */} ) } diff --git a/src/styles/_ShareButton.scss b/src/styles/_ShareButton.scss new file mode 100644 index 000000000..14d6b9c52 --- /dev/null +++ b/src/styles/_ShareButton.scss @@ -0,0 +1,11 @@ +.open > .dropdown-menu { + display: block; +} + +.dropdown.btn-group { + display: inline-block; +} + +.dropdown-item > a { + display: block; +} \ No newline at end of file diff --git a/src/styles/index.scss b/src/styles/index.scss index fb4e895c9..7277446d2 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -75,5 +75,6 @@ main { @import './GetInvolved.scss'; @import './PageAbout.scss'; @import './charter.scss'; +@import './ShareButton.scss'; @import './utils.scss'; From bf4736d27ae792202983439c231a14655bccb286 Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Wed, 6 Jul 2022 15:45:59 -0700 Subject: [PATCH 12/16] Support component search by provider 1. Added provider to the pattern string for coordinates suggestion The search api call in service ignores provider type. For example, the following call returns co-ordinates with provider other than npmjs: curl -X GET "https://dev-api.clearlydefined.io/definitions?pattern=jw&type=npm" -H "accept: */*" This is probably by design: the suggestion api only takes the pattern string into account. When provider is included in the pattern string, the search result reflects the provider specification. The solution is to pass the provider information when searching in PageBrowse. 2. Also trigger search when provider is changed Task: https://github.com/clearlydefined/website/issues/957 --- .../Navigation/Pages/PageBrowse/PageBrowse.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/Navigation/Pages/PageBrowse/PageBrowse.js b/src/components/Navigation/Pages/PageBrowse/PageBrowse.js index 0320e720f..85b29f900 100644 --- a/src/components/Navigation/Pages/PageBrowse/PageBrowse.js +++ b/src/components/Navigation/Pages/PageBrowse/PageBrowse.js @@ -34,7 +34,8 @@ class PageBrowse extends SystemManagedList { this.state = { activeSort: 'releaseDate-desc', searchFocused: false, - selectedProvider: providers[0] + selectedProvider: providers[0], + searchTerm: '' } this.onFilter = this.onFilter.bind(this) this.onSort = this.onSort.bind(this) @@ -63,13 +64,19 @@ class PageBrowse extends SystemManagedList { } onBrowse = value => { - this.setState({ activeName: value }, () => this.updateData()) + this.setState({ activeName: value, searchTerm: '' }, () => this.updateData()) } onFocusChange = value => { this.setState({ searchFocused: value }) } + onSearch = value => { + this.setState({ searchTerm: value }) + const provider = this.state.selectedProvider.value + super.onSearch(provider + '/' + value) + } + tableTitle() { return 'Browse' } @@ -163,6 +170,7 @@ class PageBrowse extends SystemManagedList { onProviderChange(item) { this.setState({ selectedProvider: item }) + this.state.searchTerm && super.onSearch(item.value + '/' + this.state.searchTerm) } // Overrides the default onFilter method From ff9900dec0dd85f9f641b55ded61eac2a7702385 Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Tue, 27 Sep 2022 16:16:59 -0700 Subject: [PATCH 13/16] Address review comments --- .../Navigation/Pages/PageBrowse/PageBrowse.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/Navigation/Pages/PageBrowse/PageBrowse.js b/src/components/Navigation/Pages/PageBrowse/PageBrowse.js index 85b29f900..dccd887f7 100644 --- a/src/components/Navigation/Pages/PageBrowse/PageBrowse.js +++ b/src/components/Navigation/Pages/PageBrowse/PageBrowse.js @@ -10,7 +10,7 @@ import difference from 'lodash/difference' import classNames from 'classnames' import { ROUTE_ROOT } from '../../../../utils/routingConstants' import { getCurationsAction } from '../../../../actions/curationActions' -import { uiBrowseUpdateList, uiNavigation, uiBrowseGet } from '../../../../actions/ui' +import { uiBrowseUpdateFilterList, uiBrowseUpdateList, uiNavigation, uiBrowseGet } from '../../../../actions/ui' import SystemManagedList from '../../../SystemManagedList' import Section from '../../../Section' import ComponentList from '../../../ComponentList' @@ -73,8 +73,8 @@ class PageBrowse extends SystemManagedList { onSearch = value => { this.setState({ searchTerm: value }) - const provider = this.state.selectedProvider.value - super.onSearch(provider + '/' + value) + const valueToSearch = this.state.selectedProvider.value + '/' + value + this.props.dispatch(uiBrowseUpdateFilterList(this.props.token, valueToSearch)) } tableTitle() { @@ -170,7 +170,10 @@ class PageBrowse extends SystemManagedList { onProviderChange(item) { this.setState({ selectedProvider: item }) - this.state.searchTerm && super.onSearch(item.value + '/' + this.state.searchTerm) + if (this.state.searchTerm) { + const valueToSearch = item.value + '/' + this.state.searchTerm + this.props.dispatch(uiBrowseUpdateFilterList(this.props.token, valueToSearch)) + } } // Overrides the default onFilter method From b6992748babb4cf2d40de11ffcc73f55c983fb1d Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Fri, 29 Jul 2022 14:32:58 -0700 Subject: [PATCH 14/16] Fix ComponentButtons Enable the ButtonGroup in ComponentButtons. Fix opening and closing of FullDetailPage for component inspection in PageDefinition (workspace). ComponentButtons is a common component used in PageBrowse, PageDefinition, and PageCuration. Some of the buttons do not make sense in a certain view: -PageBrowse does not render FullDetailPage, so onInspect, which make the contained FullDetailPage visible does not make sense there. -onAddComponent is implemented in UserManagedList. PageBrowse is not a subclass of UserManagedList and therefore will not have onAddComponent available. Adding (source) component should then be disabled in PageBrowse Task: https://github.com/clearlydefined/website/issues/946 --- .../FullDetailView/AbstractFullDetailsView.js | 4 +- .../FullDetailView/FullDetailComponent.js | 1 - .../FullDetailView/FullDetailPage.js | 4 +- .../Navigation/Pages/PageBrowse/PageBrowse.js | 1 - .../Pages/PageDefinitions/PageDefinitions.js | 3 +- .../Navigation/Ui/ComponentButtons.js | 180 ++++++++---------- src/components/SystemManagedList.js | 1 + src/styles/_Popover.scss | 2 +- 8 files changed, 91 insertions(+), 105 deletions(-) diff --git a/src/components/FullDetailView/AbstractFullDetailsView.js b/src/components/FullDetailView/AbstractFullDetailsView.js index f618984f9..c928a45f0 100644 --- a/src/components/FullDetailView/AbstractFullDetailsView.js +++ b/src/components/FullDetailView/AbstractFullDetailsView.js @@ -32,7 +32,8 @@ export class AbstractFullDetailsView extends Component { return modalView ? ( this.revertDefinition(definition, value, 'browse')} onChange={this.onChangeComponent} - onInspect={this.onInspect} renderFilterBar={this.renderFilterBar} curations={curations} definitions={definitions} diff --git a/src/components/Navigation/Pages/PageDefinitions/PageDefinitions.js b/src/components/Navigation/Pages/PageDefinitions/PageDefinitions.js index e52852dc7..ef6e3d701 100644 --- a/src/components/Navigation/Pages/PageDefinitions/PageDefinitions.js +++ b/src/components/Navigation/Pages/PageDefinitions/PageDefinitions.js @@ -23,7 +23,6 @@ import UrlShare from '../../../../utils/urlShare' export class PageDefinitions extends UserManagedList { constructor(props) { super(props) - this.onAddComponent = this.onAddComponent.bind(this) this.doSave = this.doSave.bind(this) this.doSaveAsUrl = this.doSaveAsUrl.bind(this) this.revertAll = this.revertAll.bind(this) @@ -225,7 +224,7 @@ export class PageDefinitions extends UserManagedList { path={path} currentDefinition={currentDefinition} component={currentComponent} - readOnly={this.readOnly} + readOnly={true} /> )} {showSavePopup && ( diff --git a/src/components/Navigation/Ui/ComponentButtons.js b/src/components/Navigation/Ui/ComponentButtons.js index 9036dfc53..3507327a8 100644 --- a/src/components/Navigation/Ui/ComponentButtons.js +++ b/src/components/Navigation/Ui/ComponentButtons.js @@ -1,12 +1,15 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { get } from 'lodash' -import { ButtonToolbar, Dropdown as BSDropdown } from 'react-bootstrap' +import { Button, ButtonGroup, ButtonToolbar, Dropdown as BSDropdown } from 'react-bootstrap' import EntitySpec from '../../../utils/entitySpec' import { ROUTE_DEFINITIONS } from '../../../utils/routingConstants' import { withResize } from '../../../utils/WindowProvider' +import Definition from '../../../utils/definition' import MoreVertIcon from '@material-ui/icons/MoreVert' import { IconButton } from '@material-ui/core' +import ButtonWithTooltip from './ButtonWithTooltip' + class ComponentButtons extends Component { constructor(props) { super(props) @@ -37,18 +40,21 @@ class ComponentButtons extends Component { } revertComponent(component, param) { + this.handleMenu() const { onRevert } = this.props onRevert && onRevert(component, param) } inspectComponent(component, definition, event) { event.stopPropagation() + this.handleMenu() const action = this.props.onInspect action && action(component, definition) } addSourceForComponent(component, event) { event.stopPropagation() + this.handleMenu() const definition = this.props.getDefinition(component) const sourceLocation = get(definition, 'described.sourceLocation') const sourceEntity = sourceLocation && EntitySpec.fromObject(sourceLocation) @@ -58,6 +64,7 @@ class ComponentButtons extends Component { showVersionSelectorPopup(component, multiple, event) { event.domEvent.stopPropagation() + this.handleMenu() this.props.showVersionSelectorPopup(component, multiple) } @@ -77,111 +84,92 @@ class ComponentButtons extends Component { ) } + renderDropdown(currentComponent) { + // return ( + // + // + // Switch version + // + // + // Add more versions + // + // + // } + // > + // + // + // ) + } + renderButtonGroup() { - const { definition, currentComponent, hasChange } = this.props + const { definition, currentComponent, hasChange, readOnly, onAddComponent, onInspect } = this.props const component = EntitySpec.fromObject(currentComponent) + + const isSourceComponent = this.isSourceComponent(component) + const isSourceEmpty = Definition.isSourceEmpty(definition) + const isDefinitionEmpty = Definition.isDefinitionEmpty(definition) return ( <>
- { - this.handleMenu() - }} - className="clearly-menu-btns" - > - View Components - - - -
- - {/* - - {!isSourceComponent && !readOnly && !isSourceEmpty && ( - - - - )} - {!isDefinitionEmpty && ( - + + {!isSourceComponent && !readOnly && !isSourceEmpty && onAddComponent && ( + + + + )} + {!isDefinitionEmpty && onInspect && ( + - - )} - event.stopPropagation()} - > - - - {!hideVersionSelector && ( - - <> - - - Switch version - - - Add more versions - - - } + + + + )} + { + this.handleMenu() + event.stopPropagation() + }} + > + + + {/*!hideVersionSelector && ( + + {this.renderDropdown(currentComponent)} + + )*/} + {!readOnly && !isDefinitionEmpty && ( + + - - - - )} - {!readOnly && !isDefinitionEmpty && ( - - - - )} - */} + + + + )} + +
) } diff --git a/src/components/SystemManagedList.js b/src/components/SystemManagedList.js index 62be06a77..d234cc4b4 100644 --- a/src/components/SystemManagedList.js +++ b/src/components/SystemManagedList.js @@ -51,6 +51,7 @@ export default class SystemManagedList extends Component { this.updateList = this.updateList.bind(this) this.onSearch = this.onSearch.bind(this) this.onInspect = this.onInspect.bind(this) + this.onInspectClose = this.onInspectClose.bind(this) this.onSort = this.onSort.bind(this) this.onFilter = this.onFilter.bind(this) this.onChangeComponent = this.onChangeComponent.bind(this) diff --git a/src/styles/_Popover.scss b/src/styles/_Popover.scss index ca7a2b8ec..295fc077f 100644 --- a/src/styles/_Popover.scss +++ b/src/styles/_Popover.scss @@ -219,7 +219,7 @@ button.modal__btn--secondary, } } -.fade.in.definition__tooltip.tooltip, +.fade.in.tooltip, .fade.in.modal { opacity: 1 !important; } \ No newline at end of file From 124d721e79081ae020d6c9ef9fbaded45b6919c7 Mon Sep 17 00:00:00 2001 From: Qing Tomlinson Date: Wed, 10 Aug 2022 15:10:30 -0700 Subject: [PATCH 15/16] Add delete component button to ComponentButtons The delete button is only availble in PageDefinition (workspace) where onRemoveComponent is defined. --- src/components/Navigation/Ui/ComponentButtons.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/Navigation/Ui/ComponentButtons.js b/src/components/Navigation/Ui/ComponentButtons.js index 3507327a8..6722bf04e 100644 --- a/src/components/Navigation/Ui/ComponentButtons.js +++ b/src/components/Navigation/Ui/ComponentButtons.js @@ -35,6 +35,7 @@ class ComponentButtons extends Component { removeComponent(component, event) { event.stopPropagation() + this.handleMenu() const { onRemove } = this.props onRemove && onRemove(component) } @@ -113,7 +114,7 @@ class ComponentButtons extends Component { } renderButtonGroup() { - const { definition, currentComponent, hasChange, readOnly, onAddComponent, onInspect } = this.props + const { definition, currentComponent, hasChange, readOnly, onAddComponent, onInspect, onRemove } = this.props const component = EntitySpec.fromObject(currentComponent) const isSourceComponent = this.isSourceComponent(component) @@ -157,6 +158,13 @@ class ComponentButtons extends Component { {this.renderDropdown(currentComponent)} )*/} + {!readOnly && onRemove && ( + + + + )} {!readOnly && !isDefinitionEmpty && ( - // - // ) + return ( + + + Switch version + + + Add more versions + + + } + > + + + ) } renderButtonGroup() { - const { definition, currentComponent, hasChange, readOnly, onAddComponent, onInspect, onRemove } = this.props + const { + definition, + currentComponent, + hasChange, + readOnly, + onAddComponent, + onInspect, + onRemove, + hideVersionSelector + } = this.props const component = EntitySpec.fromObject(currentComponent) const isSourceComponent = this.isSourceComponent(component) const isSourceEmpty = Definition.isSourceEmpty(definition) const isDefinitionEmpty = Definition.isDefinitionEmpty(definition) + const isProviderSupported = this._isProviderSupported(component) return ( <> @@ -153,11 +169,11 @@ class ComponentButtons extends Component { > - {/*!hideVersionSelector && ( + {!hideVersionSelector && isProviderSupported && ( {this.renderDropdown(currentComponent)} - )*/} + )} {!readOnly && onRemove && (