Browse Source

Merge pull request #3193 from abpframework/feat/admin-email-password-for-new-tenant

feature: add admin email and password fields to new tenant form
pull/3213/head
Mehmet Erim 6 years ago
committed by GitHub
parent
commit
5e423bda16
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      npm/ng-packs/packages/core/src/lib/models/index.ts
  2. 20
      npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html
  3. 15
      npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts
  4. 5
      npm/ng-packs/packages/tenant-management/src/lib/models/tenant-management.ts
  5. 24
      npm/ng-packs/packages/tenant-management/src/lib/services/tenant-management.service.ts
  6. 2
      templates/app/react-native/package.json
  7. 64
      templates/app/react-native/src/screens/CreateUpdateTenant/CreateUpdateTenantForm.js
  8. 51
      templates/app/react-native/yarn.lock

2
npm/ng-packs/packages/core/src/lib/models/index.ts

@ -3,6 +3,6 @@ export * from './common';
export * from './config';
export * from './dtos';
export * from './profile';
export * from './replaceable-components';
export * from './replaceable-components';
export * from './rest';
export * from './session';

20
npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html

@ -140,6 +140,26 @@
<label for="name">{{ 'AbpTenantManagement::TenantName' | abpLocalization }}</label>
<input type="text" id="name" class="form-control" formControlName="name" autofocus />
</div>
<div class="form-group" *ngIf="tenantForm.controls.adminEmailAddress">
<label for="name">{{ 'AbpTenantManagement::DisplayName:AdminEmailAddress' | abpLocalization }}</label>
<input
autocomplete="email"
type="email"
id="admin-email-address"
class="form-control"
formControlName="adminEmailAddress"
/>
</div>
<div class="form-group" *ngIf="tenantForm.controls.adminPassword">
<label for="name">{{ 'AbpTenantManagement::DisplayName:AdminPassword' | abpLocalization }}</label>
<input
autocomplete="new-password"
type="password"
id="admin-password"
class="form-control"
formControlName="adminPassword"
/>
</div>
</div>
</form>
</ng-template>

15
npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts

