From: Daniel Kutyła Date: Fri, 19 Nov 2021 15:34:49 +0000 (+0100) Subject: Merge remote-tracking branch 'origin/main' into 18169-cancel-button-not-working X-Git-Tag: 2.4.0~29^2~1 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/172ba18e43743d90b8a1110d62209be2ab7627d1?hp=d8f669aadc5f3d7241395abd6aa764406079d7d3 Merge remote-tracking branch 'origin/main' into 18169-cancel-button-not-working Arvados-DCO-1.1-Signed-off-by: Daniel Kutyła --- diff --git a/Makefile b/Makefile index aaf2271c..ab58fc58 100644 --- a/Makefile +++ b/Makefile @@ -97,8 +97,9 @@ $(DEB_FILE): build --url="https://arvados.org" \ --license="GNU Affero General Public License, version 3.0" \ --description="$(DESCRIPTION)" \ - --config-files="etc/arvados/workbench2/workbench2.example.json" \ - $(WORKSPACE)/build/=$(DEST_DIR) + --config-files="etc/arvados/$(APP_NAME)/workbench2.example.json" \ + $(WORKSPACE)/build/=$(DEST_DIR) \ + etc/arvados/workbench2/workbench2.example.json=/etc/arvados/$(APP_NAME)/workbench2.example.json $(RPM_FILE): build fpm \ @@ -112,8 +113,9 @@ $(RPM_FILE): build --url="https://arvados.org" \ --license="GNU Affero General Public License, version 3.0" \ --description="$(DESCRIPTION)" \ - --config-files="etc/arvados/workbench2/workbench2.example.json" \ - $(WORKSPACE)/build/=$(DEST_DIR) + --config-files="etc/arvados/$(APP_NAME)/workbench2.example.json" \ + $(WORKSPACE)/build/=$(DEST_DIR) \ + etc/arvados/workbench2/workbench2.example.json=/etc/arvados/$(APP_NAME)/workbench2.example.json copy: $(DEB_FILE) $(RPM_FILE) for target in $(TARGETS) ; do \ @@ -130,5 +132,16 @@ copy: $(DEB_FILE) $(RPM_FILE) # use FPM to create DEB and RPM packages: copy +packages-in-docker: workbench2-build-image + docker run --env ci="true" \ + --env ARVADOS_DIRECTORY=/tmp/arvados \ + --env APP_NAME=${APP_NAME} \ + --env ITERATION=${ITERATION} \ + --env TARGETS="${TARGETS}" \ + -w="/tmp/workbench2" \ + -t -v ${WORKSPACE}:/tmp/workbench2 \ + -v ${ARVADOS_DIRECTORY}:/tmp/arvados workbench2-build:latest \ + make packages + workbench2-build-image: (cd docker && docker build -t workbench2-build .) diff --git a/README.md b/README.md index 8bb50dbe..4ec4bd1c 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,6 @@ Currently this configuration schema is supported: ``` { "API_HOST": "string", - "VOCABULARY_URL": "string", "FILE_VIEWERS_CONFIG_URL": "string", } ``` @@ -93,12 +92,6 @@ The Arvados base URL. The `REACT_APP_ARVADOS_API_HOST` environment variable can be used to set the default URL if the run time configuration is unreachable. -### VOCABULARY_URL -Local path, or any URL that allows cross-origin requests. See -[Vocabulary JSON file example](public/vocabulary-example.json). - -To use the URL defined in the Arvados cluster configuration, remove the entire `VOCABULARY_URL` entry from the runtime configuration. Found in `/config.json` by default. - ## FILE_VIEWERS_CONFIG_URL Local path, or any URL that allows cross-origin requests. See: diff --git a/cypress/integration/collection.spec.js b/cypress/integration/collection.spec.js index 31337e28..e46be0c3 100644 --- a/cypress/integration/collection.spec.js +++ b/cypress/integration/collection.spec.js @@ -97,14 +97,37 @@ describe('Collection panel tests', function () { }); // Confirm proper vocabulary labels are displayed on the UI. cy.get('[data-cy=collection-properties-panel]') - .should('contain', 'Color') - .and('contain', 'Magenta'); + .should('contain', 'Color: Magenta'); // Confirm proper vocabulary IDs were saved on the backend. cy.doRequest('GET', `/arvados/v1/collections/${this.testCollection.uuid}`) .its('body').as('collection') .then(function () { expect(this.collection.properties.IDTAGCOLORS).to.equal('IDVALCOLORS3'); }); + + // Case-insensitive on-blur auto-selection test + // Key: Size (IDTAGSIZES) - Value: Small (IDVALSIZES2) + cy.get('[data-cy=resource-properties-form]').within(() => { + cy.get('[data-cy=property-field-key]').within(() => { + cy.get('input').type('sIzE'); + }); + cy.get('[data-cy=property-field-value]').within(() => { + cy.get('input').type('sMaLL'); + }); + // Cannot "type()" TAB on Cypress so let's click another field + // to trigger the onBlur event. + cy.get('[data-cy=property-field-key]').click(); + cy.root().submit(); + }); + // Confirm proper vocabulary labels are displayed on the UI. + cy.get('[data-cy=collection-properties-panel]') + .should('contain', 'Size: S'); + // Confirm proper vocabulary IDs were saved on the backend. + cy.doRequest('GET', `/arvados/v1/collections/${this.testCollection.uuid}`) + .its('body').as('collection') + .then(function () { + expect(this.collection.properties.IDTAGSIZES).to.equal('IDVALSIZES2'); + }); }); }); diff --git a/cypress/integration/favorites.spec.js b/cypress/integration/favorites.spec.js index 9f4e2b84..13a2c467 100644 --- a/cypress/integration/favorites.spec.js +++ b/cypress/integration/favorites.spec.js @@ -150,7 +150,7 @@ describe('Favorites tests', function () { cy.getAll('@mySharedWritableProject', '@testTargetCollection') .then(function ([mySharedWritableProject, testTargetCollection]) { cy.loginAs(adminUser); - + cy.get('[data-cy=side-panel-tree]').contains('My Favorites').click(); const newProjectName = `New project name ${mySharedWritableProject.name}`; @@ -160,7 +160,7 @@ describe('Favorites tests', function () { cy.testEditProjectOrCollection('main', mySharedWritableProject.name, newProjectName, newProjectDescription); cy.testEditProjectOrCollection('main', testTargetCollection.name, newCollectionName, newCollectionDescription, false); - + cy.get('[data-cy=side-panel-tree]').contains('Projects').click(); cy.get('main').contains(newProjectName).rightclick(); @@ -171,7 +171,7 @@ describe('Favorites tests', function () { cy.get('[data-cy=side-panel-tree]').contains('Public Favorites').click(); cy.testEditProjectOrCollection('main', newProjectName, mySharedWritableProject.name, 'newProjectDescription'); - cy.testEditProjectOrCollection('main', newCollectionName, testTargetCollection.name, 'newCollectionDescription', false); + cy.testEditProjectOrCollection('main', newCollectionName, testTargetCollection.name, 'newCollectionDescription', false); }); }); diff --git a/cypress/integration/side-panel.spec.js b/cypress/integration/side-panel.spec.js index 912e68eb..f9d4dca3 100644 --- a/cypress/integration/side-panel.spec.js +++ b/cypress/integration/side-panel.spec.js @@ -114,4 +114,30 @@ describe('Side panel tests', function() { }); }); + it('side panel react to refresh when project data changes', () => { + const project = 'writableProject'; + + cy.createProject({ + owningUser: activeUser, + targetUser: activeUser, + projectName: project, + canWrite: true, + addToFavorites: false + }); + + cy.getAll('@writableProject') + .then(function ([writableProject]) { + cy.loginAs(activeUser); + + cy.get('[data-cy=side-panel-tree]').contains('Projects').click(); + + cy.get('[data-cy=side-panel-tree]').contains(writableProject.name).should('exist'); + + cy.trashGroup(activeUser.token, writableProject.uuid); + + cy.contains('Refresh').click(); + + cy.contains(writableProject.name).should('not.exist'); + }); + }); }) diff --git a/docker/Dockerfile b/docker/Dockerfile index 729d62c4..3bffcac4 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -11,8 +11,16 @@ RUN apt-get update && \ libsecret-1-0 libsecret-1-dev rpm ruby ruby-dev rubygems build-essential \ libpam0g-dev libgbm1 git && \ apt-get clean -RUN apt-get -yq --no-install-recommends -t buster-backports install golang-go && \ - apt-get clean + +# Get Go 1.16.9 +RUN cd /usr/src && \ + wget https://golang.org/dl/go1.16.9.linux-amd64.tar.gz && \ + tar xzf go1.16.9.linux-amd64.tar.gz && \ + ln -s /usr/src/go/bin/go /usr/local/bin/go-1.16.9 && \ + ln -s /usr/src/go/bin/gofmt /usr/local/bin/gofmt-1.16.9 && \ + ln -s /usr/local/bin/go-1.16.9 /usr/local/bin/go && \ + ln -s /usr/local/bin/gofmt-1.16.9 /usr/local/bin/gofmt + RUN gem install --no-ri --no-rdoc fpm RUN git clone https://git.arvados.org/arvados.git && cd arvados && \ go mod download && \ diff --git a/src/common/config.ts b/src/common/config.ts index 56f7c488..2518c95e 100644 --- a/src/common/config.ts +++ b/src/common/config.ts @@ -51,7 +51,6 @@ export interface ClusterConfigJSON { }; Workbench: { ArvadosDocsite: string; - VocabularyURL: string; FileViewersConfigURL: string; WelcomePageHTML: string; InactivePageHTML: string; @@ -204,15 +203,10 @@ remove the entire ${varName} entry from ${WORKBENCH_CONFIG_URL}`); } config.fileViewersConfigUrl = fileViewerConfigUrl; - let vocabularyUrl; if (workbenchConfig.VOCABULARY_URL !== undefined) { - warnLocalConfig("VOCABULARY_URL"); - vocabularyUrl = workbenchConfig.VOCABULARY_URL; + console.warn(`A value for VOCABULARY_URL was found in ${WORKBENCH_CONFIG_URL}. It will be ignored as the cluster already provides its own endpoint, you can safely remove it.`) } - else { - vocabularyUrl = config.clusterConfig.Workbench.VocabularyURL || "/vocabulary-example.json"; - } - config.vocabularyUrl = vocabularyUrl; + config.vocabularyUrl = getVocabularyURL(workbenchConfig.API_HOST); return { config, apiHost: workbenchConfig.API_HOST }; }); @@ -240,7 +234,6 @@ export const mockClusterConfigJSON = (config: Partial): Clust }, Workbench: { ArvadosDocsite: "", - VocabularyURL: "", FileViewersConfigURL: "", WelcomePageHTML: "", InactivePageHTML: "", @@ -315,5 +308,7 @@ const getDefaultConfig = (): WorkbenchConfig => { export const ARVADOS_API_PATH = "arvados/v1"; export const CLUSTER_CONFIG_PATH = "arvados/v1/config"; +export const VOCABULARY_PATH = "arvados/v1/vocabulary"; export const DISCOVERY_DOC_PATH = "discovery/v1/apis/arvados/v1/rest"; -export const getClusterConfigURL = (apiHost: string) => `${window.location.protocol}//${apiHost}/${CLUSTER_CONFIG_PATH}?nocache=${(new Date()).getTime()}`; +export const getClusterConfigURL = (apiHost: string) => `https://${apiHost}/${CLUSTER_CONFIG_PATH}?nocache=${(new Date()).getTime()}`; +export const getVocabularyURL = (apiHost: string) => `https://${apiHost}/${VOCABULARY_PATH}?nocache=${(new Date()).getTime()}`; diff --git a/src/components/chips/chips.tsx b/src/components/chips/chips.tsx index 2a6fafc3..eb68ed7a 100644 --- a/src/components/chips/chips.tsx +++ b/src/components/chips/chips.tsx @@ -43,10 +43,13 @@ export const Chips = withStyles(styles)( ; } - renderChip = (value: Value, index: number) => - - + renderChip = (value: Value, index: number) => { + const { deletable, getLabel } = this.props; + return + + } type = 'chip'; @@ -132,4 +135,4 @@ interface CollectedProps { interface DraggableChipProps { value: Value; -} \ No newline at end of file +} diff --git a/src/components/refresh-button/refresh-button.tsx b/src/components/refresh-button/refresh-button.tsx index f2c41d28..9971547b 100644 --- a/src/components/refresh-button/refresh-button.tsx +++ b/src/components/refresh-button/refresh-button.tsx @@ -22,13 +22,20 @@ const styles: StyleRulesCallback = theme => ({ }, }); -export const RefreshButton = ({ history, classes }: RouteComponentProps & WithStyles) => +interface RefreshButtonProps { + onClick?: () => void; +} + +export const RefreshButton = ({ history, classes, onClick }: RouteComponentProps & WithStyles & RefreshButtonProps) =>