mirror of
https://github.com/cypress-io/cypress.git
synced 2026-01-31 03:29:43 -06:00
Have org selector properly show when no default org (#5955)
* Update logic when looking for org to check length of orgs excluding default - Also hide the ‘Me | Org’ selector altogether since it makes to sense to be there, you can’t choose ‘Me’ because it doesn’t exist. * Remove radios for 'me' and 'an org' entirely - have default org show up as ‘Your personal organization’ * Select default org by default * Preselect 'personal org' or first org in list by default * clean up test selectors + fix failing runs list spec * Add react-select for orgs select / add back showing avatar for 'personal org' * Have loader properly display in setup project model when orgs are still loading
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
[
|
||||
{
|
||||
"id": "777",
|
||||
"name": "Acme Developers",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"id": "000",
|
||||
"name": "Jane Lane",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"id": "777",
|
||||
"name": "Acme Developers",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"id": "999",
|
||||
"name": "Osato Devs",
|
||||
|
||||
@@ -715,8 +715,10 @@ describe('Runs List', function () {
|
||||
|
||||
it('clears message after setting up to record', function () {
|
||||
cy.contains('.btn', 'Set up project').click()
|
||||
cy.get('.modal-body')
|
||||
.contains('.btn', 'Me').click()
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.contains('Your personal organization').click()
|
||||
|
||||
cy.get('.privacy-radio').find('input').last().check()
|
||||
cy.get('.modal-body')
|
||||
@@ -784,8 +786,10 @@ describe('Runs List', function () {
|
||||
|
||||
it('clears message after setting up CI', function () {
|
||||
cy.contains('.btn', 'Set up a new project').click()
|
||||
cy.get('.modal-body')
|
||||
.contains('.btn', 'Me').click()
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.contains('Your personal organization').click()
|
||||
|
||||
cy.get('.privacy-radio').find('input').last().check()
|
||||
cy.get('.modal-body')
|
||||
|
||||
@@ -80,27 +80,43 @@ describe('Set Up Project', function () {
|
||||
.should('have.value', 'New Project Here')
|
||||
})
|
||||
|
||||
describe('default owner', function () {
|
||||
it('has no owner selected by default', function () {
|
||||
cy.get('#me').should('not.be.selected')
|
||||
|
||||
cy.get('#org').should('not.be.selected')
|
||||
})
|
||||
|
||||
it('org docs are linked', () => {
|
||||
cy.contains('label', 'Who should own this')
|
||||
.find('a').click().then(function () {
|
||||
expect(this.ipc.externalOpen).to.be.calledWith('https://on.cypress.io/what-are-organizations')
|
||||
})
|
||||
it('org docs are linked', () => {
|
||||
cy.contains('label', 'Who should own this')
|
||||
.find('a').click().then(function () {
|
||||
expect(this.ipc.externalOpen).to.be.calledWith('https://on.cypress.io/what-are-organizations')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('selecting me as owner', function () {
|
||||
describe('loading behavior', function () {
|
||||
beforeEach(function () {
|
||||
cy.get('.btn').contains('Set up project').click()
|
||||
})
|
||||
|
||||
it('calls getOrgs', function () {
|
||||
expect(this.ipc.getOrgs).to.be.calledOnce
|
||||
})
|
||||
|
||||
it('displays loading view before orgs load', function () {
|
||||
cy.get('.loader').then(function () {
|
||||
this.getOrgs.resolve(this.orgs)
|
||||
})
|
||||
|
||||
cy.get('.loader').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
||||
describe('selecting an org', function () {
|
||||
describe('selecting Personal org', function () {
|
||||
beforeEach(function () {
|
||||
cy.get('.privacy-radio').should('not.be.visible')
|
||||
this.getOrgs.resolve(this.orgs)
|
||||
|
||||
cy.get('.btn').contains('Set up project').click()
|
||||
cy.get('.modal-content')
|
||||
.contains('.btn', 'Me').click()
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.contains('Your personal organization').click()
|
||||
})
|
||||
|
||||
it('access docs are linked', () => {
|
||||
@@ -115,25 +131,29 @@ describe('Set Up Project', function () {
|
||||
.find('input').should('not.be.checked')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('selecting an org', function () {
|
||||
context('with orgs', function () {
|
||||
beforeEach(function () {
|
||||
this.getOrgs.resolve(this.orgs)
|
||||
cy.get('.btn').contains('Set up project').click()
|
||||
|
||||
cy.get('.modal-content')
|
||||
.contains('.btn', 'An Organization').click()
|
||||
})
|
||||
|
||||
it('lists organizations to assign to project', function () {
|
||||
cy.get('#organizations-select').find('option')
|
||||
cy.get('.empty-select-orgs').should('not.be.visible')
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.should('have.length', this.orgs.length)
|
||||
})
|
||||
|
||||
it('selects none by default', () => {
|
||||
cy.get('#organizations-select').should('have.value', '')
|
||||
it('selects personal org by default', function () {
|
||||
cy.get('.organizations-select').contains(
|
||||
'Your personal organization'
|
||||
)
|
||||
|
||||
cy.get('.privacy-radio').should('be.visible')
|
||||
})
|
||||
|
||||
it('opens external link on click of manage', () => {
|
||||
@@ -143,23 +163,49 @@ describe('Set Up Project', function () {
|
||||
})
|
||||
|
||||
it('displays public & private radios on select', function () {
|
||||
cy.get('.privacy-radio').should('not.be.visible')
|
||||
cy.get('select').select('Acme Developers')
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.contains('Acme Developers').click()
|
||||
|
||||
cy.get('.privacy-radio').should('be.visible')
|
||||
.find('input').should('not.be.checked')
|
||||
})
|
||||
})
|
||||
|
||||
it('clears selections when switching back to Me', function () {
|
||||
cy.get('select').select('Acme Developers')
|
||||
cy.get('.privacy-radio')
|
||||
.find('input').first().check()
|
||||
context('orgs with no default org', function () {
|
||||
beforeEach(function () {
|
||||
this.getOrgs.resolve(Cypress._.filter(this.orgs, { 'default': false }))
|
||||
cy.get('.btn').contains('Set up project').click()
|
||||
})
|
||||
|
||||
cy.get('.btn').contains('Me').click()
|
||||
cy.get('.privacy-radio').find('input').should('not.be.checked')
|
||||
cy.get('.btn').contains('An Organization').click()
|
||||
it('lists organizations to assign to project', function () {
|
||||
cy.get('.empty-select-orgs').should('not.be.visible')
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
// do not count the default org we removed
|
||||
.should('have.length', this.orgs.length - 1)
|
||||
})
|
||||
|
||||
cy.get('#organizations-select').should('have.value', '')
|
||||
it('selects first org by default', function () {
|
||||
cy.get('.organizations-select').contains(this.orgs[1].name)
|
||||
})
|
||||
|
||||
it('opens external link on click of manage', () => {
|
||||
cy.get('.manage-orgs-btn').click().then(function () {
|
||||
expect(this.ipc.externalOpen).to.be.calledWith('https://on.cypress.io/dashboard/organizations')
|
||||
})
|
||||
})
|
||||
|
||||
it('displays public & private radios on select', function () {
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.contains('Acme Developers').click()
|
||||
|
||||
cy.get('.privacy-radio').should('be.visible')
|
||||
.find('input').should('not.be.checked')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -167,13 +213,12 @@ describe('Set Up Project', function () {
|
||||
beforeEach(function () {
|
||||
this.getOrgs.resolve([])
|
||||
cy.get('.btn').contains('Set up project').click()
|
||||
|
||||
cy.get('.modal-content')
|
||||
.contains('.btn', 'An Organization').click()
|
||||
})
|
||||
|
||||
it('displays empty message', () => {
|
||||
cy.get('.empty-select-orgs').should('be.visible')
|
||||
cy.get('.organizations-select').should('not.be.visible')
|
||||
cy.get('.privacy-radio').should('not.be.visible')
|
||||
})
|
||||
|
||||
it('opens dashboard organizations when \'create org\' is clicked', () => {
|
||||
@@ -183,7 +228,7 @@ describe('Set Up Project', function () {
|
||||
})
|
||||
})
|
||||
|
||||
context('without only default org', function () {
|
||||
context('with only default org', function () {
|
||||
beforeEach(function () {
|
||||
this.getOrgs.resolve([{
|
||||
'id': '000',
|
||||
@@ -192,19 +237,13 @@ describe('Set Up Project', function () {
|
||||
}])
|
||||
|
||||
cy.get('.btn').contains('Set up project').click()
|
||||
|
||||
cy.get('.modal-content')
|
||||
.contains('.btn', 'An Organization').click()
|
||||
})
|
||||
|
||||
it('displays empty message', () => {
|
||||
cy.get('.empty-select-orgs').should('be.visible')
|
||||
})
|
||||
|
||||
it('opens dashboard organizations when \'create org\' is clicked', () => {
|
||||
cy.contains('Create organization').click().then(function () {
|
||||
expect(this.ipc.externalOpen).to.be.calledWith('https://on.cypress.io/dashboard/organizations')
|
||||
})
|
||||
it('displays in dropdown', () => {
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option').should('have.length', 1)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -213,9 +252,6 @@ describe('Set Up Project', function () {
|
||||
cy.clock()
|
||||
this.getOrgs.resolve(this.orgs)
|
||||
cy.get('.btn').contains('Set up project').click()
|
||||
|
||||
cy.get('.modal-content')
|
||||
.contains('.btn', 'An Organization').click()
|
||||
})
|
||||
|
||||
it('polls for orgs twice in 10+sec on click of org', function () {
|
||||
@@ -226,12 +262,14 @@ describe('Set Up Project', function () {
|
||||
|
||||
it('updates org name on list on successful poll', function () {
|
||||
this.name = 'Foo Bar Devs'
|
||||
this.orgs[0].name = this.name
|
||||
this.orgs[1].name = this.name
|
||||
this.getOrgsAgain = this.ipc.getOrgs.onCall(2).resolves(this.orgs)
|
||||
|
||||
cy.tick(11000)
|
||||
|
||||
cy.get('#organizations-select').find('option')
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.contains(this.name)
|
||||
})
|
||||
|
||||
@@ -246,7 +284,9 @@ describe('Set Up Project', function () {
|
||||
|
||||
cy.tick(11000)
|
||||
|
||||
cy.get('#organizations-select').find('option')
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.should('have.length', this.orgs.length)
|
||||
})
|
||||
})
|
||||
@@ -256,8 +296,10 @@ describe('Set Up Project', function () {
|
||||
beforeEach(function () {
|
||||
this.getOrgs.resolve(this.orgs)
|
||||
cy.contains('.btn', 'Set up project').click()
|
||||
cy.get('.modal-body')
|
||||
.contains('.btn', 'Me').click()
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.contains('Your personal organization').click()
|
||||
|
||||
cy.get('.privacy-radio').find('input').last().check()
|
||||
|
||||
@@ -292,11 +334,12 @@ describe('Set Up Project', function () {
|
||||
})
|
||||
|
||||
it('sends project name, org id, and public flag to ipc event', function () {
|
||||
cy.get('.modal-body')
|
||||
.contains('.btn', 'An Organization').click()
|
||||
|
||||
cy.get('#projectName').clear().type('New Project')
|
||||
cy.get('select').select('Acme Developers')
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.contains('Acme Developers').click()
|
||||
|
||||
cy.get('.privacy-radio').find('input').first().check()
|
||||
|
||||
cy.get('.modal-body')
|
||||
@@ -312,10 +355,11 @@ describe('Set Up Project', function () {
|
||||
|
||||
context('org/public', function () {
|
||||
beforeEach(function () {
|
||||
cy.get('.modal-body')
|
||||
.contains('.btn', 'An Organization').click()
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.contains('Acme Developers').click()
|
||||
|
||||
cy.get('select').select('Acme Developers')
|
||||
cy.get('.privacy-radio').find('input').first().check()
|
||||
|
||||
cy.get('.modal-body')
|
||||
@@ -333,11 +377,12 @@ describe('Set Up Project', function () {
|
||||
|
||||
context('me/private', function () {
|
||||
beforeEach(function () {
|
||||
cy.get('.modal-body')
|
||||
.contains('.btn', 'Me').click()
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.contains('Your personal organization').click()
|
||||
|
||||
cy.get('.privacy-radio').find('input').last().check()
|
||||
|
||||
cy.get('.modal-body')
|
||||
.contains('.btn', 'Set up project').click()
|
||||
})
|
||||
@@ -353,11 +398,12 @@ describe('Set Up Project', function () {
|
||||
|
||||
context('me/public', function () {
|
||||
beforeEach(function () {
|
||||
cy.get('.modal-body')
|
||||
.contains('.btn', 'Me').click()
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.contains('Your personal organization').click()
|
||||
|
||||
cy.get('.privacy-radio').find('input').first().check()
|
||||
|
||||
cy.get('.modal-body')
|
||||
.contains('.btn', 'Set up project').click()
|
||||
})
|
||||
@@ -392,8 +438,10 @@ describe('Set Up Project', function () {
|
||||
beforeEach(function () {
|
||||
this.getOrgs.resolve(this.orgs)
|
||||
cy.contains('.btn', 'Set up project').click()
|
||||
cy.get('.modal-body')
|
||||
.contains('.btn', 'Me').click()
|
||||
cy.get('.organizations-select__dropdown-indicator').click()
|
||||
cy.get('.organizations-select__menu').should('be.visible')
|
||||
cy.get('.organizations-select__option')
|
||||
.contains('Your personal organization').click()
|
||||
|
||||
cy.get('.privacy-radio').find('input').last().check()
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"watch": "npm run build -- --watch --progress"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/polyfill": "^7.7.0",
|
||||
"@babel/polyfill": "7.7.0",
|
||||
"@cypress/icons": "0.7.0",
|
||||
"@cypress/json-schemas": "5.33.0",
|
||||
"@cypress/react-tooltip": "0.5.3",
|
||||
@@ -41,8 +41,9 @@
|
||||
"react": "16.8.6",
|
||||
"react-bootstrap-modal": "4.2.0",
|
||||
"react-dom": "16.8.6",
|
||||
"react-inspector": "^4.0.0",
|
||||
"react-inspector": "4.0.0",
|
||||
"react-loader": "2.4.5",
|
||||
"react-select": "3.0.8",
|
||||
"webpack": "4.35.3",
|
||||
"webpack-cli": "3.3.2"
|
||||
},
|
||||
|
||||
@@ -322,6 +322,15 @@
|
||||
}
|
||||
|
||||
.setup-project-modal {
|
||||
form {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.loader {
|
||||
position: relative;
|
||||
min-height: 181px;
|
||||
}
|
||||
|
||||
a>i {
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
@@ -345,34 +354,14 @@
|
||||
}
|
||||
|
||||
.owner-parts {
|
||||
overflow: auto;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.owner-part-one {
|
||||
float: left;
|
||||
width: 42%;
|
||||
margin-right: 1%;
|
||||
}
|
||||
|
||||
.owner-part-two {
|
||||
float: left;
|
||||
width: 57%;
|
||||
}
|
||||
|
||||
.radio + .radio {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.form-horizontal {
|
||||
background: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
|
||||
.form-group {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.help-block {
|
||||
@@ -390,22 +379,10 @@
|
||||
border-color: #dadada !important;
|
||||
}
|
||||
|
||||
.btn-group .btn {
|
||||
padding: 4px 12px;
|
||||
|
||||
i {
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.manage-orgs-btn {
|
||||
padding: 0;
|
||||
font-size: 12px;
|
||||
margin-top: 20px;
|
||||
line-height: 30px;
|
||||
line-height: 20px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
@@ -415,7 +392,7 @@
|
||||
}
|
||||
|
||||
.well.empty-select-orgs {
|
||||
margin-top: 20px;
|
||||
margin-top: 10px;
|
||||
|
||||
a.btn.btn-link {
|
||||
padding: 0;
|
||||
@@ -429,6 +406,7 @@
|
||||
.user-avatar {
|
||||
position: relative;
|
||||
top: -2px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.control-label {
|
||||
@@ -443,7 +421,7 @@
|
||||
|
||||
input[type='text'].form-control {
|
||||
padding: 3px 6px;
|
||||
height: 28px;
|
||||
height: 38px;
|
||||
}
|
||||
|
||||
.privacy-radio {
|
||||
@@ -469,6 +447,8 @@
|
||||
|
||||
.actions.form-group {
|
||||
margin-bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
|
||||
button {
|
||||
position: relative;
|
||||
@@ -478,12 +458,13 @@
|
||||
.text-danger {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.alert-danger {
|
||||
margin: 0 0 1em;
|
||||
pre.alert-danger {
|
||||
margin: 1em 0;
|
||||
padding: 5px;
|
||||
max-height: 200px;
|
||||
overflow: auto;
|
||||
text-align: left;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,11 +512,9 @@
|
||||
}
|
||||
|
||||
.select-orgs {
|
||||
overflow: auto;
|
||||
|
||||
select {
|
||||
float: left;
|
||||
width: 205px;
|
||||
margin-top: 20px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,11 @@ import PropTypes from 'prop-types'
|
||||
import { observer } from 'mobx-react'
|
||||
import BootstrapModal from 'react-bootstrap-modal'
|
||||
import Loader from 'react-loader'
|
||||
import Select from 'react-select'
|
||||
import { gravatarUrl } from '../lib/utils'
|
||||
|
||||
import authStore from '../auth/auth-store'
|
||||
import ipc from '../lib/ipc'
|
||||
import { gravatarUrl } from '../lib/utils'
|
||||
import orgsStore from '../organizations/organizations-store'
|
||||
import orgsApi from '../organizations/organizations-api'
|
||||
|
||||
@@ -26,8 +27,7 @@ class SetupProject extends Component {
|
||||
error: null,
|
||||
projectName: this.props.project.displayName,
|
||||
public: null,
|
||||
owner: null,
|
||||
orgId: null,
|
||||
selectedOrg: {},
|
||||
showNameMissingError: false,
|
||||
isSubmitting: false,
|
||||
}
|
||||
@@ -75,10 +75,6 @@ class SetupProject extends Component {
|
||||
return null
|
||||
}
|
||||
|
||||
if (!orgsStore.isLoaded) {
|
||||
this._loading()
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='setup-project-modal modal-body os-dialog'>
|
||||
<BootstrapModal.Dismiss className='btn btn-link close'>x</BootstrapModal.Dismiss>
|
||||
@@ -91,7 +87,7 @@ class SetupProject extends Component {
|
||||
{this._accessSelector()}
|
||||
{this._error()}
|
||||
<div className='actions form-group'>
|
||||
<div className='pull-right'>
|
||||
<div>
|
||||
<button
|
||||
disabled={this.state.isSubmitting || this._formNotFilled()}
|
||||
className='btn btn-primary btn-block'
|
||||
@@ -110,15 +106,6 @@ class SetupProject extends Component {
|
||||
)
|
||||
}
|
||||
|
||||
_loading () {
|
||||
return (
|
||||
<div className='setup-project-modal modal-body os-dialog'>
|
||||
<BootstrapModal.Dismiss className='btn btn-link close'>x</BootstrapModal.Dismiss>
|
||||
<Loader color='#888' scale={0.5} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
_nameField () {
|
||||
return (
|
||||
<div className='form-group'>
|
||||
@@ -154,110 +141,91 @@ class SetupProject extends Component {
|
||||
<a onClick={this._openOrgDocs}>
|
||||
<i className='fas fa-question-circle'></i>
|
||||
</a>
|
||||
|
||||
</label>
|
||||
<a
|
||||
href='#'
|
||||
className='btn btn-link manage-orgs-btn pull-right'
|
||||
onClick={this._manageOrgs}>
|
||||
Manage organizations
|
||||
</a>
|
||||
</div>
|
||||
<div className='owner-parts'>
|
||||
<div>
|
||||
<div className='btn-group' data-toggle='buttons'>
|
||||
<label className={cs('btn btn-default', {
|
||||
'active': this.state.owner === 'me',
|
||||
})}>
|
||||
<input
|
||||
type='radio'
|
||||
name='owner-toggle'
|
||||
id='me'
|
||||
autoComplete='off'
|
||||
value='me'
|
||||
checked={this.state.owner === 'me'}
|
||||
onChange={this._updateOwner}
|
||||
/>
|
||||
<img
|
||||
className='user-avatar'
|
||||
height='13'
|
||||
width='13'
|
||||
src={`${gravatarUrl(authStore.user && authStore.user.email)}`}
|
||||
/>
|
||||
{' '}Me
|
||||
</label>
|
||||
<label className={`btn btn-default ${this.state.owner === 'org' ? 'active' : ''}`}>
|
||||
<input
|
||||
type='radio'
|
||||
name='owner-toggle'
|
||||
id='org'
|
||||
autoComplete='off'
|
||||
value='org'
|
||||
checked={this.state.owner === 'org'}
|
||||
onChange={this._updateOwner}
|
||||
/>
|
||||
<i className='far fa-building'></i>
|
||||
{' '}An Organization
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className='select-orgs'>
|
||||
<div className={cs({ 'hidden': this.state.owner !== 'org' || this._hasOrgsOtherThanDefault() })}>
|
||||
<div className='empty-select-orgs well'>
|
||||
<p>You don't have any organizations yet.</p>
|
||||
<p>Organizations can help you manage projects, including billing.</p>
|
||||
<p>
|
||||
<a
|
||||
href='#'
|
||||
className={cs('btn btn-link', { 'hidden': this.state.owner !== 'org' })}
|
||||
onClick={this._manageOrgs}>
|
||||
<i className='fas fa-plus'></i>{' '}
|
||||
Create organization
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{this._orgSelector()}
|
||||
{
|
||||
orgsStore.isLoaded ?
|
||||
this._hasOrgs() ?
|
||||
this._orgSelector() :
|
||||
<div className='empty-select-orgs well'>
|
||||
<p>You don't have any organizations yet.</p>
|
||||
<p>Organizations can help you manage projects, including billing.</p>
|
||||
<p>
|
||||
<a
|
||||
href='#'
|
||||
className='btn btn-link'
|
||||
onClick={this._manageOrgs}>
|
||||
<i className='fas fa-plus'></i>{' '}
|
||||
Create organization
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
: <Loader color='#888' scale={0.5} />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
_hasOrgsOtherThanDefault () {
|
||||
return orgsStore.orgs.length > 1
|
||||
_hasOrgs () {
|
||||
return orgsStore.orgs.length
|
||||
}
|
||||
|
||||
_orgSelectValue (options) {
|
||||
if (!_.isEmpty(this.state.selectedOrg)) {
|
||||
return this.state.selectedOrg
|
||||
}
|
||||
|
||||
return this._hasDefaultOrg() ?
|
||||
_.find(options, { default: true }) :
|
||||
options[0]
|
||||
}
|
||||
|
||||
_orgSelector () {
|
||||
return (
|
||||
<div className={cs({ 'hidden': this.state.owner !== 'org' || !(this._hasOrgsOtherThanDefault()) })}>
|
||||
<select
|
||||
ref='orgId'
|
||||
id='organizations-select'
|
||||
className='form-control float-left'
|
||||
value={this.state.orgId || ''}
|
||||
onChange={this._updateOrgId}
|
||||
>
|
||||
<option value=''>-- Select organization --</option>
|
||||
{_.map(orgsStore.orgs, (org) => {
|
||||
if (org.default) return null
|
||||
const options = _.map(orgsStore.orgs, (org) => {
|
||||
return {
|
||||
value: org.id,
|
||||
default: org.default,
|
||||
label: org.default ?
|
||||
<div>
|
||||
<img
|
||||
className='user-avatar'
|
||||
height='13'
|
||||
width='13'
|
||||
src={`${gravatarUrl(authStore.user && authStore.user.email)}`}
|
||||
/>
|
||||
Your personal organization
|
||||
</div> : org.name,
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<option
|
||||
key={org.id}
|
||||
value={org.id}
|
||||
>
|
||||
{org.name}
|
||||
</option>
|
||||
)
|
||||
})}
|
||||
</select>
|
||||
<a
|
||||
href='#'
|
||||
className='btn btn-link manage-orgs-btn float-left'
|
||||
onClick={this._manageOrgs}>
|
||||
(manage organizations)
|
||||
</a>
|
||||
return (
|
||||
<div className={!this._hasOrgs() ? 'hidden' : ''}>
|
||||
<Select
|
||||
className='organizations-select'
|
||||
classNamePrefix='organizations-select'
|
||||
value={this._orgSelectValue(options)}
|
||||
onChange={this._updateSelectedOrg}
|
||||
isLoading={!orgsStore.isLoaded}
|
||||
options={options}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
_accessSelector () {
|
||||
return (
|
||||
<div className={cs({ 'hidden': !this.state.orgId })}>
|
||||
<div className={cs({ 'hidden': !this._hasOrgs() })}>
|
||||
<hr />
|
||||
<label htmlFor='projectName' className='control-label'>
|
||||
Who should see the runs and recordings?
|
||||
@@ -334,17 +302,15 @@ class SetupProject extends Component {
|
||||
)
|
||||
}
|
||||
|
||||
_updateOrgId = () => {
|
||||
const orgIsNotSelected = this.refs.orgId.value === '-- Select Organization --'
|
||||
|
||||
const orgId = orgIsNotSelected ? null : this.refs.orgId.value
|
||||
_updateSelectedOrg = (selectedOrg, action) => {
|
||||
const orgIsNotSelected = _.isEmpty(selectedOrg)
|
||||
|
||||
this.setState({
|
||||
orgId,
|
||||
selectedOrg,
|
||||
})
|
||||
|
||||
// deselect their choice for access
|
||||
// if they didn'tselect anything
|
||||
// if they didn't select anything
|
||||
if (orgIsNotSelected) {
|
||||
this.setState({
|
||||
public: null,
|
||||
@@ -362,24 +328,8 @@ class SetupProject extends Component {
|
||||
return _.trim(this.state.projectName)
|
||||
}
|
||||
|
||||
_updateOwner = (e) => {
|
||||
let owner = e.target.value
|
||||
|
||||
// if they clicked the same radio button that's
|
||||
// already selected, then ignore it
|
||||
if (this.state.owner === owner) return
|
||||
|
||||
const defaultOrg = _.find(orgsStore.orgs, { default: true })
|
||||
|
||||
let chosenOrgId = owner === 'me' ? defaultOrg.id : null
|
||||
|
||||
// we want to clear all selects below the radio buttons
|
||||
// otherwise it looks jarring to already have selects
|
||||
this.setState({
|
||||
owner,
|
||||
orgId: chosenOrgId,
|
||||
public: null,
|
||||
})
|
||||
_hasDefaultOrg () {
|
||||
return _.find(orgsStore.orgs, { default: true })
|
||||
}
|
||||
|
||||
_updateAccess = (e) => {
|
||||
@@ -409,7 +359,7 @@ class SetupProject extends Component {
|
||||
_setupProject () {
|
||||
ipc.setupDashboardProject({
|
||||
projectName: this.state.projectName,
|
||||
orgId: this.state.orgId,
|
||||
orgId: this.state.selectedOrg.value,
|
||||
public: this.state.public,
|
||||
})
|
||||
.then((projectDetails) => {
|
||||
|
||||
Reference in New Issue
Block a user