Add create/delete capabilities and UI
This commit is contained in:
+36
-3
@@ -2,7 +2,16 @@
|
||||
<div>
|
||||
<div class="uk-container uk-padding">
|
||||
<h1 v-text="$gettext('Accounts')" />
|
||||
<oc-grid v-if="numberOfSelectedAccounts > 0" key="selected-accounts-info" gutter="small" class="uk-flex-middle">
|
||||
<oc-button
|
||||
v-if="numberOfSelectedAccounts < 1"
|
||||
key="create-accounts-button"
|
||||
v-text="$gettext('Create new user')"
|
||||
variation="primary"
|
||||
:disabled="isAccountCreationInProgress || !isInitialized"
|
||||
:uk-tooltip="disabledCreateAccountBtnTooltip"
|
||||
@click="setAccountCreationProgress(true)"
|
||||
/>
|
||||
<oc-grid v-else key="selected-accounts-info" gutter="small" class="uk-flex-middle">
|
||||
<span v-text="selectionInfoText" />
|
||||
<span>|</span>
|
||||
<div>
|
||||
@@ -32,7 +41,11 @@
|
||||
</div>
|
||||
</oc-grid>
|
||||
<template v-if="isInitialized">
|
||||
<accounts-list :accounts="accounts" />
|
||||
<accounts-list
|
||||
:accounts="accounts"
|
||||
:is-create-new-row-displayed="isAccountCreationInProgress"
|
||||
@cancelAccountCreation="setAccountCreationProgress(false)"
|
||||
/>
|
||||
</template>
|
||||
<oc-loader v-else />
|
||||
</div>
|
||||
@@ -45,6 +58,9 @@ import AccountsList from './accounts/AccountsList.vue'
|
||||
export default {
|
||||
name: 'App',
|
||||
components: { AccountsList },
|
||||
data: () => ({
|
||||
isAccountCreationInProgress: false
|
||||
}),
|
||||
computed: {
|
||||
...mapGetters('Accounts', ['isInitialized', 'getAccountsSorted']),
|
||||
...mapState('Accounts', ['selectedAccounts']),
|
||||
@@ -86,17 +102,34 @@ export default {
|
||||
}
|
||||
|
||||
return actions
|
||||
},
|
||||
|
||||
disabledCreateAccountBtnTooltip () {
|
||||
if (!this.isInitialized) {
|
||||
return this.$gettext('Loading users')
|
||||
}
|
||||
|
||||
if (this.isAccountCreationInProgress) {
|
||||
return this.$gettext('User creation is already in progress')
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('Accounts', ['initialize', 'toggleAccountStatus']),
|
||||
...mapMutations('Accounts', ['RESET_ACCOUNTS_SELECTION'])
|
||||
...mapMutations('Accounts', ['RESET_ACCOUNTS_SELECTION']),
|
||||
|
||||
setAccountCreationProgress (isInProgress) {
|
||||
this.isAccountCreationInProgress = isInProgress
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.initialize()
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.RESET_ACCOUNTS_SELECTION()
|
||||
this.setAccountCreationProgress(false)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
</oc-table-row>
|
||||
</oc-table-group>
|
||||
<oc-table-group>
|
||||
<accounts-list-new-account-row v-if="isCreateNewRowDisplayed" @cancel="emitCreationCancel" />
|
||||
<accounts-list-row
|
||||
v-for="account in accounts"
|
||||
:key="`account-list-row-${account.id}`"
|
||||
@@ -35,23 +36,34 @@
|
||||
<script>
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import AccountsListRow from './AccountsListRow.vue'
|
||||
import AccountsListNewAccountRow from './AccountsListNewAccountRow.vue'
|
||||
|
||||
export default {
|
||||
name: 'AccountsList',
|
||||
components: {
|
||||
AccountsListRow
|
||||
AccountsListRow,
|
||||
AccountsListNewAccountRow
|
||||
},
|
||||
props: {
|
||||
accounts: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
isCreateNewRowDisplayed: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('Accounts', ['areAllAccountsSelected'])
|
||||
},
|
||||
methods: {
|
||||
...mapActions('Accounts', ['toggleSelectionAll'])
|
||||
...mapActions('Accounts', ['toggleSelectionAll']),
|
||||
|
||||
emitCreationCancel () {
|
||||
this.$emit('cancelAccountCreation')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<oc-table-row>
|
||||
<oc-table-cell colspan="9">
|
||||
<oc-grid gutter="small">
|
||||
<label>
|
||||
<oc-text-input
|
||||
type="text"
|
||||
v-model="username"
|
||||
:error-message="usernameError"
|
||||
:placeholder="$gettext('Username')"
|
||||
@input="checkUsername"
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
<oc-text-input
|
||||
type="email"
|
||||
v-model="email"
|
||||
:error-message="emailError"
|
||||
:placeholder="$gettext('Email')"
|
||||
@input="checkEmail"
|
||||
/>
|
||||
</label>
|
||||
<label class="uk-flex uk-flex-middle">
|
||||
<oc-text-input
|
||||
:type="passwordInputType"
|
||||
v-model="password"
|
||||
:error-message="passwordError"
|
||||
:placeholder="$gettext('Password')"
|
||||
class="uk-margin-xsmall-right"
|
||||
@input="checkPassword"
|
||||
/>
|
||||
<oc-button variation="raw" :aria-label="$gettext('Display password')" @click="togglePasswordVisibility">
|
||||
<oc-icon name="remove_red_eye" aria-hidden="true" size="small" />
|
||||
</oc-button>
|
||||
</label>
|
||||
<div>
|
||||
<oc-button v-text="$gettext('Cancel')" @click="emitCancel" class="uk-margin-xsmall-right" />
|
||||
<oc-button v-text="$gettext('Create')" variation="primary" @click="createAccount" />
|
||||
</div>
|
||||
</oc-grid>
|
||||
</oc-table-cell>
|
||||
</oc-table-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import isEmail from 'validator/es/lib/isEmail'
|
||||
import isEmpty from 'validator/es/lib/isEmpty'
|
||||
import debounce from 'debounce'
|
||||
import { mapActions } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'AccountsListNewAccountRow',
|
||||
|
||||
data: () => ({
|
||||
username: '',
|
||||
usernameError: '',
|
||||
email: '',
|
||||
emailError: '',
|
||||
password: '',
|
||||
passwordError: '',
|
||||
passwordInputType: 'password'
|
||||
}),
|
||||
|
||||
methods: {
|
||||
...mapActions('Accounts', ['createNewAccount']),
|
||||
|
||||
emitCancel () {
|
||||
this.$emit('cancel')
|
||||
},
|
||||
createAccount () {
|
||||
this.checkUsername()
|
||||
this.checkEmail()
|
||||
this.checkPassword()
|
||||
|
||||
if (this.usernameError !== '' || this.emailError !== '' || this.passwordError !== '') {
|
||||
return
|
||||
}
|
||||
|
||||
this.createNewAccount({ username: this.username, email: this.email, password: this.password })
|
||||
},
|
||||
|
||||
checkUsername () {
|
||||
if (isEmpty(this.username)) {
|
||||
debounce(this.usernameError = this.$gettext('Username cannot be empty'), 500)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.usernameError = ''
|
||||
},
|
||||
|
||||
checkEmail () {
|
||||
if (isEmpty(this.email)) {
|
||||
debounce(this.emailError = this.$gettext('Email cannot be empty'), 500)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (!isEmail(this.email)) {
|
||||
debounce(this.emailError = this.$gettext('Invalid email address'), 500)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.emailError = ''
|
||||
},
|
||||
|
||||
checkPassword () {
|
||||
// Later on some restrictions might be applied here
|
||||
if (isEmpty(this.password)) {
|
||||
debounce(this.passwordError = this.$gettext('Password cannot be empty'), 500)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.passwordError = ''
|
||||
},
|
||||
|
||||
togglePasswordVisibility () {
|
||||
this.passwordInputType === 'password'
|
||||
? this.passwordInputType = 'text'
|
||||
: this.passwordInputType = 'password'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
+34
-1
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable camelcase */
|
||||
import { AccountsService_ListAccounts, AccountsService_UpdateAccount } from '../client/accounts'
|
||||
import { AccountsService_ListAccounts, AccountsService_UpdateAccount, AccountsService_CreateAccount } from '../client/accounts'
|
||||
import { RoleService_ListRoles } from '../client/settings'
|
||||
/* eslint-enable camelcase */
|
||||
import { injectAuthToken } from '../helpers/auth'
|
||||
@@ -56,6 +56,10 @@ const mutations = {
|
||||
|
||||
RESET_ACCOUNTS_SELECTION (state) {
|
||||
state.selectedAccounts = []
|
||||
},
|
||||
|
||||
PUSH_NEW_ACCOUNT (state, account) {
|
||||
state.accounts.push(account)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,6 +168,35 @@ const actions = {
|
||||
}
|
||||
|
||||
commit('RESET_ACCOUNTS_SELECTION')
|
||||
},
|
||||
async createNewAccount ({ rootGetters, commit, dispatch }, account) {
|
||||
injectAuthToken(rootGetters.user.token)
|
||||
|
||||
const response = await AccountsService_CreateAccount({
|
||||
$domain: rootGetters.configuration.server,
|
||||
body: {
|
||||
account: {
|
||||
on_premises_sam_account_name: account.username,
|
||||
mail: account.email,
|
||||
password_profile: {
|
||||
password: account.password
|
||||
},
|
||||
account_enabled: true,
|
||||
display_name: account.username
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (response.status === 201) {
|
||||
commit('PUSH_NEW_ACCOUNT', account)
|
||||
console.log(response)
|
||||
} else {
|
||||
dispatch('showMessage', {
|
||||
title: 'Failed to create account',
|
||||
desc: response.statusText,
|
||||
status: 'danger'
|
||||
}, { root: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user