@ -60,6 +60,10 @@ export class TenantsComponent implements OnInit {
sortKey = '';
get hasSelectedTenant(): boolean {
return Boolean(this.selected.id);
}
get useSharedDatabase(): boolean {
return this.defaultConnectionStringForm.get('useSharedDatabase').value;
}
@ -115,9 +119,18 @@ export class TenantsComponent implements OnInit {
}
private createTenantForm() {
this.tenantForm = this.fb.group({
const tenantForm = this.fb.group({
name: [this.selected.name || '', [Validators.required, Validators.maxLength(256)]],
adminEmailAddress: [null, [Validators.required, Validators.maxLength(256), Validators.email]],
adminPassword: [null, [Validators.required]],
});
if (this.hasSelectedTenant) {
tenantForm.removeControl('adminEmailAddress');
tenantForm.removeControl('adminPassword');
}
this.tenantForm = tenantForm;
}
private createDefaultConnectionStringForm() {

5
npm/ng-packs/packages/tenant-management/src/lib/models/tenant-management.ts

@ -14,11 +14,14 @@ export namespace TenantManagement {
}
export interface AddRequest {
adminEmailAddress: string;
adminPassword: string;
name: string;
}
export interface UpdateRequest extends AddRequest {
export interface UpdateRequest {
id: string;
name: string;
}
export interface DefaultConnectionStringRequest {

24
npm/ng-packs/packages/tenant-management/src/lib/services/tenant-management.service.ts

@ -4,7 +4,7 @@ import { RestService, Rest, ABP } from '@abp/ng.core';
import { TenantManagement } from '../models/tenant-management';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class TenantManagementService {
constructor(private rest: RestService) {}
@ -13,7 +13,7 @@ export class TenantManagementService {
const request: Rest.Request<null> = {
method: 'GET',
url: '/api/multi-tenancy/tenants',
params
params,
};
return this.rest.request<null, TenantManagement.Response>(request);
@ -22,7 +22,7 @@ export class TenantManagementService {
getTenantById(id: string): Observable<ABP.BasicItem> {
const request: Rest.Request<null> = {
method: 'GET',
url: `/api/multi-tenancy/tenants/${id}`
url: `/api/multi-tenancy/tenants/${id}`,
};
return this.rest.request<null, ABP.BasicItem>(request);
@ -31,7 +31,7 @@ export class TenantManagementService {
deleteTenant(id: string): Observable<null> {
const request: Rest.Request<null> = {
method: 'DELETE',
url: `/api/multi-tenancy/tenants/${id}`
url: `/api/multi-tenancy/tenants/${id}`,
};
return this.rest.request<null, null>(request);
@ -41,7 +41,7 @@ export class TenantManagementService {
const request: Rest.Request<TenantManagement.AddRequest> = {
method: 'POST',
url: '/api/multi-tenancy/tenants',
body
body,
};
return this.rest.request<TenantManagement.AddRequest, ABP.BasicItem>(request);
@ -54,10 +54,10 @@ export class TenantManagementService {
const request: Rest.Request<TenantManagement.UpdateRequest> = {
method: 'PUT',
url,
body
body,
};
return this.rest.request<TenantManagement.AddRequest, ABP.BasicItem>(request);
return this.rest.request<TenantManagement.UpdateRequest, ABP.BasicItem>(request);
}
getDefaultConnectionString(id: string): Observable<string> {
@ -66,18 +66,20 @@ export class TenantManagementService {
const request: Rest.Request<TenantManagement.DefaultConnectionStringRequest> = {
method: 'GET',
responseType: Rest.ResponseType.Text,
url
url,
};
return this.rest.request<TenantManagement.DefaultConnectionStringRequest, string>(request);
}
updateDefaultConnectionString(payload: TenantManagement.DefaultConnectionStringRequest): Observable<any> {
updateDefaultConnectionString(
payload: TenantManagement.DefaultConnectionStringRequest,
): Observable<any> {
const url = `/api/multi-tenancy/tenants/${payload.id}/default-connection-string`;
const request: Rest.Request<TenantManagement.DefaultConnectionStringRequest> = {
method: 'PUT',
url,
params: { defaultConnectionString: payload.defaultConnectionString }
params: { defaultConnectionString: payload.defaultConnectionString },
};
return this.rest.request<TenantManagement.DefaultConnectionStringRequest, any>(request);
}
@ -87,7 +89,7 @@ export class TenantManagementService {
const request: Rest.Request<TenantManagement.DefaultConnectionStringRequest> = {
method: 'DELETE',
url
url,
};
return this.rest.request<TenantManagement.DefaultConnectionStringRequest, any>(request);
}

2
templates/app/react-native/package.json

@ -24,7 +24,7 @@
"formik": "^2.1.2",
"i18n-js": "^3.5.1",
"lodash": "^4.17.15",
"native-base": "^2.13.8",
"native-base": "2.13.8",
"prop-types": "^15.7.2",
"react": "~16.9.0",
"react-dom": "~16.9.0",

64
templates/app/react-native/src/screens/CreateUpdateTenant/CreateUpdateTenantForm.js

@ -1,8 +1,8 @@
import { Formik } from 'formik';
import i18n from 'i18n-js';
import { Container, Content, Input, InputGroup, Label } from 'native-base';
import { Container, Content, Input, InputGroup, Label, Item, Icon } from 'native-base';
import PropTypes from 'prop-types';
import React, { useRef } from 'react';
import React, { useRef, useState } from 'react';
import { StyleSheet } from 'react-native';
import * as Yup from 'yup';
import FormButtons from '../../components/FormButtons/FormButtons';
@ -15,7 +15,10 @@ const validations = {
function CreateUpdateTenantForm({ editingTenant = {}, submit, remove }) {
const tenantNameRef = useRef();
const adminEmailRef = useRef();
const adminPasswordRef = useRef();
const [showAdminPassword, setShowAdminPassword] = useState(false);
const hasRemovePermission = usePermission('AbpTenantManagement.Tenants.Delete');
const onSubmit = values => {
@ -25,11 +28,25 @@ function CreateUpdateTenantForm({ editingTenant = {}, submit, remove }) {
});
};
const adminEmailAddressValidation = Yup.lazy(() =>
Yup.string()
.required('AbpAccount::ThisFieldIsRequired.')
.email('AbpAccount::ThisFieldIsNotAValidEmailAddress.'),
);
const adminPasswordValidation = Yup.lazy(() =>
Yup.string().required('AbpAccount::ThisFieldIsRequired.'),
);
return (
<Formik
enableReinitialize
validationSchema={Yup.object().shape({
...validations,
...(!editingTenant.id && {
adminEmailAddress: adminEmailAddressValidation,
adminPassword: adminPasswordValidation,
}),
})}
initialValues={{
lockoutEnabled: false,
@ -46,12 +63,55 @@ function CreateUpdateTenantForm({ editingTenant = {}, submit, remove }) {
<Input
abpInput
ref={tenantNameRef}
onSubmitEditing={() =>
!editingTenant.id ? adminEmailRef.current._root.focus() : null
}
returnKeyType={!editingTenant.id ? 'next' : 'done'}
onChangeText={handleChange('name')}
onBlur={handleBlur('name')}
value={values.name}
/>
</InputGroup>
<ValidationMessage>{errors.name}</ValidationMessage>
{!editingTenant.id ? (
<>
<InputGroup abpInputGroup>
<Label abpLabel>
{i18n.t('AbpTenantManagement::DisplayName:AdminEmailAddress')}
</Label>
<Input
abpInput
ref={adminEmailRef}
onSubmitEditing={() => adminPasswordRef.current._root.focus()}
returnKeyType="next"
onChangeText={handleChange('adminEmailAddress')}
onBlur={handleBlur('adminEmailAddress')}
value={values.adminEmailAddress}
/>
</InputGroup>
<ValidationMessage>{errors.adminEmailAddress}</ValidationMessage>
<InputGroup abpInputGroup>
<Label abpLabel>
{i18n.t('AbpTenantManagement::DisplayName:AdminPassword')}
</Label>
<Item abpInput>
<Input
ref={adminPasswordRef}
returnKeyType="done"
secureTextEntry={!showAdminPassword}
onChangeText={handleChange('adminPassword')}
onBlur={handleBlur('adminPassword')}
value={values.adminPassword}
/>
<Icon
name={showAdminPassword ? 'eye-off' : 'eye'}
onPress={() => setShowAdminPassword(!showAdminPassword)}
/>
</Item>
</InputGroup>
<ValidationMessage>{errors.adminPassword}</ValidationMessage>
</>
) : null}
</Content>
</Container>
<FormButtons

51
templates/app/react-native/yarn.lock

@ -1117,17 +1117,17 @@
use-subscription "^1.4.0"
"@react-navigation/drawer@^5.1.1":
version "5.2.0"
resolved "https://registry.yarnpkg.com/@react-navigation/drawer/-/drawer-5.2.0.tgz#dacff335908c759ff8fa294c07b2d75fe4ba7767"
integrity sha512-xySVAlt7Msu0swF23mg/seKGiCh5JiDmh0TE1/Mo5bDVH2tJ8prQgORWNg7hR40aN5dc90nyTLlAgM+0DB5tBg==
version "5.3.1"
resolved "https://registry.yarnpkg.com/@react-navigation/drawer/-/drawer-5.3.1.tgz#117946960a126e9e9248c63c8552f435cf7e9aed"
integrity sha512-s9VPXLzZeGWNy7CEaq468Q9T5fKPoHyiv2LAWVeEmXAhNUZ4jlVLsgJITb2OoXqOLxxIn4F/EluGFWkxdYdodw==
dependencies:
color "^3.1.2"
react-native-iphone-x-helper "^1.2.1"
"@react-navigation/native@^5.0.9":
version "5.0.10"
resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-5.0.10.tgz#bbb128cd963138d90f8327519088ae896fb22b4d"
integrity sha512-VoVKuiwOwYh8u+Y1rfLQ4mGXzBgjWVHFD1exhOIMIAymbEBV5rFZkS0D5SHbDpL+SVW6wovv4jK85Gdutd8mEg==
version "5.1.0"
resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-5.1.0.tgz#60aba3efe1cacaaba77a455f9cefd9a6bf4bf658"
integrity sha512-GW1HCEUOg+IBHoLQfQ73N6HMUtqPFp+9PIdH/479P1AWzD2DSZB4u9qs5WlXlbad3Z1Lw8l3Zo8Ct9sZfjh2Ug==
dependencies:
"@react-navigation/core" "^5.2.2"
@ -1139,9 +1139,9 @@
shortid "^2.2.15"
"@react-navigation/stack@^5.1.1":
version "5.2.0"
resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-5.2.0.tgz#e16138cd23b457594e790999552ab3d72e8e2707"
integrity sha512-lFTVV1S9YEPsIxzLUPY95Y2lqmday79uOadOopQkjq3JWmZTXBJDMW9jgV8B+F5EfUh0VabQ2zX06OfjxrvtUw==
version "5.2.1"
resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-5.2.1.tgz#47339ecc8e96a7565b636b9115956f4aae9eae34"
integrity sha512-iEP3QnSPcvKju8jRYa4c/GrtIYVAcsRScSqHl/M/Vh+73HgbhbJNMomiZNW0CZa9FZfYgpo8fBs29Q8rhn4q6A==
dependencies:
color "^3.1.2"
react-native-iphone-x-helper "^1.2.1"
@ -2484,9 +2484,9 @@ ee-first@1.1.1:
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
electron-to-chromium@^1.3.363:
version "1.3.377"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.377.tgz#b49d420b36ee6c48b0cd3137bfc7fec75f369b2e"
integrity sha512-cm2WzMKf/3dW5+hNANKm8GAW6SwIWOqLTJ6GPCD0Bbw1qJ9Wzm9nmx9M+byzSsgw8CdCv5fb/wzLFqVS5h6QrA==
version "1.3.378"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.378.tgz#18c572cbb54bf5b2769855597cdc7511c02b481f"
integrity sha512-nBp/AfhaVIOnfwgL1CZxt80IcqWcyYXiX6v5gflAksxy+SzBVz7A7UWR1Nos92c9ofXW74V9PoapzRb0jJfYXw==
emoji-regex@^7.0.1, emoji-regex@^7.0.2:
version "7.0.3"
@ -4569,11 +4569,6 @@ minimatch@^3.0.4:
dependencies:
brace-expansion "^1.1.7"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
@ -4603,11 +4598,11 @@ mixin-deep@^1.2.0:
is-extendable "^1.0.1"
mkdirp@^0.5.0, mkdirp@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
version "0.5.3"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.3.tgz#5a514b7179259287952881e94410ec5465659f8c"
integrity sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==
dependencies:
minimist "0.0.8"
minimist "^1.2.5"
morgan@^1.9.0:
version "1.9.1"
@ -4681,10 +4676,10 @@ native-base-shoutem-theme@0.3.1:
lodash "^4.17.14"
prop-types "^15.5.10"
native-base@^2.13.8:
version "2.13.12"
resolved "https://registry.yarnpkg.com/native-base/-/native-base-2.13.12.tgz#06020b46019964ddaef3a646ec07e72008018efc"
integrity sha512-LdKGNXisbmQ0vDHG86McZKIFTlRyo+OQdJpqmQ05Yf7CGlMbBykJZCFe9rdiee5pLq20xiChe/jXbzFdWcysrg==
native-base@2.13.8:
version "2.13.8"
resolved "https://registry.yarnpkg.com/native-base/-/native-base-2.13.8.tgz#817dfaf74ec63cd17f48991fab452fdc75103db9"
integrity sha512-47Wm7bjH5Dc99gBUeVvsURyADU97aiLMLPGX4ewPgR9kW47TD9slS/Y5vGMToBgz1bsku9anXgN2T1rpdQbpFA==
dependencies:
blueimp-md5 "^2.5.0"
clamp "^1.0.1"
@ -5689,9 +5684,9 @@ regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.4:
integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==
regenerator-transform@^0.14.2:
version "0.14.3"
resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.3.tgz#54aebff2ef58c0ae61e695ad1b9a9d65995fff78"
integrity sha512-zXHNKJspmONxBViAb3ZUmFoFPnTBs3zFhCEZJiwp/gkNzxVbTqNJVjYKx6Qk1tQ1P4XLf4TbH9+KBB7wGoAaUw==
version "0.14.4"
resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.4.tgz#5266857896518d1616a78a0479337a30ea974cc7"
integrity sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==
dependencies:
"@babel/runtime" "^7.8.4"
private "^0.1.8"

Loading…
Cancel
Save