@sumaris-net/ngx-components 2.6.6-rc6 → 2.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/src/app/core/account/account.page.mjs +16 -14
- package/esm2020/src/app/core/graphql/graphql.service.mjs +6 -1
- package/esm2020/src/app/core/services/account.service.mjs +47 -20
- package/esm2020/src/app/core/services/config/core.config.mjs +4 -4
- package/esm2020/src/app/core/services/platform.service.mjs +17 -7
- package/esm2020/src/app/shared/services/entity-service.class.mjs +1 -1
- package/esm2020/src/app/shared/services/startable-service.class.mjs +2 -2
- package/esm2020/src/environments/environment.mjs +19 -16
- package/fesm2015/sumaris-net.ngx-components.mjs +103 -56
- package/fesm2015/sumaris-net.ngx-components.mjs.map +1 -1
- package/fesm2020/sumaris-net.ngx-components.mjs +103 -56
- package/fesm2020/sumaris-net.ngx-components.mjs.map +1 -1
- package/package.json +1 -1
- package/src/app/core/account/account.page.d.ts +3 -2
- package/src/app/core/services/account.service.d.ts +4 -0
- package/src/app/core/services/config/core.config.d.ts +1 -1
- package/src/assets/environments/environment-test.json +6 -0
- package/src/assets/i18n/en-US.json +7 -4
- package/src/assets/i18n/en.json +7 -4
- package/src/assets/i18n/fr.json +1 -3
- package/src/assets/manifest.json +1 -1
|
@@ -10711,7 +10711,7 @@ let StartableService = class StartableService {
|
|
|
10711
10711
|
}
|
|
10712
10712
|
async restart(opts) {
|
|
10713
10713
|
if (this._startPromise)
|
|
10714
|
-
await this._startPromise; // Wait end of previous
|
|
10714
|
+
await this._startPromise; // Wait end of previous start, if running
|
|
10715
10715
|
if (this._started)
|
|
10716
10716
|
await this.stop(); // Then stop if started
|
|
10717
10717
|
return this.start(opts); // Then start again
|
|
@@ -11626,9 +11626,9 @@ const CORE_CONFIG_OPTIONS = Object.freeze({
|
|
|
11626
11626
|
],
|
|
11627
11627
|
defaultValue: 'token'
|
|
11628
11628
|
},
|
|
11629
|
-
|
|
11630
|
-
key: 'sumaris.auth.token.enabled',
|
|
11631
|
-
label: 'CONFIGURATION.OPTIONS.
|
|
11629
|
+
AUTH_API_TOKEN_ENABLED: {
|
|
11630
|
+
key: 'sumaris.auth.api.token.enabled',
|
|
11631
|
+
label: 'CONFIGURATION.OPTIONS.ENABLE_AUTH_API_TOKENS',
|
|
11632
11632
|
type: 'boolean',
|
|
11633
11633
|
defaultValue: false,
|
|
11634
11634
|
isTransient: true
|
|
@@ -13813,7 +13813,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
13813
13813
|
const environment = Object.freeze({
|
|
13814
13814
|
name: '@sumaris-net/ngx-components',
|
|
13815
13815
|
version: undefined,
|
|
13816
|
+
// Do NOT set to false - because this value will be used by releases
|
|
13816
13817
|
production: true,
|
|
13818
|
+
// Do NOT set - because this value will be used by releases
|
|
13819
|
+
//externalEnvironmentUrl: null,
|
|
13817
13820
|
baseUrl: '/',
|
|
13818
13821
|
defaultLocale: 'fr',
|
|
13819
13822
|
defaultLatLongFormat: 'DDMM',
|
|
@@ -13825,51 +13828,51 @@ const environment = Object.freeze({
|
|
|
13825
13828
|
peerMinVersion: '1.8.0',
|
|
13826
13829
|
defaultPeer: {
|
|
13827
13830
|
host: '192.168.0.45',
|
|
13828
|
-
port: 8080
|
|
13831
|
+
port: 8080,
|
|
13829
13832
|
},
|
|
13830
13833
|
defaultPeers: [
|
|
13831
13834
|
{
|
|
13832
13835
|
host: 'localhost',
|
|
13833
|
-
port: 8080
|
|
13836
|
+
port: 8080,
|
|
13834
13837
|
},
|
|
13835
13838
|
{
|
|
13836
13839
|
host: 'localhost',
|
|
13837
|
-
port: 8081
|
|
13840
|
+
port: 8081,
|
|
13838
13841
|
},
|
|
13839
13842
|
{
|
|
13840
13843
|
host: '192.168.0.45',
|
|
13841
|
-
port: 8080
|
|
13844
|
+
port: 8080,
|
|
13842
13845
|
},
|
|
13843
13846
|
{
|
|
13844
13847
|
host: '192.168.0.24',
|
|
13845
|
-
port: 8080
|
|
13848
|
+
port: 8080,
|
|
13846
13849
|
},
|
|
13847
13850
|
{
|
|
13848
13851
|
host: '192.168.0.29',
|
|
13849
|
-
port: 8080
|
|
13852
|
+
port: 8080,
|
|
13850
13853
|
},
|
|
13851
13854
|
{
|
|
13852
13855
|
host: 'sih.sfa.sc',
|
|
13853
|
-
port: 443
|
|
13856
|
+
port: 443,
|
|
13854
13857
|
},
|
|
13855
13858
|
{
|
|
13856
13859
|
host: 'test.sumaris.net',
|
|
13857
|
-
port: 443
|
|
13860
|
+
port: 443,
|
|
13858
13861
|
},
|
|
13859
13862
|
{
|
|
13860
13863
|
host: 'open.sumaris.net',
|
|
13861
|
-
port: 443
|
|
13864
|
+
port: 443,
|
|
13862
13865
|
},
|
|
13863
13866
|
{
|
|
13864
13867
|
host: 'server.e-is.pro',
|
|
13865
|
-
port: 443
|
|
13866
|
-
}
|
|
13868
|
+
port: 443,
|
|
13869
|
+
},
|
|
13867
13870
|
],
|
|
13868
13871
|
defaultAppName: 'SUMARiS',
|
|
13869
13872
|
defaultAndroidInstallUrl: 'https://play.google.com/store/apps/details?id=net.sumaris.app',
|
|
13870
13873
|
// Storage
|
|
13871
13874
|
storage: {
|
|
13872
|
-
driverOrder: [StorageDrivers.SQLLite, StorageDrivers.IndexedDB, StorageDrivers.WebSQL, StorageDrivers.LocalStorage]
|
|
13875
|
+
driverOrder: [StorageDrivers.SQLLite, StorageDrivers.IndexedDB, StorageDrivers.WebSQL, StorageDrivers.LocalStorage],
|
|
13873
13876
|
},
|
|
13874
13877
|
// About
|
|
13875
13878
|
sourceUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/ngx-sumaris-components',
|
|
@@ -13885,12 +13888,12 @@ const environment = Object.freeze({
|
|
|
13885
13888
|
},
|
|
13886
13889
|
account: {
|
|
13887
13890
|
enableListenChanges: true,
|
|
13888
|
-
listenIntervalInSeconds: 60
|
|
13891
|
+
listenIntervalInSeconds: 60,
|
|
13889
13892
|
},
|
|
13890
13893
|
entityEditor: {
|
|
13891
13894
|
enableListenChanges: true,
|
|
13892
|
-
listenIntervalInSeconds: 60
|
|
13893
|
-
}
|
|
13895
|
+
listenIntervalInSeconds: 60,
|
|
13896
|
+
},
|
|
13894
13897
|
});
|
|
13895
13898
|
|
|
13896
13899
|
class EntityClasses {
|
|
@@ -17413,6 +17416,10 @@ class GraphqlService extends StartableService {
|
|
|
17413
17416
|
webSocketImpl: AppWebSocket,
|
|
17414
17417
|
url: wsUrl,
|
|
17415
17418
|
shouldRetry: (errOrCloseEvent) => {
|
|
17419
|
+
// If WS URL changed, then do not retry
|
|
17420
|
+
if (wsUrl !== this.wsParams.url) {
|
|
17421
|
+
return false;
|
|
17422
|
+
}
|
|
17416
17423
|
console.warn('[graphql-service] [WS] Trying to reconnect...', errOrCloseEvent);
|
|
17417
17424
|
return true;
|
|
17418
17425
|
},
|
|
@@ -17560,6 +17567,7 @@ class GraphqlService extends StartableService {
|
|
|
17560
17567
|
return;
|
|
17561
17568
|
console.info('[graphql] Resetting Apollo client...');
|
|
17562
17569
|
client.stop();
|
|
17570
|
+
this.onResetAuth.next();
|
|
17563
17571
|
await Promise.all([
|
|
17564
17572
|
client.clearStore(),
|
|
17565
17573
|
this.clearCache(client)
|
|
@@ -17999,8 +18007,6 @@ const Fragments = {
|
|
|
17999
18007
|
lastName
|
|
18000
18008
|
email
|
|
18001
18009
|
pubkey
|
|
18002
|
-
# username
|
|
18003
|
-
# usernameExtranet
|
|
18004
18010
|
avatar
|
|
18005
18011
|
statusId
|
|
18006
18012
|
updateDate
|
|
@@ -18009,9 +18015,6 @@ const Fragments = {
|
|
|
18009
18015
|
settings {
|
|
18010
18016
|
...UserSettingsFragment
|
|
18011
18017
|
}
|
|
18012
|
-
tokens {
|
|
18013
|
-
...UserTokenFragment
|
|
18014
|
-
}
|
|
18015
18018
|
department {
|
|
18016
18019
|
id
|
|
18017
18020
|
label
|
|
@@ -18042,34 +18045,53 @@ const Fragments = {
|
|
|
18042
18045
|
__typename
|
|
18043
18046
|
}`
|
|
18044
18047
|
};
|
|
18045
|
-
//
|
|
18046
|
-
const
|
|
18047
|
-
|
|
18048
|
+
// Account queries
|
|
18049
|
+
const Queries = {
|
|
18050
|
+
load: gql `query Account {
|
|
18048
18051
|
data: account {
|
|
18049
18052
|
...AccountFragment
|
|
18050
18053
|
}
|
|
18051
18054
|
}
|
|
18052
18055
|
${Fragments.account}
|
|
18056
|
+
${Fragments.settings}`,
|
|
18057
|
+
loadWithTokens: gql `query AccountWithToken {
|
|
18058
|
+
data: account {
|
|
18059
|
+
...AccountFragment
|
|
18060
|
+
tokens {
|
|
18061
|
+
...UserTokenFragment
|
|
18062
|
+
}
|
|
18063
|
+
}
|
|
18064
|
+
}
|
|
18065
|
+
${Fragments.account}
|
|
18053
18066
|
${Fragments.settings}
|
|
18054
|
-
${Fragments.token}
|
|
18055
|
-
|
|
18067
|
+
${Fragments.token}`,
|
|
18068
|
+
};
|
|
18056
18069
|
// Check email query
|
|
18057
18070
|
const IsEmailExistsQuery = gql `
|
|
18058
18071
|
query IsEmailExists($email: String, $hash: String){
|
|
18059
18072
|
isEmailExists(email: $email, hash: $hash)
|
|
18060
18073
|
}
|
|
18061
18074
|
`;
|
|
18062
|
-
//
|
|
18063
|
-
const
|
|
18075
|
+
// Account mutations
|
|
18076
|
+
const Mutations$1 = {
|
|
18064
18077
|
save: gql ` mutation SaveAccount($data:AccountVOInput){
|
|
18065
18078
|
data: saveAccount(account: $data){
|
|
18066
18079
|
...AccountFragment
|
|
18067
18080
|
}
|
|
18068
18081
|
}
|
|
18069
18082
|
${Fragments.account}
|
|
18070
|
-
${Fragments.
|
|
18083
|
+
${Fragments.settings}`,
|
|
18084
|
+
saveWithTokens: gql ` mutation SaveAccountWithTokens($data:AccountVOInput){
|
|
18085
|
+
data: saveAccount(account: $data){
|
|
18086
|
+
...AccountFragment
|
|
18087
|
+
tokens {
|
|
18088
|
+
...UserTokenFragment
|
|
18089
|
+
}
|
|
18090
|
+
}
|
|
18091
|
+
}
|
|
18092
|
+
${Fragments.account}
|
|
18071
18093
|
${Fragments.settings}
|
|
18072
|
-
`,
|
|
18094
|
+
${Fragments.token}`,
|
|
18073
18095
|
create: gql `mutation CreateAccount($data:AccountVOInput){
|
|
18074
18096
|
data: createAccount(account: $data){
|
|
18075
18097
|
...AccountFragment
|
|
@@ -18077,7 +18099,6 @@ const AccountMutations = {
|
|
|
18077
18099
|
}
|
|
18078
18100
|
${Fragments.account}
|
|
18079
18101
|
${Fragments.settings}
|
|
18080
|
-
${Fragments.token}
|
|
18081
18102
|
`,
|
|
18082
18103
|
saveSettings: gql `mutation SaveSettings($data:UserSettingsVOInput){
|
|
18083
18104
|
data: saveSettings(settings: $data){
|
|
@@ -18151,6 +18172,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
18151
18172
|
};
|
|
18152
18173
|
this._$additionalFields = new BehaviorSubject([]);
|
|
18153
18174
|
this._tokenType$ = new BehaviorSubject(undefined);
|
|
18175
|
+
this._apiTokenEnabled = true;
|
|
18154
18176
|
this._enableListenChanges = (!environment.account || environment.account.enableListenChanges !== false); // True by default
|
|
18155
18177
|
this._listenIntervalInSeconds = toNumber(environment.account && environment.account.listenIntervalInSeconds, 0); // no timer by default
|
|
18156
18178
|
this._debug = !environment.production;
|
|
@@ -18201,6 +18223,12 @@ class AccountService extends BaseGraphqlService {
|
|
|
18201
18223
|
this.onAuthBasicChange.next(undefined);
|
|
18202
18224
|
}
|
|
18203
18225
|
}
|
|
18226
|
+
get apiTokenEnabled() {
|
|
18227
|
+
return this._apiTokenEnabled;
|
|
18228
|
+
}
|
|
18229
|
+
set apiTokenEnabled(value) {
|
|
18230
|
+
this._apiTokenEnabled = value;
|
|
18231
|
+
}
|
|
18204
18232
|
async ngOnStart() {
|
|
18205
18233
|
await Promise.all([
|
|
18206
18234
|
this.settings.ready(),
|
|
@@ -18575,8 +18603,9 @@ class AccountService extends BaseGraphqlService {
|
|
|
18575
18603
|
}
|
|
18576
18604
|
// Load remotely
|
|
18577
18605
|
else {
|
|
18606
|
+
const query = opts?.query || (this.apiTokenEnabled ? Queries.loadWithTokens : Queries.load);
|
|
18578
18607
|
const { data } = await this.graphql.query({
|
|
18579
|
-
query
|
|
18608
|
+
query,
|
|
18580
18609
|
error: { code: ErrorCodes.LOAD_ACCOUNT_ERROR, message: 'ERROR.LOAD_ACCOUNT_ERROR' },
|
|
18581
18610
|
fetchPolicy: opts && opts.fetchPolicy || 'no-cache' || undefined
|
|
18582
18611
|
});
|
|
@@ -18944,9 +18973,11 @@ class AccountService extends BaseGraphqlService {
|
|
|
18944
18973
|
const json = account.asObject(MINIFY_ENTITY_FOR_POD);
|
|
18945
18974
|
// User not allow to change his profiles
|
|
18946
18975
|
delete json.profiles;
|
|
18976
|
+
const mutation = isNew ? Mutations$1.create :
|
|
18977
|
+
(this._apiTokenEnabled ? Mutations$1.saveWithTokens : Mutations$1.save);
|
|
18947
18978
|
// Execute mutation
|
|
18948
18979
|
const { data } = await this.graphql.mutate({
|
|
18949
|
-
mutation
|
|
18980
|
+
mutation,
|
|
18950
18981
|
variables: { data: json },
|
|
18951
18982
|
error: {
|
|
18952
18983
|
code: ErrorCodes.SAVE_ACCOUNT_ERROR,
|
|
@@ -18971,7 +19002,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
18971
19002
|
const json = settings.asObject(MINIFY_ENTITY_FOR_POD);
|
|
18972
19003
|
// Execute mutation
|
|
18973
19004
|
const { data } = await this.graphql.mutate({
|
|
18974
|
-
mutation:
|
|
19005
|
+
mutation: Mutations$1.saveSettings,
|
|
18975
19006
|
variables: { data: json },
|
|
18976
19007
|
error: {
|
|
18977
19008
|
code: ErrorCodes.SAVE_SETTINGS_ERROR,
|
|
@@ -19116,8 +19147,12 @@ class AccountService extends BaseGraphqlService {
|
|
|
19116
19147
|
return;
|
|
19117
19148
|
target.id = source.id || target.id;
|
|
19118
19149
|
target.updateDate = source.updateDate || target.updateDate;
|
|
19150
|
+
// Update settings
|
|
19119
19151
|
this.copyIdAndUpdateDateSettings(source.settings, target.settings);
|
|
19120
|
-
|
|
19152
|
+
// Update tokens
|
|
19153
|
+
if (this._apiTokenEnabled) {
|
|
19154
|
+
this.copyIdAndUpdateDateToken(source.tokens, target.tokens);
|
|
19155
|
+
}
|
|
19121
19156
|
}
|
|
19122
19157
|
copyIdAndUpdateDateSettings(source, target) {
|
|
19123
19158
|
if (!source)
|
|
@@ -19728,12 +19763,22 @@ class PlatformService extends StartableService {
|
|
|
19728
19763
|
)
|
|
19729
19764
|
.subscribe(type => this.configureCache(type !== 'none')));
|
|
19730
19765
|
console.info(`[platform] Starting platform [OK] {mobile: ${this._mobile}, capacitor: ${this._capacitor}, web: ${this.isWeb()}, downloader: ${this.canDownload}} in ${Date.now() - now}ms`);
|
|
19731
|
-
// Update authentication type
|
|
19732
19766
|
this.registerSubscription(this.configService.config
|
|
19733
|
-
.
|
|
19734
|
-
|
|
19735
|
-
|
|
19736
|
-
|
|
19767
|
+
.subscribe(config => {
|
|
19768
|
+
if (!config)
|
|
19769
|
+
return; // Skip
|
|
19770
|
+
// Update authentication type
|
|
19771
|
+
const tokenType = config.getProperty(CORE_CONFIG_OPTIONS.AUTH_TOKEN_TYPE);
|
|
19772
|
+
if (isNotNilOrBlank(tokenType) && this.accountService.tokenType !== tokenType) {
|
|
19773
|
+
console.info(`[platform] Using auth token type {${tokenType}}`);
|
|
19774
|
+
this.accountService.tokenType = tokenType;
|
|
19775
|
+
}
|
|
19776
|
+
// Enable auth API using tokens
|
|
19777
|
+
const authApiEnabled = config.getPropertyAsBoolean(CORE_CONFIG_OPTIONS.AUTH_API_TOKEN_ENABLED);
|
|
19778
|
+
if (isNotNil(authApiEnabled) && authApiEnabled !== this.accountService.apiTokenEnabled) {
|
|
19779
|
+
console.info(`[platform] Using auth API tokens ? ${authApiEnabled}}`);
|
|
19780
|
+
this.accountService.apiTokenEnabled = authApiEnabled;
|
|
19781
|
+
}
|
|
19737
19782
|
}));
|
|
19738
19783
|
if (this._mobile) {
|
|
19739
19784
|
// Hide the splashscreen (if mobile) - after 1s - and play start sound
|
|
@@ -31570,7 +31615,7 @@ class AccountPage extends AppForm {
|
|
|
31570
31615
|
this.saving = false;
|
|
31571
31616
|
this.submitted = false;
|
|
31572
31617
|
this.accountReadOnly = false;
|
|
31573
|
-
this.
|
|
31618
|
+
this.showApiTokens = false;
|
|
31574
31619
|
this.locales = locales;
|
|
31575
31620
|
// Add settings fo form
|
|
31576
31621
|
// this.settingsForm = settingsValidatorService.getFormGroup(accountService.account && accountService.account.settings);
|
|
@@ -31609,10 +31654,7 @@ class AccountPage extends AppForm {
|
|
|
31609
31654
|
this.markAsLoaded();
|
|
31610
31655
|
}
|
|
31611
31656
|
}));
|
|
31612
|
-
this.registerSubscription(this.configService.config.subscribe((
|
|
31613
|
-
this.accountReadOnly = value.getPropertyAsBoolean(CORE_CONFIG_OPTIONS.ACCOUNT_READONLY);
|
|
31614
|
-
this.authTokenEnabled = value.getPropertyAsBoolean(CORE_CONFIG_OPTIONS.AUTH_TOKEN_ENABLED);
|
|
31615
|
-
}));
|
|
31657
|
+
this.registerSubscription(this.configService.config.subscribe((config) => this.onConfigLoaded(config)));
|
|
31616
31658
|
// Realign tab, after a delay because the tab can be disabled when component is created
|
|
31617
31659
|
setTimeout(() => this.tabGroup.realignInkBar(), 500);
|
|
31618
31660
|
}
|
|
@@ -31632,9 +31674,9 @@ class AccountPage extends AppForm {
|
|
|
31632
31674
|
this.configService.config,
|
|
31633
31675
|
this.network.onNetworkStatusChanges.pipe(map((connectionType) => connectionType !== 'none')),
|
|
31634
31676
|
]).subscribe(([config, online]) => {
|
|
31677
|
+
this.onConfigLoaded(config);
|
|
31635
31678
|
if (online) {
|
|
31636
|
-
|
|
31637
|
-
this.enable({ accountReadOnly });
|
|
31679
|
+
this.enable();
|
|
31638
31680
|
this.markAsPristine();
|
|
31639
31681
|
this.startListenChanges();
|
|
31640
31682
|
}
|
|
@@ -31769,13 +31811,14 @@ class AccountPage extends AppForm {
|
|
|
31769
31811
|
}
|
|
31770
31812
|
}
|
|
31771
31813
|
enable(opts) {
|
|
31772
|
-
super.enable();
|
|
31814
|
+
super.enable(opts);
|
|
31773
31815
|
// Some fields are always disable
|
|
31774
31816
|
this.form.controls.email.disable();
|
|
31775
31817
|
this.form.controls.mainProfile.disable();
|
|
31776
31818
|
this.form.controls.pubkey.disable();
|
|
31777
31819
|
// Disable account fields if readonly by configuration
|
|
31778
|
-
|
|
31820
|
+
const disabled = this.accountReadOnly;
|
|
31821
|
+
if (disabled) {
|
|
31779
31822
|
this.form.controls.lastName.disable();
|
|
31780
31823
|
this.form.controls.firstName.disable();
|
|
31781
31824
|
}
|
|
@@ -31784,8 +31827,8 @@ class AccountPage extends AppForm {
|
|
|
31784
31827
|
const control = this.form.controls[field.key];
|
|
31785
31828
|
if (!control)
|
|
31786
31829
|
return; // Skip
|
|
31787
|
-
const
|
|
31788
|
-
if (
|
|
31830
|
+
const fieldDisabled = disabled || (field.extra?.account && field.extra.account.disabled) || false;
|
|
31831
|
+
if (fieldDisabled && control.enabled) {
|
|
31789
31832
|
control.disable();
|
|
31790
31833
|
}
|
|
31791
31834
|
const required = (field.extra?.account && field.extra.account.required) || false;
|
|
@@ -31804,15 +31847,19 @@ class AccountPage extends AppForm {
|
|
|
31804
31847
|
// Back to home
|
|
31805
31848
|
return this.navController.navigateRoot('/'); // back to home
|
|
31806
31849
|
}
|
|
31850
|
+
onConfigLoaded(config) {
|
|
31851
|
+
this.accountReadOnly = config.getPropertyAsBoolean(CORE_CONFIG_OPTIONS.ACCOUNT_READONLY);
|
|
31852
|
+
this.showApiTokens = config.getPropertyAsBoolean(CORE_CONFIG_OPTIONS.AUTH_API_TOKEN_ENABLED);
|
|
31853
|
+
}
|
|
31807
31854
|
markForCheck() {
|
|
31808
31855
|
this.cd.markForCheck();
|
|
31809
31856
|
}
|
|
31810
31857
|
}
|
|
31811
31858
|
AccountPage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AccountPage, deps: [{ token: i0.Injector }, { token: i1$2.UntypedFormBuilder }, { token: AccountService }, { token: NetworkService }, { token: i2$1.NavController }, { token: AccountValidatorService }, { token: ConfigService }, { token: i0.ChangeDetectorRef }, { token: APP_LOCALES }], target: i0.ɵɵFactoryTarget.Component });
|
|
31812
|
-
AccountPage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: AccountPage, selector: "app-account-page", viewQueries: [{ propertyName: "tabGroup", first: true, predicate: ["tabGroup"], descendants: true, static: true }, { propertyName: "propertiesTable", first: true, predicate: ["propertiesTable"], descendants: true, static: true }, { propertyName: "tokensTable", first: true, predicate: ["tokensTable"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar [title]=\"'ACCOUNT.TITLE'|translate\" color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n [canGoBack]=\"false\"\n (onClose)=\"close($event)\">\n\n <ion-buttons slot=\"end\">\n <!-- loader -->\n <ion-spinner *ngIf=\"loading || saving; else endButtons\"></ion-spinner>\n\n <ng-template #endButtons>\n <!-- refresh button (if online) -->\n <ion-button [matTooltip]=\"'COMMON.BTN_REFRESH'|translate\"\n *ngIf=\"network.online\"\n (click)=\"refresh($event)\">\n <mat-icon slot=\"icon-only\">refresh</mat-icon>\n </ion-button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n\n<ion-content>\n\n <!-- error -->\n <ion-item *ngIf=\"error && mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <form [formGroup]=\"form\" novalidate class=\"form-container\">\n\n <mat-tab-group #tabGroup [(selectedIndex)]=\"selectedTabIndex\" dynamicHeight>\n\n <!-- TAB: user details -->\n <mat-tab label=\"{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}\" class=\"ion-padding\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"person-circle\"></ion-icon>\n </mat-icon>\n <ion-label>{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}</ion-label>\n <ion-icon slot=\"end\" name=\"alert-circle\" color=\"danger\" *ngIf=\"submitted && form.invalid\"></ion-icon>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.USER_DETAILS.DESCRIPTION'|translate\"></p>\n\n <!--h1>Identit\u00E9</h1-->\n\n <!-- Email -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.EMAIL'|translate\"\n formControlName=\"email\" autocomplete=\"section-red email\">\n <mat-error *ngIf=\"form.controls.email.hasError('required') && form.controls.email.dirty\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.email.hasError('email') && form.controls.email.dirty\">\n <span>{{'ERROR.FIELD_NOT_VALID_EMAIL' | translate }}</span>\n </mat-error>\n </mat-form-field>\n\n <ion-grid *ngIf=\"email.notConfirmed\" class=\"ion-no-padding ion-padding-bottom\">\n <ion-row>\n <ion-col color=\"danger\">\n <ion-icon slot=\"start\" color=\"danger\" name=\"alert-circle\"></ion-icon>\n <ion-text [innerHTML]=\"'ACCOUNT.EMAIL_NOT_CONFIRMED_LABEL'|translate\"></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row style=\"height: 51px;\">\n <ion-col style=\"text-align: right;\">\n <ion-text>\n <small [innerHTML]=\"'ACCOUNT.EMAIL_NOT_RECEIVED_QUESTION'|translate\"></small>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"secondary\" *ngIf=\"!email.sending\" (click)=\"sendConfirmationEmail($event)\">\n {{'ACCOUNT.BTN_RESEND'|translate}}\n </ion-button>\n <ion-spinner class=\"ion-no-padding\" *ngIf=\"email.sending\"></ion-spinner>\n </ion-col>\n </ion-row>\n\n <ion-row *ngIf=\"email.error && !email.sending\">\n <ion-col>\n <span *ngIf=\"email.error && !email.sending\" [innerHTML]=\"email.error|translate\"></span>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Last name -->\n <mat-form-field>\n <input matInput [appAutofocus]=\"true\" [autofocusDelay]=\"500\" [placeholder]=\"'USER.LAST_NAME'|translate\"\n formControlName=\"lastName\"\n autocomplete=\"section-blue family-name\"\n required>\n <mat-error *ngIf=\"form.controls.lastName.hasError('required') && form.controls.lastName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.lastName.hasError('minlength') && form.controls.lastName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n <!-- First name -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.FIRST_NAME'|translate\" formControlName=\"firstName\" autocomplete=\"section-blue given-name\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('required') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('minlength') && form.controls.firstName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n\n <!-- Additional fields -->\n <ng-container *ngFor=\"let definition of additionalFields\">\n <app-form-field [definition]=\"definition\"\n [formControlName]=\"definition.key\"\n [required]=\"definition.extra && definition.extra.account && definition.extra.account.required || false\">\n </app-form-field>\n </ng-container>\n\n <h3 translate>ACCOUNT.USER_DETAILS.TECHNICAL_DIVIDER</h3>\n\n <!-- profile -->\n <mat-form-field>\n <input matInput hidden readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PROFILE'|translate\"\n formControlName=\"mainProfile\" required>\n <span>{{'USER.PROFILE_ENUM.' + form.controls.mainProfile.value | translate}}</span>\n <mat-error *ngIf=\"form.controls.firstName.hasError('mainProfile') && form.controls.mainProfile.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- pubkey -->\n <mat-form-field>\n <input matInput readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PUBKEY'|translate\" formControlName=\"pubkey\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\">\n <span translate>ERROR.FIELD_NOT_VALID_PUBKEY</span>\n </mat-error>\n </mat-form-field>\n\n </div>\n </mat-tab>\n\n <!-- TAB: settings -->\n <mat-tab label=\"{{'ACCOUNT.SETTINGS.TITLE'|translate}}\" formGroupName=\"settings\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"settings\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.SETTINGS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.SETTINGS.DESCRIPTION'|translate\"></p>\n\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LOCALE'|translate\" formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{item.value}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.locale.hasError('required') && settingsForm?.controls.locale.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- lat/long format-->\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LAT_LONG_FORMAT'|translate\" formControlName=\"latLongFormat\"\n required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{'COMMON.LAT_LONG.' + item + '_PLACEHOLDER'|translate}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.latLongFormat.hasError('required') && settingsForm?.controls.latLongFormat.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n </div>\n\n <!-- Options table -->\n <div class=\"options-table\" [class.cdk-visually-hidden]=\"optionDefinitions | isEmptyArray\">\n <app-properties-table\n #propertiesTable\n i18nColumnPrefix=\"ACCOUNT.SETTINGS.OPTIONS.\"\n [definitions]=\"optionDefinitions\"\n [debug]=\"debug\"\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-properties-table>\n </div>\n\n </mat-tab>\n\n <!-- TAB: tokens -->\n <mat-tab *ngIf=\"authTokenEnabled\" label=\"{{'ACCOUNT.TOKENS.TITLE'|translate}}\" formGroupName=\"tokens\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"ticket\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.TOKENS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n <p [innerHTML]=\"'ACCOUNT.TOKENS.DESCRIPTION'|translate\"></p>\n </div>\n\n <!-- Tokens table -->\n <div class=\"tokens-table\">\n <app-user-token-table\n #tokensTable\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-user-token-table>\n </div>\n\n </mat-tab>\n </mat-tab-group>\n\n\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar (onCancel)=\"cancel()\" (onSave)=\"save($event)\" [disabled]=\"!form.dirty || !valid || saving\">\n <!-- error -->\n <ion-item *ngIf=\"error && !mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n", styles: ["mat-tab-group .mat-tab-body-content{padding:var(--ion-grid-padding);display:grid}form{width:100%}form mat-form-field{width:100%}div.options-table{height:calc(100vh - 380px)}div.tokens-table{height:calc(100vh - 250px)}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2$1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i6$1.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i2$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i7$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple"], exportAs: ["matTabGroup"] }, { kind: "directive", type: i7$2.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i7$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "directive", type: i6$3.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "component", type: ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: AppFormField, selector: "app-form-field", inputs: ["definition", "required", "readonly", "disabled", "formControl", "formControlName", "placeholder", "compact", "floatLabel", "tabindex", "autofocus", "clearable", "chipColor", "debug", "class"], outputs: ["keyup.enter"] }, { kind: "component", type: FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave", "showSaveAndClose", "showSaveAndNext"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: AppPropertiesTable, selector: "app-properties-table", inputs: ["definitions", "showToolbar", "debug"] }, { kind: "component", type: UserTokenTable, selector: "app-user-token-table", inputs: ["useSticky"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: EmptyArrayPipe, name: "isEmptyArray" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
31859
|
+
AccountPage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: AccountPage, selector: "app-account-page", viewQueries: [{ propertyName: "tabGroup", first: true, predicate: ["tabGroup"], descendants: true, static: true }, { propertyName: "propertiesTable", first: true, predicate: ["propertiesTable"], descendants: true, static: true }, { propertyName: "tokensTable", first: true, predicate: ["tokensTable"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar [title]=\"'ACCOUNT.TITLE'|translate\" color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n [canGoBack]=\"false\"\n (onClose)=\"close($event)\">\n\n <ion-buttons slot=\"end\">\n <!-- loader -->\n <ion-spinner *ngIf=\"loading || saving; else endButtons\"></ion-spinner>\n\n <ng-template #endButtons>\n <!-- refresh button (if online) -->\n <ion-button [matTooltip]=\"'COMMON.BTN_REFRESH'|translate\"\n *ngIf=\"network.online\"\n (click)=\"refresh($event)\">\n <mat-icon slot=\"icon-only\">refresh</mat-icon>\n </ion-button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n\n<ion-content>\n\n <!-- error -->\n <ion-item *ngIf=\"error && mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <form [formGroup]=\"form\" novalidate class=\"form-container\">\n\n <mat-tab-group #tabGroup [(selectedIndex)]=\"selectedTabIndex\" dynamicHeight>\n\n <!-- TAB: user details -->\n <mat-tab label=\"{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}\" class=\"ion-padding\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"person-circle\"></ion-icon>\n </mat-icon>\n <ion-label>{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}</ion-label>\n <ion-icon slot=\"end\" name=\"alert-circle\" color=\"danger\" *ngIf=\"submitted && form.invalid\"></ion-icon>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.USER_DETAILS.DESCRIPTION'|translate\"></p>\n\n <!--h1>Identit\u00E9</h1-->\n\n <!-- Email -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.EMAIL'|translate\"\n formControlName=\"email\" autocomplete=\"section-red email\">\n <mat-error *ngIf=\"form.controls.email.hasError('required') && form.controls.email.dirty\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.email.hasError('email') && form.controls.email.dirty\">\n <span>{{'ERROR.FIELD_NOT_VALID_EMAIL' | translate }}</span>\n </mat-error>\n </mat-form-field>\n\n <ion-grid *ngIf=\"email.notConfirmed\" class=\"ion-no-padding ion-padding-bottom\">\n <ion-row>\n <ion-col color=\"danger\">\n <ion-icon slot=\"start\" color=\"danger\" name=\"alert-circle\"></ion-icon>\n <ion-text [innerHTML]=\"'ACCOUNT.EMAIL_NOT_CONFIRMED_LABEL'|translate\"></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row style=\"height: 51px;\">\n <ion-col style=\"text-align: right;\">\n <ion-text>\n <small [innerHTML]=\"'ACCOUNT.EMAIL_NOT_RECEIVED_QUESTION'|translate\"></small>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"secondary\" *ngIf=\"!email.sending\" (click)=\"sendConfirmationEmail($event)\">\n {{'ACCOUNT.BTN_RESEND'|translate}}\n </ion-button>\n <ion-spinner class=\"ion-no-padding\" *ngIf=\"email.sending\"></ion-spinner>\n </ion-col>\n </ion-row>\n\n <ion-row *ngIf=\"email.error && !email.sending\">\n <ion-col>\n <span *ngIf=\"email.error && !email.sending\" [innerHTML]=\"email.error|translate\"></span>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Last name -->\n <mat-form-field>\n <input matInput [appAutofocus]=\"true\" [autofocusDelay]=\"500\" [placeholder]=\"'USER.LAST_NAME'|translate\"\n formControlName=\"lastName\"\n autocomplete=\"section-blue family-name\"\n required>\n <mat-error *ngIf=\"form.controls.lastName.hasError('required') && form.controls.lastName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.lastName.hasError('minlength') && form.controls.lastName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n <!-- First name -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.FIRST_NAME'|translate\" formControlName=\"firstName\" autocomplete=\"section-blue given-name\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('required') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('minlength') && form.controls.firstName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n\n <!-- Additional fields -->\n <ng-container *ngFor=\"let definition of additionalFields\">\n <app-form-field [definition]=\"definition\"\n [formControlName]=\"definition.key\"\n [required]=\"definition.extra && definition.extra.account && definition.extra.account.required || false\">\n </app-form-field>\n </ng-container>\n\n <h3 translate>ACCOUNT.USER_DETAILS.TECHNICAL_DIVIDER</h3>\n\n <!-- profile -->\n <mat-form-field>\n <input matInput hidden readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PROFILE'|translate\"\n formControlName=\"mainProfile\" required>\n <span>{{'USER.PROFILE_ENUM.' + form.controls.mainProfile.value | translate}}</span>\n <mat-error *ngIf=\"form.controls.firstName.hasError('mainProfile') && form.controls.mainProfile.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- pubkey -->\n <mat-form-field>\n <input matInput readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PUBKEY'|translate\" formControlName=\"pubkey\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\">\n <span translate>ERROR.FIELD_NOT_VALID_PUBKEY</span>\n </mat-error>\n </mat-form-field>\n\n </div>\n </mat-tab>\n\n <!-- TAB: settings -->\n <mat-tab label=\"{{'ACCOUNT.SETTINGS.TITLE'|translate}}\" formGroupName=\"settings\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"settings\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.SETTINGS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.SETTINGS.DESCRIPTION'|translate\"></p>\n\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LOCALE'|translate\" formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{item.value}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.locale.hasError('required') && settingsForm?.controls.locale.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- lat/long format-->\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LAT_LONG_FORMAT'|translate\" formControlName=\"latLongFormat\"\n required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{'COMMON.LAT_LONG.' + item + '_PLACEHOLDER'|translate}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.latLongFormat.hasError('required') && settingsForm?.controls.latLongFormat.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n </div>\n\n <!-- Options table -->\n <div class=\"options-table\" [class.cdk-visually-hidden]=\"optionDefinitions | isEmptyArray\">\n <app-properties-table\n #propertiesTable\n i18nColumnPrefix=\"ACCOUNT.SETTINGS.OPTIONS.\"\n [definitions]=\"optionDefinitions\"\n [debug]=\"debug\"\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-properties-table>\n </div>\n\n </mat-tab>\n\n <!-- TAB: tokens -->\n <mat-tab *ngIf=\"showApiTokens\" label=\"{{'ACCOUNT.TOKENS.TITLE'|translate}}\" formGroupName=\"tokens\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"ticket\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.TOKENS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n <p [innerHTML]=\"'ACCOUNT.TOKENS.DESCRIPTION'|translate\"></p>\n </div>\n\n <!-- Tokens table -->\n <div class=\"tokens-table\">\n <app-user-token-table\n #tokensTable\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-user-token-table>\n </div>\n\n </mat-tab>\n </mat-tab-group>\n\n\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar (onCancel)=\"cancel()\" (onSave)=\"save($event)\" [disabled]=\"!form.dirty || !valid || saving\">\n <!-- error -->\n <ion-item *ngIf=\"error && !mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n", styles: ["mat-tab-group .mat-tab-body-content{padding:var(--ion-grid-padding);display:grid}form{width:100%}form mat-form-field{width:100%}div.options-table{height:calc(100vh - 380px)}div.tokens-table{height:calc(100vh - 250px)}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2$1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i6$1.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i2$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i7$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple"], exportAs: ["matTabGroup"] }, { kind: "directive", type: i7$2.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i7$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "directive", type: i6$3.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "component", type: ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: AppFormField, selector: "app-form-field", inputs: ["definition", "required", "readonly", "disabled", "formControl", "formControlName", "placeholder", "compact", "floatLabel", "tabindex", "autofocus", "clearable", "chipColor", "debug", "class"], outputs: ["keyup.enter"] }, { kind: "component", type: FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave", "showSaveAndClose", "showSaveAndNext"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: AppPropertiesTable, selector: "app-properties-table", inputs: ["definitions", "showToolbar", "debug"] }, { kind: "component", type: UserTokenTable, selector: "app-user-token-table", inputs: ["useSticky"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: EmptyArrayPipe, name: "isEmptyArray" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
31813
31860
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AccountPage, decorators: [{
|
|
31814
31861
|
type: Component,
|
|
31815
|
-
args: [{ selector: 'app-account-page', changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar [title]=\"'ACCOUNT.TITLE'|translate\" color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n [canGoBack]=\"false\"\n (onClose)=\"close($event)\">\n\n <ion-buttons slot=\"end\">\n <!-- loader -->\n <ion-spinner *ngIf=\"loading || saving; else endButtons\"></ion-spinner>\n\n <ng-template #endButtons>\n <!-- refresh button (if online) -->\n <ion-button [matTooltip]=\"'COMMON.BTN_REFRESH'|translate\"\n *ngIf=\"network.online\"\n (click)=\"refresh($event)\">\n <mat-icon slot=\"icon-only\">refresh</mat-icon>\n </ion-button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n\n<ion-content>\n\n <!-- error -->\n <ion-item *ngIf=\"error && mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <form [formGroup]=\"form\" novalidate class=\"form-container\">\n\n <mat-tab-group #tabGroup [(selectedIndex)]=\"selectedTabIndex\" dynamicHeight>\n\n <!-- TAB: user details -->\n <mat-tab label=\"{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}\" class=\"ion-padding\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"person-circle\"></ion-icon>\n </mat-icon>\n <ion-label>{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}</ion-label>\n <ion-icon slot=\"end\" name=\"alert-circle\" color=\"danger\" *ngIf=\"submitted && form.invalid\"></ion-icon>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.USER_DETAILS.DESCRIPTION'|translate\"></p>\n\n <!--h1>Identit\u00E9</h1-->\n\n <!-- Email -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.EMAIL'|translate\"\n formControlName=\"email\" autocomplete=\"section-red email\">\n <mat-error *ngIf=\"form.controls.email.hasError('required') && form.controls.email.dirty\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.email.hasError('email') && form.controls.email.dirty\">\n <span>{{'ERROR.FIELD_NOT_VALID_EMAIL' | translate }}</span>\n </mat-error>\n </mat-form-field>\n\n <ion-grid *ngIf=\"email.notConfirmed\" class=\"ion-no-padding ion-padding-bottom\">\n <ion-row>\n <ion-col color=\"danger\">\n <ion-icon slot=\"start\" color=\"danger\" name=\"alert-circle\"></ion-icon>\n <ion-text [innerHTML]=\"'ACCOUNT.EMAIL_NOT_CONFIRMED_LABEL'|translate\"></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row style=\"height: 51px;\">\n <ion-col style=\"text-align: right;\">\n <ion-text>\n <small [innerHTML]=\"'ACCOUNT.EMAIL_NOT_RECEIVED_QUESTION'|translate\"></small>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"secondary\" *ngIf=\"!email.sending\" (click)=\"sendConfirmationEmail($event)\">\n {{'ACCOUNT.BTN_RESEND'|translate}}\n </ion-button>\n <ion-spinner class=\"ion-no-padding\" *ngIf=\"email.sending\"></ion-spinner>\n </ion-col>\n </ion-row>\n\n <ion-row *ngIf=\"email.error && !email.sending\">\n <ion-col>\n <span *ngIf=\"email.error && !email.sending\" [innerHTML]=\"email.error|translate\"></span>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Last name -->\n <mat-form-field>\n <input matInput [appAutofocus]=\"true\" [autofocusDelay]=\"500\" [placeholder]=\"'USER.LAST_NAME'|translate\"\n formControlName=\"lastName\"\n autocomplete=\"section-blue family-name\"\n required>\n <mat-error *ngIf=\"form.controls.lastName.hasError('required') && form.controls.lastName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.lastName.hasError('minlength') && form.controls.lastName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n <!-- First name -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.FIRST_NAME'|translate\" formControlName=\"firstName\" autocomplete=\"section-blue given-name\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('required') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('minlength') && form.controls.firstName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n\n <!-- Additional fields -->\n <ng-container *ngFor=\"let definition of additionalFields\">\n <app-form-field [definition]=\"definition\"\n [formControlName]=\"definition.key\"\n [required]=\"definition.extra && definition.extra.account && definition.extra.account.required || false\">\n </app-form-field>\n </ng-container>\n\n <h3 translate>ACCOUNT.USER_DETAILS.TECHNICAL_DIVIDER</h3>\n\n <!-- profile -->\n <mat-form-field>\n <input matInput hidden readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PROFILE'|translate\"\n formControlName=\"mainProfile\" required>\n <span>{{'USER.PROFILE_ENUM.' + form.controls.mainProfile.value | translate}}</span>\n <mat-error *ngIf=\"form.controls.firstName.hasError('mainProfile') && form.controls.mainProfile.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- pubkey -->\n <mat-form-field>\n <input matInput readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PUBKEY'|translate\" formControlName=\"pubkey\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\">\n <span translate>ERROR.FIELD_NOT_VALID_PUBKEY</span>\n </mat-error>\n </mat-form-field>\n\n </div>\n </mat-tab>\n\n <!-- TAB: settings -->\n <mat-tab label=\"{{'ACCOUNT.SETTINGS.TITLE'|translate}}\" formGroupName=\"settings\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"settings\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.SETTINGS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.SETTINGS.DESCRIPTION'|translate\"></p>\n\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LOCALE'|translate\" formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{item.value}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.locale.hasError('required') && settingsForm?.controls.locale.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- lat/long format-->\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LAT_LONG_FORMAT'|translate\" formControlName=\"latLongFormat\"\n required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{'COMMON.LAT_LONG.' + item + '_PLACEHOLDER'|translate}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.latLongFormat.hasError('required') && settingsForm?.controls.latLongFormat.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n </div>\n\n <!-- Options table -->\n <div class=\"options-table\" [class.cdk-visually-hidden]=\"optionDefinitions | isEmptyArray\">\n <app-properties-table\n #propertiesTable\n i18nColumnPrefix=\"ACCOUNT.SETTINGS.OPTIONS.\"\n [definitions]=\"optionDefinitions\"\n [debug]=\"debug\"\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-properties-table>\n </div>\n\n </mat-tab>\n\n <!-- TAB: tokens -->\n <mat-tab *ngIf=\"authTokenEnabled\" label=\"{{'ACCOUNT.TOKENS.TITLE'|translate}}\" formGroupName=\"tokens\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"ticket\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.TOKENS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n <p [innerHTML]=\"'ACCOUNT.TOKENS.DESCRIPTION'|translate\"></p>\n </div>\n\n <!-- Tokens table -->\n <div class=\"tokens-table\">\n <app-user-token-table\n #tokensTable\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-user-token-table>\n </div>\n\n </mat-tab>\n </mat-tab-group>\n\n\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar (onCancel)=\"cancel()\" (onSave)=\"save($event)\" [disabled]=\"!form.dirty || !valid || saving\">\n <!-- error -->\n <ion-item *ngIf=\"error && !mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n", styles: ["mat-tab-group .mat-tab-body-content{padding:var(--ion-grid-padding);display:grid}form{width:100%}form mat-form-field{width:100%}div.options-table{height:calc(100vh - 380px)}div.tokens-table{height:calc(100vh - 250px)}\n"] }]
|
|
31862
|
+
args: [{ selector: 'app-account-page', changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar [title]=\"'ACCOUNT.TITLE'|translate\" color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n [canGoBack]=\"false\"\n (onClose)=\"close($event)\">\n\n <ion-buttons slot=\"end\">\n <!-- loader -->\n <ion-spinner *ngIf=\"loading || saving; else endButtons\"></ion-spinner>\n\n <ng-template #endButtons>\n <!-- refresh button (if online) -->\n <ion-button [matTooltip]=\"'COMMON.BTN_REFRESH'|translate\"\n *ngIf=\"network.online\"\n (click)=\"refresh($event)\">\n <mat-icon slot=\"icon-only\">refresh</mat-icon>\n </ion-button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n\n<ion-content>\n\n <!-- error -->\n <ion-item *ngIf=\"error && mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <form [formGroup]=\"form\" novalidate class=\"form-container\">\n\n <mat-tab-group #tabGroup [(selectedIndex)]=\"selectedTabIndex\" dynamicHeight>\n\n <!-- TAB: user details -->\n <mat-tab label=\"{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}\" class=\"ion-padding\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"person-circle\"></ion-icon>\n </mat-icon>\n <ion-label>{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}</ion-label>\n <ion-icon slot=\"end\" name=\"alert-circle\" color=\"danger\" *ngIf=\"submitted && form.invalid\"></ion-icon>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.USER_DETAILS.DESCRIPTION'|translate\"></p>\n\n <!--h1>Identit\u00E9</h1-->\n\n <!-- Email -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.EMAIL'|translate\"\n formControlName=\"email\" autocomplete=\"section-red email\">\n <mat-error *ngIf=\"form.controls.email.hasError('required') && form.controls.email.dirty\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.email.hasError('email') && form.controls.email.dirty\">\n <span>{{'ERROR.FIELD_NOT_VALID_EMAIL' | translate }}</span>\n </mat-error>\n </mat-form-field>\n\n <ion-grid *ngIf=\"email.notConfirmed\" class=\"ion-no-padding ion-padding-bottom\">\n <ion-row>\n <ion-col color=\"danger\">\n <ion-icon slot=\"start\" color=\"danger\" name=\"alert-circle\"></ion-icon>\n <ion-text [innerHTML]=\"'ACCOUNT.EMAIL_NOT_CONFIRMED_LABEL'|translate\"></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row style=\"height: 51px;\">\n <ion-col style=\"text-align: right;\">\n <ion-text>\n <small [innerHTML]=\"'ACCOUNT.EMAIL_NOT_RECEIVED_QUESTION'|translate\"></small>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"secondary\" *ngIf=\"!email.sending\" (click)=\"sendConfirmationEmail($event)\">\n {{'ACCOUNT.BTN_RESEND'|translate}}\n </ion-button>\n <ion-spinner class=\"ion-no-padding\" *ngIf=\"email.sending\"></ion-spinner>\n </ion-col>\n </ion-row>\n\n <ion-row *ngIf=\"email.error && !email.sending\">\n <ion-col>\n <span *ngIf=\"email.error && !email.sending\" [innerHTML]=\"email.error|translate\"></span>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Last name -->\n <mat-form-field>\n <input matInput [appAutofocus]=\"true\" [autofocusDelay]=\"500\" [placeholder]=\"'USER.LAST_NAME'|translate\"\n formControlName=\"lastName\"\n autocomplete=\"section-blue family-name\"\n required>\n <mat-error *ngIf=\"form.controls.lastName.hasError('required') && form.controls.lastName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.lastName.hasError('minlength') && form.controls.lastName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n <!-- First name -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.FIRST_NAME'|translate\" formControlName=\"firstName\" autocomplete=\"section-blue given-name\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('required') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('minlength') && form.controls.firstName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n\n <!-- Additional fields -->\n <ng-container *ngFor=\"let definition of additionalFields\">\n <app-form-field [definition]=\"definition\"\n [formControlName]=\"definition.key\"\n [required]=\"definition.extra && definition.extra.account && definition.extra.account.required || false\">\n </app-form-field>\n </ng-container>\n\n <h3 translate>ACCOUNT.USER_DETAILS.TECHNICAL_DIVIDER</h3>\n\n <!-- profile -->\n <mat-form-field>\n <input matInput hidden readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PROFILE'|translate\"\n formControlName=\"mainProfile\" required>\n <span>{{'USER.PROFILE_ENUM.' + form.controls.mainProfile.value | translate}}</span>\n <mat-error *ngIf=\"form.controls.firstName.hasError('mainProfile') && form.controls.mainProfile.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- pubkey -->\n <mat-form-field>\n <input matInput readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PUBKEY'|translate\" formControlName=\"pubkey\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\">\n <span translate>ERROR.FIELD_NOT_VALID_PUBKEY</span>\n </mat-error>\n </mat-form-field>\n\n </div>\n </mat-tab>\n\n <!-- TAB: settings -->\n <mat-tab label=\"{{'ACCOUNT.SETTINGS.TITLE'|translate}}\" formGroupName=\"settings\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"settings\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.SETTINGS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.SETTINGS.DESCRIPTION'|translate\"></p>\n\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LOCALE'|translate\" formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{item.value}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.locale.hasError('required') && settingsForm?.controls.locale.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- lat/long format-->\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LAT_LONG_FORMAT'|translate\" formControlName=\"latLongFormat\"\n required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{'COMMON.LAT_LONG.' + item + '_PLACEHOLDER'|translate}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.latLongFormat.hasError('required') && settingsForm?.controls.latLongFormat.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n </div>\n\n <!-- Options table -->\n <div class=\"options-table\" [class.cdk-visually-hidden]=\"optionDefinitions | isEmptyArray\">\n <app-properties-table\n #propertiesTable\n i18nColumnPrefix=\"ACCOUNT.SETTINGS.OPTIONS.\"\n [definitions]=\"optionDefinitions\"\n [debug]=\"debug\"\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-properties-table>\n </div>\n\n </mat-tab>\n\n <!-- TAB: tokens -->\n <mat-tab *ngIf=\"showApiTokens\" label=\"{{'ACCOUNT.TOKENS.TITLE'|translate}}\" formGroupName=\"tokens\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"ticket\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.TOKENS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n <p [innerHTML]=\"'ACCOUNT.TOKENS.DESCRIPTION'|translate\"></p>\n </div>\n\n <!-- Tokens table -->\n <div class=\"tokens-table\">\n <app-user-token-table\n #tokensTable\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-user-token-table>\n </div>\n\n </mat-tab>\n </mat-tab-group>\n\n\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar (onCancel)=\"cancel()\" (onSave)=\"save($event)\" [disabled]=\"!form.dirty || !valid || saving\">\n <!-- error -->\n <ion-item *ngIf=\"error && !mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n", styles: ["mat-tab-group .mat-tab-body-content{padding:var(--ion-grid-padding);display:grid}form{width:100%}form mat-form-field{width:100%}div.options-table{height:calc(100vh - 380px)}div.tokens-table{height:calc(100vh - 250px)}\n"] }]
|
|
31816
31863
|
}], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1$2.UntypedFormBuilder }, { type: AccountService }, { type: NetworkService }, { type: i2$1.NavController }, { type: AccountValidatorService }, { type: ConfigService }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
|
|
31817
31864
|
type: Inject,
|
|
31818
31865
|
args: [APP_LOCALES]
|