@c8y/ngx-components 1017.0.510 → 1017.0.512
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/core/bootstrap/cookie-banner/cookie-banner.service.d.ts +1 -1
- package/core/common/ApplicationOptions.d.ts +2 -0
- package/core/header/right-drawer/right-drawer.component.d.ts +22 -0
- package/core/product-experience/gainsight.service.d.ts +86 -28
- package/core/product-experience/index.d.ts +1 -0
- package/core/product-experience/product-experience.module.d.ts +18 -5
- package/core/product-experience/user-engagements.service.d.ts +109 -0
- package/core/shared/core.model.d.ts +22 -0
- package/core/user/user-edit-modal.component.d.ts +33 -6
- package/core/user/user-edit.component.d.ts +8 -13
- package/device-grid/device-grid.service.d.ts +3 -4
- package/esm2020/core/action-bar/action-bar.component.mjs +10 -7
- package/esm2020/core/bootstrap/cookie-banner/cookie-banner.service.mjs +2 -2
- package/esm2020/core/common/ApplicationOptions.mjs +1 -1
- package/esm2020/core/header/right-drawer/right-drawer.component.mjs +5 -3
- package/esm2020/core/product-experience/gainsight.service.mjs +157 -76
- package/esm2020/core/product-experience/index.mjs +2 -1
- package/esm2020/core/product-experience/product-experience.module.mjs +42 -24
- package/esm2020/core/product-experience/user-engagements.service.mjs +174 -0
- package/esm2020/core/shared/core.model.mjs +15 -0
- package/esm2020/core/user/user-edit-modal.component.mjs +68 -33
- package/esm2020/core/user/user-edit.component.mjs +36 -45
- package/esm2020/device-grid/device-grid.service.mjs +6 -15
- package/esm2020/sensor-phone/sensor-phone-modal.component.mjs +26 -15
- package/esm2020/sensor-phone/sensor-phone.model.mjs +13 -0
- package/esm2020/sensor-phone/sensor-phone.service.mjs +5 -7
- package/esm2020/sub-assets/delete-assets-modal/delete-assets-modal.component.mjs +13 -3
- package/esm2020/sub-assets/shared/sub-assets.model.mjs +11 -0
- package/fesm2015/c8y-ngx-components-device-grid.mjs +4 -15
- package/fesm2015/c8y-ngx-components-device-grid.mjs.map +1 -1
- package/fesm2015/c8y-ngx-components-sensor-phone.mjs +40 -19
- package/fesm2015/c8y-ngx-components-sensor-phone.mjs.map +1 -1
- package/fesm2015/c8y-ngx-components-sub-assets.mjs +22 -2
- package/fesm2015/c8y-ngx-components-sub-assets.mjs.map +1 -1
- package/fesm2015/c8y-ngx-components.mjs +481 -167
- package/fesm2015/c8y-ngx-components.mjs.map +1 -1
- package/fesm2020/c8y-ngx-components-device-grid.mjs +4 -13
- package/fesm2020/c8y-ngx-components-device-grid.mjs.map +1 -1
- package/fesm2020/c8y-ngx-components-sensor-phone.mjs +40 -19
- package/fesm2020/c8y-ngx-components-sensor-phone.mjs.map +1 -1
- package/fesm2020/c8y-ngx-components-sub-assets.mjs +22 -2
- package/fesm2020/c8y-ngx-components-sub-assets.mjs.map +1 -1
- package/fesm2020/c8y-ngx-components.mjs +472 -161
- package/fesm2020/c8y-ngx-components.mjs.map +1 -1
- package/locales/locales.pot +2 -2
- package/package.json +2 -2
- package/sensor-phone/sensor-phone.model.d.ts +18 -0
- package/sensor-phone/sensor-phone.service.d.ts +2 -3
- package/sub-assets/delete-assets-modal/delete-assets-modal.component.d.ts +1 -0
- package/sub-assets/shared/sub-assets.model.d.ts +15 -0
|
@@ -6910,6 +6910,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
|
|
|
6910
6910
|
}]
|
|
6911
6911
|
}], ctorParameters: function () { return []; } });
|
|
6912
6912
|
|
|
6913
|
+
const PRODUCT_EXPERIENCE = {
|
|
6914
|
+
ACTION_BAR: {
|
|
6915
|
+
EVENTS: { ACTION_BAR_ITEM: 'actionBarItem' },
|
|
6916
|
+
COMPONENTS: { ACTION_BAR_COMPONENT: 'action-bar' },
|
|
6917
|
+
ACTIONS: {},
|
|
6918
|
+
RESULTS: {}
|
|
6919
|
+
},
|
|
6920
|
+
QUICK_LINKS: {
|
|
6921
|
+
EVENTS: { QUICK_LINK_RIGHT_DRAWER: 'quickLinkRightDrawer' },
|
|
6922
|
+
COMPONENTS: { RIGHT_DRAWER_COMPONENT: 'right-drawer' },
|
|
6923
|
+
ACTIONS: {},
|
|
6924
|
+
RESULTS: {}
|
|
6925
|
+
}
|
|
6926
|
+
};
|
|
6927
|
+
|
|
6913
6928
|
/**
|
|
6914
6929
|
* This service is handling the cookie banner and cookie preferences related logic.
|
|
6915
6930
|
*/
|
|
@@ -6981,7 +6996,7 @@ class CookieBannerService {
|
|
|
6981
6996
|
return JSON.parse(localStorage.getItem(this.STORAGE_KEY));
|
|
6982
6997
|
}
|
|
6983
6998
|
/**
|
|
6984
|
-
* Verifies that cookie preferences configuration is defined.
|
|
6999
|
+
* Verifies that cookie preferences configuration is defined in the application options.
|
|
6985
7000
|
* @returns {boolean} Returns if the cookie preferences configuration is defined.
|
|
6986
7001
|
*/
|
|
6987
7002
|
isConfigCookiePreferencesDefined() {
|
|
@@ -7048,8 +7063,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
|
|
|
7048
7063
|
* tag and
|
|
7049
7064
|
*/
|
|
7050
7065
|
class GainsightService {
|
|
7051
|
-
constructor(
|
|
7052
|
-
this.document = document;
|
|
7066
|
+
constructor(appState, options, cookieBannerService, userPreferencesService, translateService) {
|
|
7053
7067
|
this.appState = appState;
|
|
7054
7068
|
this.options = options;
|
|
7055
7069
|
this.cookieBannerService = cookieBannerService;
|
|
@@ -7059,6 +7073,11 @@ class GainsightService {
|
|
|
7059
7073
|
* A subject that emits the tag function as soon as a new tag is set.
|
|
7060
7074
|
*/
|
|
7061
7075
|
this.tagFunction$ = new BehaviorSubject(null);
|
|
7076
|
+
this.trackingLoaded$ = new Subject();
|
|
7077
|
+
/**
|
|
7078
|
+
* Gainsight is activated only when the cookie banner is present. If functional cookies are enabled, both personally identifiable information (PII) and required data are sent.
|
|
7079
|
+
* Otherwise, only the required data is transmitted during the identity step execution.
|
|
7080
|
+
*/
|
|
7062
7081
|
this.USER_PREFERENCES_GAINSIGHT_KEY = 'gainsightEnabled';
|
|
7063
7082
|
/**
|
|
7064
7083
|
* The name of the key remained unchanged, but applies to all engagements.
|
|
@@ -7070,13 +7089,21 @@ class GainsightService {
|
|
|
7070
7089
|
this.SCRIPT_EXECUTION_WAIT_TIME = 500;
|
|
7071
7090
|
this.OPTIONS_KEY_CATEGORY = 'gainsight';
|
|
7072
7091
|
this.OPTIONS_KEY_NAME = 'api.key';
|
|
7073
|
-
this.ENGAGEMENTS = 'engagements';
|
|
7074
7092
|
this.isScriptLoaded = false;
|
|
7075
7093
|
}
|
|
7094
|
+
/**
|
|
7095
|
+
* Checks if the specified Gainsight preference is disabled in user preferences.
|
|
7096
|
+
* @param preferenceName - Name of the Gainsight preference.
|
|
7097
|
+
* @returns A promise that resolves to `true` if the preference is disabled, otherwise `false`.
|
|
7098
|
+
*/
|
|
7076
7099
|
async isGainsightPreferenceDisabledInUserPreferences(preferenceName) {
|
|
7077
7100
|
const userGainsightPref = await this.userPreferencesService.get(preferenceName).toPromise();
|
|
7078
7101
|
return userGainsightPref === false;
|
|
7079
7102
|
}
|
|
7103
|
+
/**
|
|
7104
|
+
* Sets the state of the functional cookie.
|
|
7105
|
+
* @param value - A boolean value to indicate whether the functional cookie should be enabled (`true`) or disabled (`false`).
|
|
7106
|
+
*/
|
|
7080
7107
|
setFunctionalCookie(value) {
|
|
7081
7108
|
const cookies = this.cookieBannerService.getUserCookiePreferences();
|
|
7082
7109
|
if (cookies) {
|
|
@@ -7105,56 +7132,111 @@ class GainsightService {
|
|
|
7105
7132
|
/**
|
|
7106
7133
|
* Load the script tag and calls the identify function to start the tracking.
|
|
7107
7134
|
* @param currentTenant The current tenant.
|
|
7108
|
-
* @param
|
|
7135
|
+
* @param sendPiiData Flag for sending personally identifiable information (PII) during identification in Gainsight.
|
|
7109
7136
|
*/
|
|
7110
|
-
async loadTag(currentTenant,
|
|
7137
|
+
async loadTag(currentTenant, sendPiiData) {
|
|
7111
7138
|
const scriptTag = document.createElement('script');
|
|
7112
7139
|
const key = await this.getGainsightKey();
|
|
7113
7140
|
if (key && !this.isScriptLoaded) {
|
|
7114
7141
|
this.loadScriptTag(scriptTag, key);
|
|
7115
|
-
|
|
7142
|
+
const currentUserStream = this.appState.currentUser;
|
|
7143
|
+
const scriptLoadStream = fromEvent(scriptTag, 'load');
|
|
7144
|
+
const versionStream = this.appState.state$.pipe(filter(({ versions }) => versions.backend), map(({ versions }) => versions), take(1));
|
|
7145
|
+
const sourceStreams = sendPiiData
|
|
7146
|
+
? [currentUserStream, scriptLoadStream, versionStream]
|
|
7147
|
+
: [currentUserStream, scriptLoadStream];
|
|
7148
|
+
combineLatest(sourceStreams)
|
|
7116
7149
|
.pipe(delay(this.SCRIPT_EXECUTION_WAIT_TIME), filter(([user, scriptEvent]) => !!(scriptEvent && user)))
|
|
7117
|
-
.subscribe(
|
|
7150
|
+
.subscribe(args => {
|
|
7151
|
+
const [user, , versions] = args;
|
|
7152
|
+
this.setGlobalContext();
|
|
7118
7153
|
const instanceId = this.getInstanceIdFromUrl();
|
|
7119
|
-
if (
|
|
7120
|
-
|
|
7121
|
-
|
|
7154
|
+
if (sendPiiData) {
|
|
7155
|
+
const versionUI = versions.ui.ngx;
|
|
7156
|
+
const versionBE = versions.backend;
|
|
7157
|
+
const extendedIdentifyData = {
|
|
7158
|
+
user,
|
|
7159
|
+
currentTenant,
|
|
7160
|
+
instanceId,
|
|
7161
|
+
versionUI,
|
|
7162
|
+
versionBE
|
|
7163
|
+
};
|
|
7164
|
+
this.identify(sendPiiData, extendedIdentifyData);
|
|
7165
|
+
}
|
|
7166
|
+
else {
|
|
7167
|
+
const requiredIdentifyData = { user, currentTenant, instanceId };
|
|
7168
|
+
this.identify(sendPiiData, requiredIdentifyData);
|
|
7122
7169
|
}
|
|
7123
7170
|
this.isScriptLoaded = true;
|
|
7124
7171
|
this.tagFunction$.next(this.tagFunction);
|
|
7172
|
+
this.trackingLoaded$.next(true);
|
|
7125
7173
|
});
|
|
7126
7174
|
}
|
|
7127
7175
|
}
|
|
7128
7176
|
/**
|
|
7129
7177
|
* Identifies the user/account at Gainsight.
|
|
7130
|
-
* @param
|
|
7131
|
-
* @param
|
|
7132
|
-
* @param versionUI The UI version used.
|
|
7133
|
-
* @param versionBE The BE version used.
|
|
7178
|
+
* @param sendPiiData Flag for sending personally identifiable information.
|
|
7179
|
+
* @param identifyData Object containing identification data.
|
|
7134
7180
|
*/
|
|
7135
|
-
identify(
|
|
7181
|
+
identify(sendPiiData, identifyData) {
|
|
7136
7182
|
const windowRef = window;
|
|
7137
|
-
const { id: userId, email,
|
|
7138
|
-
const { name, customProperties, domainName } =
|
|
7139
|
-
const {
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7183
|
+
const { id: userId, email, roles } = identifyData.user;
|
|
7184
|
+
const { name: tenantID, customProperties, domainName } = identifyData.currentTenant;
|
|
7185
|
+
const { instanceId, versionUI, versionBE } = identifyData;
|
|
7186
|
+
/**
|
|
7187
|
+
* Passing ID is a minimum required data to make an identify call to Gainsight.
|
|
7188
|
+
* isUserCreatedAfterAnonymizationWasActivated parameter is passed to later distinguish between users created before and after data anonymization done by Gainsight.
|
|
7189
|
+
* tenantID Used to distinguish between tenants when same email is used for different tenants.
|
|
7190
|
+
*
|
|
7191
|
+
* Due to GS limitations (GS does not allow clearing user attr/preferences via the GS tag!),
|
|
7192
|
+
* we always need to initialize fields related to PII to prevent leaking this data to GS when the user has disabled functional cookies.
|
|
7193
|
+
*/
|
|
7194
|
+
const requiredIdentify = {
|
|
7195
|
+
/**
|
|
7196
|
+
* Email was not mandatory form field until 10.14
|
|
7197
|
+
*/
|
|
7198
|
+
id: email ? email : `${userId}_${tenantID}_${instanceId}`,
|
|
7199
|
+
isUserCreatedAfterAnonymizationWasActivated: true,
|
|
7200
|
+
tenantID: tenantID,
|
|
7201
|
+
email: '--',
|
|
7202
|
+
userName: '--',
|
|
7203
|
+
firstName: '--',
|
|
7204
|
+
lastName: '--',
|
|
7146
7205
|
domainName,
|
|
7147
7206
|
versionUI,
|
|
7148
7207
|
versionBE,
|
|
7149
7208
|
userLanguage: this.translateService.currentLang,
|
|
7209
|
+
browserLanguage: this.translateService.getBrowserLang(),
|
|
7150
7210
|
instanceId,
|
|
7151
|
-
externalReference,
|
|
7152
|
-
userRoles: this.transformUserRolesToStr(roles?.references)
|
|
7153
|
-
|
|
7154
|
-
|
|
7155
|
-
|
|
7156
|
-
|
|
7211
|
+
externalReference: customProperties?.externalReference,
|
|
7212
|
+
userRoles: this.transformUserRolesToStr(roles?.references),
|
|
7213
|
+
customBranding: this.isCustomBranding(),
|
|
7214
|
+
fullTracking: sendPiiData
|
|
7215
|
+
};
|
|
7216
|
+
if (sendPiiData) {
|
|
7217
|
+
const { userName, firstName, lastName } = identifyData.user;
|
|
7218
|
+
const extendedIdentify = {
|
|
7219
|
+
...requiredIdentify,
|
|
7220
|
+
email,
|
|
7221
|
+
userName,
|
|
7222
|
+
firstName,
|
|
7223
|
+
lastName
|
|
7224
|
+
};
|
|
7225
|
+
windowRef[this.GAINSIGHT_GLOBAL_SCOPE]('identify', extendedIdentify, {
|
|
7226
|
+
id: `${tenantID}_${instanceId}`,
|
|
7227
|
+
instanceId
|
|
7228
|
+
});
|
|
7229
|
+
return;
|
|
7230
|
+
}
|
|
7231
|
+
windowRef[this.GAINSIGHT_GLOBAL_SCOPE]('identify', requiredIdentify);
|
|
7157
7232
|
}
|
|
7233
|
+
/**
|
|
7234
|
+
* Triggers an event to be recorded by Gainsight PX.
|
|
7235
|
+
* This method calls the Gainsight PX's tracking mechanism to log a specific event
|
|
7236
|
+
* along with its associated properties.
|
|
7237
|
+
* @param eventName - Name of the event to be triggered.
|
|
7238
|
+
* @param props - Optional properties associated with the event.
|
|
7239
|
+
*/
|
|
7158
7240
|
triggerEvent(eventName, props) {
|
|
7159
7241
|
if (this.tagFunction && eventName) {
|
|
7160
7242
|
eventName = this.prepareEventName(eventName);
|
|
@@ -7176,38 +7258,51 @@ class GainsightService {
|
|
|
7176
7258
|
return this.getEnTranslation(textToTranslate, this.cachedRevertedTranslations);
|
|
7177
7259
|
}
|
|
7178
7260
|
/**
|
|
7179
|
-
*
|
|
7180
|
-
* The decision to
|
|
7181
|
-
*
|
|
7261
|
+
* Determines whether personally identifiable information (PII) should be sent while loading a tag.
|
|
7262
|
+
* The decision to activate Gainsight and send PII relies on whether the cookiePreferences option is defined in the application settings,
|
|
7263
|
+
* if the functional cookie is enabled, and if the user grants permission.
|
|
7182
7264
|
*/
|
|
7183
|
-
|
|
7265
|
+
async shouldSendPiiData() {
|
|
7184
7266
|
return (this.cookieBannerService.isConfigCookiePreferencesDefined() &&
|
|
7185
7267
|
this.cookieBannerService.isFunctionalCookieEnabled() &&
|
|
7186
|
-
!this.
|
|
7187
|
-
!this.isCustomBranding());
|
|
7268
|
+
!(await this.isGainsightPreferenceDisabledInUserPreferences(this.USER_PREFERENCES_GAINSIGHT_KEY)));
|
|
7188
7269
|
}
|
|
7270
|
+
/**
|
|
7271
|
+
* Updates a specific user attribute in the Gainsight global scope.
|
|
7272
|
+
* This method interfaces with the Gainsight global object to set a user's specific attribute with a provided value.
|
|
7273
|
+
* @param name - Name of the user attribute to be updated.
|
|
7274
|
+
* @param value - Value to set for the specified user attribute.
|
|
7275
|
+
*/
|
|
7189
7276
|
updateUserAttribute(name, value) {
|
|
7190
7277
|
window[this.GAINSIGHT_GLOBAL_SCOPE]?.('set', 'user', { [name]: value });
|
|
7191
7278
|
}
|
|
7279
|
+
/**
|
|
7280
|
+
* Determines if the current user has the capability to modify Gainsight PX settings.
|
|
7281
|
+
*
|
|
7282
|
+
* This method checks multiple conditions:
|
|
7283
|
+
* 1. Whether tracking has been disabled globally via application options.
|
|
7284
|
+
* 2. Whether Gainsight is disabled at the tenant level through custom properties.
|
|
7285
|
+
* 3. Whether a Gainsight key is available, either currently loaded or fetched asynchronously.
|
|
7286
|
+
* 4. Whether cookie preferences are defined and available for the user.
|
|
7287
|
+
*
|
|
7288
|
+
* @returns Promise that resolves to a boolean. True indicates the user can edit product experience settings, and false otherwise.
|
|
7289
|
+
*/
|
|
7192
7290
|
async canEditProductExperienceSettings() {
|
|
7193
7291
|
const currentTenant = this.appState.currentTenant.value;
|
|
7194
7292
|
const { customProperties } = currentTenant;
|
|
7293
|
+
if (this.isTrackingDisabled() ||
|
|
7294
|
+
this.isGainsightDisabledAtTenantCustomProperties(customProperties)) {
|
|
7295
|
+
return false;
|
|
7296
|
+
}
|
|
7195
7297
|
const gainsightKey = !!this.gainsightKey || !!(await this.getGainsightKey());
|
|
7196
7298
|
return (gainsightKey &&
|
|
7197
7299
|
this.cookieBannerService.isConfigCookiePreferencesDefined() &&
|
|
7198
|
-
|
|
7199
|
-
!!this.cookieBannerService.getUserCookiePreferences() &&
|
|
7200
|
-
!this.isCustomBranding());
|
|
7201
|
-
}
|
|
7202
|
-
switchGainsightEngagementsVisibility(showGainsightEngagements) {
|
|
7203
|
-
if (showGainsightEngagements) {
|
|
7204
|
-
this.removeHidingStyle(this.HIDE_GAINSIGHT_BOT_STYLE_ID);
|
|
7205
|
-
this.updateUserAttribute(this.ENGAGEMENTS, true);
|
|
7206
|
-
return;
|
|
7207
|
-
}
|
|
7208
|
-
this.addHidingStyle(this.HIDE_GAINSIGHT_BOT_STYLE_ID, '#apt-widget { display:none }');
|
|
7209
|
-
this.updateUserAttribute(this.ENGAGEMENTS, false);
|
|
7300
|
+
!!this.cookieBannerService.getUserCookiePreferences());
|
|
7210
7301
|
}
|
|
7302
|
+
/**
|
|
7303
|
+
* Sets the global context for Gainsight with the current application name.
|
|
7304
|
+
* The global context can be utilized by Gainsight for various purposes, such as segmenting users.
|
|
7305
|
+
*/
|
|
7211
7306
|
setGlobalContext() {
|
|
7212
7307
|
const currentAppState = this.appState.state$.value;
|
|
7213
7308
|
const currentAppName = currentAppState.app.name;
|
|
@@ -7219,18 +7314,31 @@ class GainsightService {
|
|
|
7219
7314
|
}
|
|
7220
7315
|
return flatMap(userRoles, (userRole) => userRole.role.name).join();
|
|
7221
7316
|
}
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
|
|
7317
|
+
/**
|
|
7318
|
+
* Checks if Gainsight is disabled based on tenant custom properties.
|
|
7319
|
+
*
|
|
7320
|
+
* @param customProperties - The custom properties of the tenant.
|
|
7321
|
+
* @returns {boolean} - True if Gainsight is disabled, false otherwise.
|
|
7322
|
+
*/
|
|
7323
|
+
isGainsightDisabledAtTenantCustomProperties(customProperties) {
|
|
7324
|
+
const gainsightEnabled = customProperties && customProperties.gainsightEnabled;
|
|
7325
|
+
return gainsightEnabled === false;
|
|
7230
7326
|
}
|
|
7231
|
-
|
|
7232
|
-
|
|
7233
|
-
|
|
7327
|
+
/**
|
|
7328
|
+
* Determines if custom branding is enabled based on the presence of a brand logo.
|
|
7329
|
+
*
|
|
7330
|
+
* @returns {boolean} - True if custom branding is applied, false otherwise.
|
|
7331
|
+
*/
|
|
7332
|
+
isCustomBranding() {
|
|
7333
|
+
const brandingCssVars = this.options.get('brandingCssVars') || {};
|
|
7334
|
+
return !!brandingCssVars['brand-logo-img'];
|
|
7335
|
+
}
|
|
7336
|
+
/**
|
|
7337
|
+
* Determines if tracking is disabled based on the application options.
|
|
7338
|
+
* @returns `true` if tracking is disabled, otherwise `false`.
|
|
7339
|
+
*/
|
|
7340
|
+
isTrackingDisabled() {
|
|
7341
|
+
return this.options.disableTracking === true;
|
|
7234
7342
|
}
|
|
7235
7343
|
prepareEventName(baseEventName) {
|
|
7236
7344
|
return baseEventName
|
|
@@ -7241,14 +7349,6 @@ class GainsightService {
|
|
|
7241
7349
|
return eventNamePart.replace(/`[\w\W]*`/g, '');
|
|
7242
7350
|
}
|
|
7243
7351
|
}
|
|
7244
|
-
isGainsightDisabled(customProperties) {
|
|
7245
|
-
const gainsightEnabled = customProperties && customProperties.gainsightEnabled;
|
|
7246
|
-
return gainsightEnabled === false;
|
|
7247
|
-
}
|
|
7248
|
-
isCustomBranding() {
|
|
7249
|
-
const brandingCssVars = this.options.get('brandingCssVars') || {};
|
|
7250
|
-
return !!brandingCssVars['brand-logo-img'];
|
|
7251
|
-
}
|
|
7252
7352
|
loadScriptTag(scriptTag, key) {
|
|
7253
7353
|
try {
|
|
7254
7354
|
const windowRef = window;
|
|
@@ -7311,17 +7411,14 @@ class GainsightService {
|
|
|
7311
7411
|
return enTranslation;
|
|
7312
7412
|
}
|
|
7313
7413
|
}
|
|
7314
|
-
GainsightService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: GainsightService, deps: [{ token:
|
|
7414
|
+
GainsightService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: GainsightService, deps: [{ token: AppStateService }, { token: OptionsService }, { token: CookieBannerService }, { token: UserPreferencesService }, { token: i1$3.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
7315
7415
|
GainsightService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: GainsightService, providedIn: 'root' });
|
|
7316
7416
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: GainsightService, decorators: [{
|
|
7317
7417
|
type: Injectable,
|
|
7318
7418
|
args: [{
|
|
7319
7419
|
providedIn: 'root'
|
|
7320
7420
|
}]
|
|
7321
|
-
}], ctorParameters: function () { return [{ type:
|
|
7322
|
-
type: Inject,
|
|
7323
|
-
args: [DOCUMENT]
|
|
7324
|
-
}] }, { type: AppStateService }, { type: OptionsService }, { type: CookieBannerService }, { type: UserPreferencesService }, { type: i1$3.TranslateService }]; } });
|
|
7421
|
+
}], ctorParameters: function () { return [{ type: AppStateService }, { type: OptionsService }, { type: CookieBannerService }, { type: UserPreferencesService }, { type: i1$3.TranslateService }]; } });
|
|
7325
7422
|
|
|
7326
7423
|
/**
|
|
7327
7424
|
* This component is used as the outlet to show the action bars.
|
|
@@ -7384,15 +7481,17 @@ class ActionBarComponent {
|
|
|
7384
7481
|
return;
|
|
7385
7482
|
}
|
|
7386
7483
|
const element = event.closest('[px-event]') || event.closest('[title]') || event.closest('[uib-tooltip]');
|
|
7387
|
-
if (!element) {
|
|
7484
|
+
if (!element || element.getAttribute('disabled')) {
|
|
7388
7485
|
return;
|
|
7389
7486
|
}
|
|
7390
|
-
const
|
|
7487
|
+
const itemName = element.getAttribute('px-event') ||
|
|
7391
7488
|
element.getAttribute('title') ||
|
|
7392
7489
|
element.getAttribute('uib-tooltip');
|
|
7393
|
-
const
|
|
7394
|
-
this.gainsightService.triggerEvent(
|
|
7395
|
-
|
|
7490
|
+
const translatedItemName = this.gainsightService.translateToEnglish(itemName);
|
|
7491
|
+
this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.ACTION_BAR.EVENTS.ACTION_BAR_ITEM, {
|
|
7492
|
+
component: PRODUCT_EXPERIENCE.ACTION_BAR.COMPONENTS.ACTION_BAR_COMPONENT,
|
|
7493
|
+
action: `${translatedItemName}`,
|
|
7494
|
+
url: location.href
|
|
7396
7495
|
});
|
|
7397
7496
|
}
|
|
7398
7497
|
ngOnInit() {
|
|
@@ -12282,6 +12381,171 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
|
|
|
12282
12381
|
type: Injectable
|
|
12283
12382
|
}], ctorParameters: function () { return [{ type: i1$8.BsModalService }]; } });
|
|
12284
12383
|
|
|
12384
|
+
class UserEngagementsService {
|
|
12385
|
+
constructor(document, userPreferencesService, gainsightService) {
|
|
12386
|
+
this.document = document;
|
|
12387
|
+
this.userPreferencesService = userPreferencesService;
|
|
12388
|
+
this.gainsightService = gainsightService;
|
|
12389
|
+
this.USER_PREFERENCES_GAINSIGHT_ENGAGEMENTS_KEY = 'gainsightBotEnabled';
|
|
12390
|
+
this.userEngagementsEnabled$ = new BehaviorSubject(false);
|
|
12391
|
+
this.HIDE_GAINSIGHT_BOT_STYLE_ID = 'hide-gs-bot';
|
|
12392
|
+
this.ENGAGEMENTS = 'engagements';
|
|
12393
|
+
this.handleUserEngagements();
|
|
12394
|
+
}
|
|
12395
|
+
/**
|
|
12396
|
+
* Handles user engagement settings based on various conditions.
|
|
12397
|
+
*
|
|
12398
|
+
* - Waits for the Gainsight tracking to be loaded.
|
|
12399
|
+
* - Retrieves the engagement settings.
|
|
12400
|
+
* - Updates the engagement settings based on the combined observations.
|
|
12401
|
+
* - Finally, toggles the Gainsight engagements based on the latest `userEngagementsEnabled$` value.
|
|
12402
|
+
*/
|
|
12403
|
+
handleUserEngagements() {
|
|
12404
|
+
this.gainsightService.trackingLoaded$
|
|
12405
|
+
.pipe(take(1), switchMap(() => this.getEngagementSettingsObservable()), tap((settings) => this.updateUserEngagementSettings(...settings)), switchMap(() => this.userEngagementsEnabled$.pipe(take(1))))
|
|
12406
|
+
.subscribe(isEnabled => this.toggleGainsightEngagements(isEnabled));
|
|
12407
|
+
}
|
|
12408
|
+
/**
|
|
12409
|
+
* Updates the user's preference for Gainsight Engagements.
|
|
12410
|
+
* @param {boolean} isEnabled - The new value for the user's engagement preference.
|
|
12411
|
+
*/
|
|
12412
|
+
updateUserEngagementPreference(isEnabled) {
|
|
12413
|
+
this.userEngagementsEnabled$.next(isEnabled);
|
|
12414
|
+
this.userPreferencesService.set(this.gainsightService.USER_PREFERENCES_GAINSIGHT_ENGAGEMENTS_KEY, this.userEngagementsEnabled$.value);
|
|
12415
|
+
}
|
|
12416
|
+
/**
|
|
12417
|
+
* Toggles the visibility of Gainsight Engagements based on the provided flag.
|
|
12418
|
+
*
|
|
12419
|
+
* @param isEnabled - A flag indicating whether Gainsight Engagements should be visible.
|
|
12420
|
+
*/
|
|
12421
|
+
toggleGainsightEngagements(isEnabled) {
|
|
12422
|
+
isEnabled ? this.showGainsightEngagements() : this.hideGainsightEngagements();
|
|
12423
|
+
}
|
|
12424
|
+
/**
|
|
12425
|
+
* Constructs an observable that emits an array of boolean values representing
|
|
12426
|
+
* the current engagement settings. The observable combines the latest values from:
|
|
12427
|
+
*
|
|
12428
|
+
* 1. User's preferences for Gainsight engagements.
|
|
12429
|
+
* 2. A flag indicating if PII data should be sent.
|
|
12430
|
+
* 3. A flag indicating if the platform uses custom branding.
|
|
12431
|
+
*
|
|
12432
|
+
* @returns An observable emitting an array of boolean values.
|
|
12433
|
+
*/
|
|
12434
|
+
getEngagementSettingsObservable() {
|
|
12435
|
+
return combineLatest([
|
|
12436
|
+
this.userPreferencesService.observe(this.USER_PREFERENCES_GAINSIGHT_ENGAGEMENTS_KEY),
|
|
12437
|
+
from(this.gainsightService.shouldSendPiiData()),
|
|
12438
|
+
of(this.gainsightService.isCustomBranding())
|
|
12439
|
+
]);
|
|
12440
|
+
}
|
|
12441
|
+
/**
|
|
12442
|
+
* Updates user engagement settings based on provided preferences and settings.
|
|
12443
|
+
*
|
|
12444
|
+
* Based on the received values, the method decides to:
|
|
12445
|
+
* 1. Disable user engagements if PII data should not be shared or certain branding/settings conditions are met.
|
|
12446
|
+
* 2. Update the user engagement preference if the user engagement bot setting is undefined.
|
|
12447
|
+
*
|
|
12448
|
+
* @param userEngagementBotSetting - The user's setting for the engagement bot.
|
|
12449
|
+
* @param shouldSendPiiData - Indicates whether PII data should be shared.
|
|
12450
|
+
* @param hasCustomBranding - Indicates if custom branding is applied.
|
|
12451
|
+
*/
|
|
12452
|
+
updateUserEngagementSettings(userEngagementBotSetting, shouldSendPiiData, hasCustomBranding) {
|
|
12453
|
+
if (this.shouldDisableUserEngagementsDueToPIIData(shouldSendPiiData)) {
|
|
12454
|
+
this.userEngagementsEnabled$.next(false);
|
|
12455
|
+
}
|
|
12456
|
+
else if (this.isUserEngagementBotSettingUndefined(userEngagementBotSetting)) {
|
|
12457
|
+
/**
|
|
12458
|
+
* Case where the user is new (freshly created) and has not changed the user engagement settings in the user edit modal (untouched state).
|
|
12459
|
+
* When custom branding is not set, we will set the user engagements in the user preferences to true by default.
|
|
12460
|
+
*/
|
|
12461
|
+
this.updateUserEngagementPreference(!hasCustomBranding);
|
|
12462
|
+
}
|
|
12463
|
+
else {
|
|
12464
|
+
this.userEngagementsEnabled$.next(userEngagementBotSetting);
|
|
12465
|
+
}
|
|
12466
|
+
}
|
|
12467
|
+
/**
|
|
12468
|
+
* Determines whether user engagements should be disabled due to PII data settings.
|
|
12469
|
+
*
|
|
12470
|
+
* If the `shouldSendPiiData` parameter is false, this indicates that the user engagements
|
|
12471
|
+
* should be disabled to prevent sharing personally identifiable information.
|
|
12472
|
+
*
|
|
12473
|
+
* @param {boolean} shouldSendPiiData - Indicates whether PII data is allowed to be sent.
|
|
12474
|
+
* @returns {boolean} Returns true if user engagements should be disabled, otherwise false.
|
|
12475
|
+
*/
|
|
12476
|
+
shouldDisableUserEngagementsDueToPIIData(shouldSendPiiData) {
|
|
12477
|
+
return !shouldSendPiiData;
|
|
12478
|
+
}
|
|
12479
|
+
/**
|
|
12480
|
+
* Determines if the user engagement bot setting is undefined.
|
|
12481
|
+
*
|
|
12482
|
+
* @param {boolean | undefined} userEngagementBotSetting - The setting value to check.
|
|
12483
|
+
* @returns {boolean} Returns `true` if the setting is undefined; otherwise, `false`.
|
|
12484
|
+
*
|
|
12485
|
+
* This scenario occurs when a user is new and hasn't modified the bot settings in the user details UI yet.
|
|
12486
|
+
*/
|
|
12487
|
+
isUserEngagementBotSettingUndefined(userEngagementBotSetting) {
|
|
12488
|
+
return userEngagementBotSetting === undefined;
|
|
12489
|
+
}
|
|
12490
|
+
/**
|
|
12491
|
+
* Enables the visibility of Gainsight engagements.
|
|
12492
|
+
*
|
|
12493
|
+
* This method removes the CSS styles that hide the Gainsight engagements
|
|
12494
|
+
* and updates the relevant user attribute to mark the engagements as visible.
|
|
12495
|
+
*/
|
|
12496
|
+
showGainsightEngagements() {
|
|
12497
|
+
this.removeHidingStyle(this.HIDE_GAINSIGHT_BOT_STYLE_ID);
|
|
12498
|
+
this.gainsightService.updateUserAttribute(this.ENGAGEMENTS, true);
|
|
12499
|
+
}
|
|
12500
|
+
/**
|
|
12501
|
+
* Hides the Gainsight engagements.
|
|
12502
|
+
*
|
|
12503
|
+
* This method applies CSS styles to hide the Gainsight engagements
|
|
12504
|
+
* and updates the relevant user attribute to mark the engagements as hidden.
|
|
12505
|
+
*/
|
|
12506
|
+
hideGainsightEngagements() {
|
|
12507
|
+
this.addHidingStyle(this.HIDE_GAINSIGHT_BOT_STYLE_ID, '#apt-widget { display:none }');
|
|
12508
|
+
this.gainsightService.updateUserAttribute(this.ENGAGEMENTS, false);
|
|
12509
|
+
}
|
|
12510
|
+
/**
|
|
12511
|
+
* Removes the specified CSS style from the document.
|
|
12512
|
+
*
|
|
12513
|
+
* @param {string} styleId - The ID of the CSS style element to remove.
|
|
12514
|
+
*/
|
|
12515
|
+
removeHidingStyle(styleId) {
|
|
12516
|
+
const style = this.document.getElementById(styleId);
|
|
12517
|
+
style?.remove();
|
|
12518
|
+
}
|
|
12519
|
+
/**
|
|
12520
|
+
* Adds a new CSS style to the document.
|
|
12521
|
+
*
|
|
12522
|
+
* If the style with the specified ID already exists, the method will do nothing.
|
|
12523
|
+
* Otherwise, it creates a new `<style>` element with the given ID and content,
|
|
12524
|
+
* then appends it to the document head.
|
|
12525
|
+
*
|
|
12526
|
+
* @param {string} styleId - The ID to assign to the new style element.
|
|
12527
|
+
* @param {string} textContent - The CSS rules to be included in the style.
|
|
12528
|
+
*/
|
|
12529
|
+
addHidingStyle(styleId, textContent) {
|
|
12530
|
+
if (this.document.getElementById(styleId)) {
|
|
12531
|
+
return;
|
|
12532
|
+
}
|
|
12533
|
+
const style = this.document.createElement('style');
|
|
12534
|
+
style.id = styleId;
|
|
12535
|
+
style.textContent = textContent;
|
|
12536
|
+
this.document.head.appendChild(style);
|
|
12537
|
+
}
|
|
12538
|
+
}
|
|
12539
|
+
UserEngagementsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UserEngagementsService, deps: [{ token: DOCUMENT }, { token: UserPreferencesService }, { token: GainsightService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
12540
|
+
UserEngagementsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UserEngagementsService, providedIn: 'root' });
|
|
12541
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UserEngagementsService, decorators: [{
|
|
12542
|
+
type: Injectable,
|
|
12543
|
+
args: [{ providedIn: 'root' }]
|
|
12544
|
+
}], ctorParameters: function () { return [{ type: DOCUMENT, decorators: [{
|
|
12545
|
+
type: Inject,
|
|
12546
|
+
args: [DOCUMENT]
|
|
12547
|
+
}] }, { type: UserPreferencesService }, { type: GainsightService }]; } });
|
|
12548
|
+
|
|
12285
12549
|
class TotpChallengeComponent {
|
|
12286
12550
|
constructor(loginService, users, alert) {
|
|
12287
12551
|
this.loginService = loginService;
|
|
@@ -12668,7 +12932,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
|
|
|
12668
12932
|
}] } });
|
|
12669
12933
|
|
|
12670
12934
|
class UserEditComponent {
|
|
12671
|
-
constructor(state, translate, bsModalService, alert, userService, tenantLoginOptionsService, tenantService
|
|
12935
|
+
constructor(state, translate, bsModalService, alert, userService, tenantLoginOptionsService, tenantService) {
|
|
12672
12936
|
this.state = state;
|
|
12673
12937
|
this.translate = translate;
|
|
12674
12938
|
this.bsModalService = bsModalService;
|
|
@@ -12676,17 +12940,15 @@ class UserEditComponent {
|
|
|
12676
12940
|
this.userService = userService;
|
|
12677
12941
|
this.tenantLoginOptionsService = tenantLoginOptionsService;
|
|
12678
12942
|
this.tenantService = tenantService;
|
|
12679
|
-
this.userPreferencesService = userPreferencesService;
|
|
12680
|
-
this.gainsightService = gainsightService;
|
|
12681
12943
|
this.loading = false;
|
|
12682
|
-
this.
|
|
12944
|
+
this.showProductExperienceOptions = false;
|
|
12683
12945
|
this.isUsageTrackingEnabled = true;
|
|
12684
|
-
this.
|
|
12946
|
+
this.isUserEngagementPreferenceEnabled = true;
|
|
12685
12947
|
this.onUser = new EventEmitter();
|
|
12686
|
-
this.
|
|
12687
|
-
this.
|
|
12688
|
-
this.onGainsightEngagements = new EventEmitter();
|
|
12948
|
+
this.onUsageTrackingChange = new EventEmitter();
|
|
12949
|
+
this.onUserEngagementPreferenceChange = new EventEmitter();
|
|
12689
12950
|
this.onCancel = new EventEmitter();
|
|
12951
|
+
this.onLanguage = new EventEmitter();
|
|
12690
12952
|
this.userHasActiveTotp = false;
|
|
12691
12953
|
this.userCanSetupTotp = false;
|
|
12692
12954
|
this.isPhoneRequired = false;
|
|
@@ -12710,16 +12972,6 @@ class UserEditComponent {
|
|
|
12710
12972
|
this.isPhoneRequired = true;
|
|
12711
12973
|
}
|
|
12712
12974
|
}
|
|
12713
|
-
async onEnablingProductUsageTracking(isUsageTrackingEnabled) {
|
|
12714
|
-
if (isUsageTrackingEnabled && this.isGainsightEngagementsEnabled === undefined) {
|
|
12715
|
-
this.isGainsightEngagementsEnabled = await this.userPreferencesService
|
|
12716
|
-
.get(this.gainsightService.USER_PREFERENCES_GAINSIGHT_ENGAGEMENTS_KEY)
|
|
12717
|
-
.toPromise();
|
|
12718
|
-
}
|
|
12719
|
-
}
|
|
12720
|
-
get langs() {
|
|
12721
|
-
return this.state.state.langs;
|
|
12722
|
-
}
|
|
12723
12975
|
setupTotp() {
|
|
12724
12976
|
this.bsModalService.show(UserTotpSetupComponent, {
|
|
12725
12977
|
class: 'modal-sm',
|
|
@@ -12735,15 +12987,22 @@ class UserEditComponent {
|
|
|
12735
12987
|
if (this.loading) {
|
|
12736
12988
|
return;
|
|
12737
12989
|
}
|
|
12738
|
-
if (this.
|
|
12739
|
-
this.
|
|
12740
|
-
|
|
12990
|
+
if (this.showProductExperienceOptions) {
|
|
12991
|
+
this.onUsageTrackingChange.emit(this.isUsageTrackingEnabled);
|
|
12992
|
+
/**
|
|
12993
|
+
* Emits a user engagement preference change event.
|
|
12994
|
+
* If usage tracking is disabled, it emits `false`. Otherwise, it emits the current state of the user engagement preference.
|
|
12995
|
+
*/
|
|
12996
|
+
this.onUserEngagementPreferenceChange.emit(this.isUsageTrackingEnabled === false ? false : this.isUserEngagementPreferenceEnabled);
|
|
12741
12997
|
}
|
|
12742
12998
|
this.onUser.emit(this._user);
|
|
12743
12999
|
}
|
|
12744
13000
|
onNewPasswordChanged(newPassword) {
|
|
12745
13001
|
this._user.password = newPassword.password;
|
|
12746
13002
|
}
|
|
13003
|
+
get langs() {
|
|
13004
|
+
return this.state.state.langs;
|
|
13005
|
+
}
|
|
12747
13006
|
async initializeTotpSettings() {
|
|
12748
13007
|
try {
|
|
12749
13008
|
this.userCanSetupTotp = await this.canUserSetupTotp();
|
|
@@ -12762,37 +13021,37 @@ class UserEditComponent {
|
|
|
12762
13021
|
return loginOptions.some(({ tfaStrategy = '' }) => tfaStrategy.toLowerCase() === 'totp');
|
|
12763
13022
|
}
|
|
12764
13023
|
}
|
|
12765
|
-
UserEditComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UserEditComponent, deps: [{ token: AppStateService }, { token: TranslateService }, { token: i1$8.BsModalService }, { token: AlertService }, { token: i1$2.UserService }, { token: i1$2.TenantLoginOptionsService }, { token: i1$2.TenantService }
|
|
12766
|
-
UserEditComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: UserEditComponent, selector: "c8y-user-edit", inputs: { lang: "lang", loading: "loading", user: "user", showProductUsageSetting: "showProductUsageSetting", isUsageTrackingEnabled: "isUsageTrackingEnabled", isGainsightEngagementsEnabled: "isGainsightEngagementsEnabled" }, outputs: { onUser: "onUser", onLanguage: "onLanguage", onProductExperience: "onProductExperience", onGainsightEngagements: "onGainsightEngagements", onCancel: "onCancel" }, ngImport: i0, template: "<form #userForm=\"ngForm\" (ngSubmit)=\"userForm.form.valid && save()\">\n <div class=\"d-block p-24 p-b-0\">\n <div class=\"alert alert-warning\" role=\"alert\" *ngIf=\"userIsExternal\" translate>\n Some of the user settings are not editable here because they are managed via your\n authorization server.\n </div>\n <c8y-form-group>\n <label translate for=\"userName\">Username (for example, email)</label>\n <input\n id=\"userName\"\n class=\"form-control\"\n [(ngModel)]=\"user.userName\"\n name=\"userName\"\n autocomplete=\"off\"\n required\n maxlength=\"254\"\n placeholder=\"{{ 'e.g. joe.doe@example.com`LOCALIZE`' | translate }}\"\n [disabled]=\"user.id\"\n c8yDefaultValidation=\"user\"\n />\n </c8y-form-group>\n\n <c8y-form-group>\n <label translate for=\"displayName\">Login alias</label>\n <input\n id=\"displayName\"\n class=\"form-control\"\n [(ngModel)]=\"user.displayName\"\n name=\"displayName\"\n autocomplete=\"off\"\n maxlength=\"254\"\n placeholder=\"{{ 'e.g. joe.doe`LOCALIZE`' | translate }}\"\n [disabled]=\"userIsExternal\"\n c8yDefaultValidation=\"loginAlias\"\n />\n </c8y-form-group>\n\n <c8y-form-group [hasWarning]=\"!user.email\">\n <label translate for=\"userEmail\">Email</label>\n <input\n id=\"userEmail\"\n class=\"form-control\"\n type=\"email\"\n name=\"email\"\n [maxlength]=\"254\"\n autocomplete=\"off\"\n placeholder=\"{{ 'e.g. joe.doe@example.com`LOCALIZE`' | translate }}\"\n [(ngModel)]=\"user.email\"\n email\n [required]=\"true\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label translate for=\"userFirstName\">First name</label>\n <input\n id=\"userFirstName\"\n class=\"form-control\"\n autocomplete=\"off\"\n maxlength=\"50\"\n name=\"firstName\"\n [(ngModel)]=\"user.firstName\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label translate for=\"userLastName\">Last name</label>\n <input\n id=\"userLastName\"\n class=\"form-control\"\n autocomplete=\"off\"\n maxlength=\"50\"\n name=\"lastName\"\n [(ngModel)]=\"user.lastName\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n </div>\n </div>\n\n <c8y-form-group>\n <label translate for=\"userTelephone\">Telephone</label>\n <input\n id=\"userTelephone\"\n class=\"form-control\"\n autocomplete=\"off\"\n name=\"phone\"\n maxlength=\"254\"\n [(ngModel)]=\"user.phone\"\n placeholder=\"{{ 'e.g. +49 9 876 543 210`LOCALIZE`' | translate }}\"\n c8yPhoneValidation\n [required]=\"isPhoneRequired\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n\n <c8y-form-group>\n <label translate for=\"userLang\">Language</label>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"userLang\"\n class=\"form-control\"\n #selectLang\n name=\"lang\"\n [(ngModel)]=\"lang\"\n (change)=\"onLanguage.emit(selectLang.value)\"\n >\n <option *ngFor=\"let lang of langs\" [value]=\"lang\">\n {{ translate.getNativeLanguage(lang) }}\n </option>\n </select>\n <span></span>\n </div>\n </c8y-form-group>\n\n <c8y-form-group class=\"p-t-16 separator-top\" *ngIf=\"showProductUsageSetting\">\n <label translate>Product experience</label>\n <label class=\"c8y-switch\" for=\"productUsageTracking\">\n <input\n id=\"productUsageTracking\"\n name=\"productUsageTracking\"\n type=\"checkbox\"\n (change)=\"onEnablingProductUsageTracking(isUsageTrackingEnabled)\"\n [(ngModel)]=\"isUsageTrackingEnabled\"\n />\n <span></span>\n {{ 'Enable tracking to enhance the product experience' | translate }}\n </label>\n <ng-container *ngIf=\"isUsageTrackingEnabled\">\n <label class=\"c8y-switch m-l-0\" for=\"gainsightEngagements\">\n <input\n id=\"gainsightEngagements\"\n name=\"gainsightEngagements\"\n type=\"checkbox\"\n [(ngModel)]=\"isGainsightEngagementsEnabled\"\n />\n <span></span>\n {{ 'Enable in-product information & communication' | translate }}\n </label>\n </ng-container>\n </c8y-form-group>\n\n <div class=\"form-group p-t-16 separator-top\" *ngIf=\"!userIsExternal\">\n <label class=\"control-label\">{{ 'Login options' | translate }}</label>\n <c8y-new-password (password)=\"onNewPasswordChanged($event)\"></c8y-new-password>\n <button\n title=\"{{ 'Set up two-factor authentication' | translate }}\"\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"setupTotp()\"\n *ngIf=\"userCanSetupTotp && !userHasActiveTotp && isTfaEnabled\"\n >\n {{ 'Set up two-factor authentication' | translate }}\n </button>\n </div>\n\n <c8y-form-group *ngIf=\"!!(state.state$ | async).newsletter\">\n <label translate>Newsletter</label>\n <label\n title=\"{{ 'Send me information about outages, maintenance or updates.' | translate }}\"\n class=\"c8y-checkbox\"\n >\n <input\n type=\"checkbox\"\n name=\"newsletter\"\n [(ngModel)]=\"user.newsletter\"\n [disabled]=\"userIsExternal\"\n />\n <span></span>\n <span>\n {{ 'Send me information about outages, maintenance or updates.' | translate }}\n </span>\n </label>\n </c8y-form-group>\n </div>\n <div class=\"modal-footer separator-top bg-level-0 sticky-bottom\">\n <button\n title=\"{{ 'Cancel' | translate }}\"\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n title=\"{{ 'Save' | translate }}\"\n class=\"btn btn-primary\"\n type=\"submit\"\n [disabled]=\"!userForm.form.valid || userForm.form.pristine || loading\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n</form>\n", dependencies: [{ kind: "directive", type: PhoneValidationDirective, selector: "[c8yPhoneValidation]" }, { kind: "directive", type: DefaultValidationDirective, selector: "[c8yDefaultValidation]", inputs: ["c8yDefaultValidation"] }, { kind: "directive", type: i2$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$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: i2$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i2$2.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i2$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NewPasswordComponent, selector: "c8y-new-password", outputs: ["password"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }] });
|
|
13024
|
+
UserEditComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UserEditComponent, deps: [{ token: AppStateService }, { token: TranslateService }, { token: i1$8.BsModalService }, { token: AlertService }, { token: i1$2.UserService }, { token: i1$2.TenantLoginOptionsService }, { token: i1$2.TenantService }], target: i0.ɵɵFactoryTarget.Component });
|
|
13025
|
+
UserEditComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: UserEditComponent, selector: "c8y-user-edit", inputs: { lang: "lang", loading: "loading", user: "user", showProductExperienceOptions: "showProductExperienceOptions", isUsageTrackingEnabled: "isUsageTrackingEnabled", isUserEngagementPreferenceEnabled: "isUserEngagementPreferenceEnabled" }, outputs: { onUser: "onUser", onUsageTrackingChange: "onUsageTrackingChange", onUserEngagementPreferenceChange: "onUserEngagementPreferenceChange", onCancel: "onCancel", onLanguage: "onLanguage" }, ngImport: i0, template: "<form #userForm=\"ngForm\" (ngSubmit)=\"userForm.form.valid && save()\">\n <div class=\"d-block p-24 p-b-0\">\n <div class=\"alert alert-warning\" role=\"alert\" *ngIf=\"userIsExternal\" translate>\n Some of the user settings are not editable here because they are managed via your\n authorization server.\n </div>\n <c8y-form-group>\n <label translate for=\"userName\">Username (for example, email)</label>\n <input\n id=\"userName\"\n class=\"form-control\"\n [(ngModel)]=\"user.userName\"\n name=\"userName\"\n autocomplete=\"off\"\n required\n maxlength=\"254\"\n placeholder=\"{{ 'e.g. joe.doe@example.com`LOCALIZE`' | translate }}\"\n [disabled]=\"user.id\"\n c8yDefaultValidation=\"user\"\n />\n </c8y-form-group>\n\n <c8y-form-group>\n <label translate for=\"displayName\">Login alias</label>\n <input\n id=\"displayName\"\n class=\"form-control\"\n [(ngModel)]=\"user.displayName\"\n name=\"displayName\"\n autocomplete=\"off\"\n maxlength=\"254\"\n placeholder=\"{{ 'e.g. joe.doe`LOCALIZE`' | translate }}\"\n [disabled]=\"userIsExternal\"\n c8yDefaultValidation=\"loginAlias\"\n />\n </c8y-form-group>\n\n <c8y-form-group [hasWarning]=\"!user.email\">\n <label translate for=\"userEmail\">Email</label>\n <input\n id=\"userEmail\"\n class=\"form-control\"\n type=\"email\"\n name=\"email\"\n [maxlength]=\"254\"\n autocomplete=\"off\"\n placeholder=\"{{ 'e.g. joe.doe@example.com`LOCALIZE`' | translate }}\"\n [(ngModel)]=\"user.email\"\n email\n [required]=\"true\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label translate for=\"userFirstName\">First name</label>\n <input\n id=\"userFirstName\"\n class=\"form-control\"\n autocomplete=\"off\"\n maxlength=\"50\"\n name=\"firstName\"\n [(ngModel)]=\"user.firstName\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label translate for=\"userLastName\">Last name</label>\n <input\n id=\"userLastName\"\n class=\"form-control\"\n autocomplete=\"off\"\n maxlength=\"50\"\n name=\"lastName\"\n [(ngModel)]=\"user.lastName\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n </div>\n </div>\n\n <c8y-form-group>\n <label translate for=\"userTelephone\">Telephone</label>\n <input\n id=\"userTelephone\"\n class=\"form-control\"\n autocomplete=\"off\"\n name=\"phone\"\n maxlength=\"254\"\n [(ngModel)]=\"user.phone\"\n placeholder=\"{{ 'e.g. +49 9 876 543 210`LOCALIZE`' | translate }}\"\n c8yPhoneValidation\n [required]=\"isPhoneRequired\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n\n <c8y-form-group>\n <label translate for=\"userLang\">Language</label>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"userLang\"\n class=\"form-control\"\n #selectLang\n name=\"lang\"\n [(ngModel)]=\"lang\"\n (change)=\"onLanguage.emit(selectLang.value)\"\n >\n <option *ngFor=\"let lang of langs\" [value]=\"lang\">\n {{ translate.getNativeLanguage(lang) }}\n </option>\n </select>\n <span></span>\n </div>\n </c8y-form-group>\n\n <c8y-form-group class=\"p-t-16 separator-top\" *ngIf=\"showProductExperienceOptions\">\n <label translate>Product experience</label>\n <label class=\"c8y-switch\" for=\"productUsageTracking\">\n <input\n id=\"productUsageTracking\"\n name=\"productUsageTracking\"\n type=\"checkbox\"\n [(ngModel)]=\"isUsageTrackingEnabled\"\n />\n <span></span>\n {{ 'Enable personalized product experience tracking' | translate }}\n </label>\n <ng-container *ngIf=\"isUsageTrackingEnabled\">\n <label class=\"c8y-switch m-l-0\" for=\"userEngagementPreference\">\n <input\n id=\"userEngagementPreference\"\n name=\"userEngagementPreference\"\n type=\"checkbox\"\n [(ngModel)]=\"isUserEngagementPreferenceEnabled\"\n />\n <span></span>\n {{ 'Enable in-product information & communication' | translate }}\n </label>\n </ng-container>\n </c8y-form-group>\n\n <div class=\"form-group p-t-16 separator-top\" *ngIf=\"!userIsExternal\">\n <label class=\"control-label\">{{ 'Login options' | translate }}</label>\n <c8y-new-password (password)=\"onNewPasswordChanged($event)\"></c8y-new-password>\n <button\n title=\"{{ 'Set up two-factor authentication' | translate }}\"\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"setupTotp()\"\n *ngIf=\"userCanSetupTotp && !userHasActiveTotp && isTfaEnabled\"\n >\n {{ 'Set up two-factor authentication' | translate }}\n </button>\n </div>\n\n <c8y-form-group *ngIf=\"!!(state.state$ | async).newsletter\">\n <label translate>Newsletter</label>\n <label\n title=\"{{ 'Send me information about outages, maintenance or updates.' | translate }}\"\n class=\"c8y-checkbox\"\n >\n <input\n type=\"checkbox\"\n name=\"newsletter\"\n [(ngModel)]=\"user.newsletter\"\n [disabled]=\"userIsExternal\"\n />\n <span></span>\n <span>\n {{ 'Send me information about outages, maintenance or updates.' | translate }}\n </span>\n </label>\n </c8y-form-group>\n </div>\n <div class=\"modal-footer separator-top bg-level-0 sticky-bottom\">\n <button\n title=\"{{ 'Cancel' | translate }}\"\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n title=\"{{ 'Save' | translate }}\"\n class=\"btn btn-primary\"\n type=\"submit\"\n [disabled]=\"!userForm.form.valid || userForm.form.pristine || loading\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n</form>\n", dependencies: [{ kind: "directive", type: PhoneValidationDirective, selector: "[c8yPhoneValidation]" }, { kind: "directive", type: DefaultValidationDirective, selector: "[c8yDefaultValidation]", inputs: ["c8yDefaultValidation"] }, { kind: "directive", type: i2$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$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: i2$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i2$2.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i2$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NewPasswordComponent, selector: "c8y-new-password", outputs: ["password"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }] });
|
|
12767
13026
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UserEditComponent, decorators: [{
|
|
12768
13027
|
type: Component,
|
|
12769
|
-
args: [{ selector: 'c8y-user-edit', template: "<form #userForm=\"ngForm\" (ngSubmit)=\"userForm.form.valid && save()\">\n <div class=\"d-block p-24 p-b-0\">\n <div class=\"alert alert-warning\" role=\"alert\" *ngIf=\"userIsExternal\" translate>\n Some of the user settings are not editable here because they are managed via your\n authorization server.\n </div>\n <c8y-form-group>\n <label translate for=\"userName\">Username (for example, email)</label>\n <input\n id=\"userName\"\n class=\"form-control\"\n [(ngModel)]=\"user.userName\"\n name=\"userName\"\n autocomplete=\"off\"\n required\n maxlength=\"254\"\n placeholder=\"{{ 'e.g. joe.doe@example.com`LOCALIZE`' | translate }}\"\n [disabled]=\"user.id\"\n c8yDefaultValidation=\"user\"\n />\n </c8y-form-group>\n\n <c8y-form-group>\n <label translate for=\"displayName\">Login alias</label>\n <input\n id=\"displayName\"\n class=\"form-control\"\n [(ngModel)]=\"user.displayName\"\n name=\"displayName\"\n autocomplete=\"off\"\n maxlength=\"254\"\n placeholder=\"{{ 'e.g. joe.doe`LOCALIZE`' | translate }}\"\n [disabled]=\"userIsExternal\"\n c8yDefaultValidation=\"loginAlias\"\n />\n </c8y-form-group>\n\n <c8y-form-group [hasWarning]=\"!user.email\">\n <label translate for=\"userEmail\">Email</label>\n <input\n id=\"userEmail\"\n class=\"form-control\"\n type=\"email\"\n name=\"email\"\n [maxlength]=\"254\"\n autocomplete=\"off\"\n placeholder=\"{{ 'e.g. joe.doe@example.com`LOCALIZE`' | translate }}\"\n [(ngModel)]=\"user.email\"\n email\n [required]=\"true\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label translate for=\"userFirstName\">First name</label>\n <input\n id=\"userFirstName\"\n class=\"form-control\"\n autocomplete=\"off\"\n maxlength=\"50\"\n name=\"firstName\"\n [(ngModel)]=\"user.firstName\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label translate for=\"userLastName\">Last name</label>\n <input\n id=\"userLastName\"\n class=\"form-control\"\n autocomplete=\"off\"\n maxlength=\"50\"\n name=\"lastName\"\n [(ngModel)]=\"user.lastName\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n </div>\n </div>\n\n <c8y-form-group>\n <label translate for=\"userTelephone\">Telephone</label>\n <input\n id=\"userTelephone\"\n class=\"form-control\"\n autocomplete=\"off\"\n name=\"phone\"\n maxlength=\"254\"\n [(ngModel)]=\"user.phone\"\n placeholder=\"{{ 'e.g. +49 9 876 543 210`LOCALIZE`' | translate }}\"\n c8yPhoneValidation\n [required]=\"isPhoneRequired\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n\n
|
|
12770
|
-
}], ctorParameters: function () { return [{ type: AppStateService }, { type: TranslateService }, { type: i1$8.BsModalService }, { type: AlertService }, { type: i1$2.UserService }, { type: i1$2.TenantLoginOptionsService }, { type: i1$2.TenantService }
|
|
13028
|
+
args: [{ selector: 'c8y-user-edit', template: "<form #userForm=\"ngForm\" (ngSubmit)=\"userForm.form.valid && save()\">\n <div class=\"d-block p-24 p-b-0\">\n <div class=\"alert alert-warning\" role=\"alert\" *ngIf=\"userIsExternal\" translate>\n Some of the user settings are not editable here because they are managed via your\n authorization server.\n </div>\n <c8y-form-group>\n <label translate for=\"userName\">Username (for example, email)</label>\n <input\n id=\"userName\"\n class=\"form-control\"\n [(ngModel)]=\"user.userName\"\n name=\"userName\"\n autocomplete=\"off\"\n required\n maxlength=\"254\"\n placeholder=\"{{ 'e.g. joe.doe@example.com`LOCALIZE`' | translate }}\"\n [disabled]=\"user.id\"\n c8yDefaultValidation=\"user\"\n />\n </c8y-form-group>\n\n <c8y-form-group>\n <label translate for=\"displayName\">Login alias</label>\n <input\n id=\"displayName\"\n class=\"form-control\"\n [(ngModel)]=\"user.displayName\"\n name=\"displayName\"\n autocomplete=\"off\"\n maxlength=\"254\"\n placeholder=\"{{ 'e.g. joe.doe`LOCALIZE`' | translate }}\"\n [disabled]=\"userIsExternal\"\n c8yDefaultValidation=\"loginAlias\"\n />\n </c8y-form-group>\n\n <c8y-form-group [hasWarning]=\"!user.email\">\n <label translate for=\"userEmail\">Email</label>\n <input\n id=\"userEmail\"\n class=\"form-control\"\n type=\"email\"\n name=\"email\"\n [maxlength]=\"254\"\n autocomplete=\"off\"\n placeholder=\"{{ 'e.g. joe.doe@example.com`LOCALIZE`' | translate }}\"\n [(ngModel)]=\"user.email\"\n email\n [required]=\"true\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label translate for=\"userFirstName\">First name</label>\n <input\n id=\"userFirstName\"\n class=\"form-control\"\n autocomplete=\"off\"\n maxlength=\"50\"\n name=\"firstName\"\n [(ngModel)]=\"user.firstName\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label translate for=\"userLastName\">Last name</label>\n <input\n id=\"userLastName\"\n class=\"form-control\"\n autocomplete=\"off\"\n maxlength=\"50\"\n name=\"lastName\"\n [(ngModel)]=\"user.lastName\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n </div>\n </div>\n\n <c8y-form-group>\n <label translate for=\"userTelephone\">Telephone</label>\n <input\n id=\"userTelephone\"\n class=\"form-control\"\n autocomplete=\"off\"\n name=\"phone\"\n maxlength=\"254\"\n [(ngModel)]=\"user.phone\"\n placeholder=\"{{ 'e.g. +49 9 876 543 210`LOCALIZE`' | translate }}\"\n c8yPhoneValidation\n [required]=\"isPhoneRequired\"\n [disabled]=\"userIsExternal\"\n />\n </c8y-form-group>\n\n <c8y-form-group>\n <label translate for=\"userLang\">Language</label>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"userLang\"\n class=\"form-control\"\n #selectLang\n name=\"lang\"\n [(ngModel)]=\"lang\"\n (change)=\"onLanguage.emit(selectLang.value)\"\n >\n <option *ngFor=\"let lang of langs\" [value]=\"lang\">\n {{ translate.getNativeLanguage(lang) }}\n </option>\n </select>\n <span></span>\n </div>\n </c8y-form-group>\n\n <c8y-form-group class=\"p-t-16 separator-top\" *ngIf=\"showProductExperienceOptions\">\n <label translate>Product experience</label>\n <label class=\"c8y-switch\" for=\"productUsageTracking\">\n <input\n id=\"productUsageTracking\"\n name=\"productUsageTracking\"\n type=\"checkbox\"\n [(ngModel)]=\"isUsageTrackingEnabled\"\n />\n <span></span>\n {{ 'Enable personalized product experience tracking' | translate }}\n </label>\n <ng-container *ngIf=\"isUsageTrackingEnabled\">\n <label class=\"c8y-switch m-l-0\" for=\"userEngagementPreference\">\n <input\n id=\"userEngagementPreference\"\n name=\"userEngagementPreference\"\n type=\"checkbox\"\n [(ngModel)]=\"isUserEngagementPreferenceEnabled\"\n />\n <span></span>\n {{ 'Enable in-product information & communication' | translate }}\n </label>\n </ng-container>\n </c8y-form-group>\n\n <div class=\"form-group p-t-16 separator-top\" *ngIf=\"!userIsExternal\">\n <label class=\"control-label\">{{ 'Login options' | translate }}</label>\n <c8y-new-password (password)=\"onNewPasswordChanged($event)\"></c8y-new-password>\n <button\n title=\"{{ 'Set up two-factor authentication' | translate }}\"\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"setupTotp()\"\n *ngIf=\"userCanSetupTotp && !userHasActiveTotp && isTfaEnabled\"\n >\n {{ 'Set up two-factor authentication' | translate }}\n </button>\n </div>\n\n <c8y-form-group *ngIf=\"!!(state.state$ | async).newsletter\">\n <label translate>Newsletter</label>\n <label\n title=\"{{ 'Send me information about outages, maintenance or updates.' | translate }}\"\n class=\"c8y-checkbox\"\n >\n <input\n type=\"checkbox\"\n name=\"newsletter\"\n [(ngModel)]=\"user.newsletter\"\n [disabled]=\"userIsExternal\"\n />\n <span></span>\n <span>\n {{ 'Send me information about outages, maintenance or updates.' | translate }}\n </span>\n </label>\n </c8y-form-group>\n </div>\n <div class=\"modal-footer separator-top bg-level-0 sticky-bottom\">\n <button\n title=\"{{ 'Cancel' | translate }}\"\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n title=\"{{ 'Save' | translate }}\"\n class=\"btn btn-primary\"\n type=\"submit\"\n [disabled]=\"!userForm.form.valid || userForm.form.pristine || loading\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n</form>\n" }]
|
|
13029
|
+
}], ctorParameters: function () { return [{ type: AppStateService }, { type: TranslateService }, { type: i1$8.BsModalService }, { type: AlertService }, { type: i1$2.UserService }, { type: i1$2.TenantLoginOptionsService }, { type: i1$2.TenantService }]; }, propDecorators: { lang: [{
|
|
12771
13030
|
type: Input
|
|
12772
13031
|
}], loading: [{
|
|
12773
13032
|
type: Input
|
|
12774
13033
|
}], user: [{
|
|
12775
13034
|
type: Input
|
|
12776
|
-
}],
|
|
13035
|
+
}], showProductExperienceOptions: [{
|
|
12777
13036
|
type: Input
|
|
12778
13037
|
}], isUsageTrackingEnabled: [{
|
|
12779
13038
|
type: Input
|
|
12780
|
-
}],
|
|
13039
|
+
}], isUserEngagementPreferenceEnabled: [{
|
|
12781
13040
|
type: Input
|
|
12782
13041
|
}], onUser: [{
|
|
12783
13042
|
type: Output
|
|
12784
|
-
}],
|
|
12785
|
-
type: Output
|
|
12786
|
-
}], onProductExperience: [{
|
|
13043
|
+
}], onUsageTrackingChange: [{
|
|
12787
13044
|
type: Output
|
|
12788
|
-
}],
|
|
13045
|
+
}], onUserEngagementPreferenceChange: [{
|
|
12789
13046
|
type: Output
|
|
12790
13047
|
}], onCancel: [{
|
|
12791
13048
|
type: Output
|
|
13049
|
+
}], onLanguage: [{
|
|
13050
|
+
type: Output
|
|
12792
13051
|
}] } });
|
|
12793
13052
|
|
|
12794
13053
|
class UserEditModalComponent {
|
|
12795
|
-
constructor(modal, user, ui, auth, client, alert, translate, userPreferences, c8yModalService, gainsightService, cookieBannerService, loginService, passwordService) {
|
|
13054
|
+
constructor(modal, user, ui, auth, client, alert, translate, userPreferences, c8yModalService, gainsightService, cookieBannerService, loginService, passwordService, userEngagementsService) {
|
|
12796
13055
|
this.modal = modal;
|
|
12797
13056
|
this.user = user;
|
|
12798
13057
|
this.ui = ui;
|
|
@@ -12806,20 +13065,34 @@ class UserEditModalComponent {
|
|
|
12806
13065
|
this.cookieBannerService = cookieBannerService;
|
|
12807
13066
|
this.loginService = loginService;
|
|
12808
13067
|
this.passwordService = passwordService;
|
|
13068
|
+
this.userEngagementsService = userEngagementsService;
|
|
12809
13069
|
this.loading = false;
|
|
12810
|
-
this.
|
|
13070
|
+
this.showProductExperienceOptions = false;
|
|
12811
13071
|
this.lang = this.ui.state.lang;
|
|
12812
13072
|
}
|
|
12813
13073
|
async ngOnInit() {
|
|
12814
13074
|
this.updateUserInAppState();
|
|
12815
|
-
|
|
12816
|
-
|
|
12817
|
-
|
|
12818
|
-
|
|
12819
|
-
|
|
12820
|
-
|
|
12821
|
-
|
|
12822
|
-
|
|
13075
|
+
await this.setInitialProductExperienceOptions();
|
|
13076
|
+
}
|
|
13077
|
+
/**
|
|
13078
|
+
* Initializes product experience options for the user.
|
|
13079
|
+
*
|
|
13080
|
+
* This function performs the following operations:
|
|
13081
|
+
* - Determines if the user has the permission to edit product experience options.
|
|
13082
|
+
* - If the user has the permission and functional cookies are enabled:
|
|
13083
|
+
* - Checks whether personalized product experience tracking is active.
|
|
13084
|
+
* - Checks whether in-product information and communication is active.
|
|
13085
|
+
*/
|
|
13086
|
+
async setInitialProductExperienceOptions() {
|
|
13087
|
+
this.showProductExperienceOptions =
|
|
13088
|
+
await this.gainsightService.canEditProductExperienceSettings();
|
|
13089
|
+
if (this.showProductExperienceOptions && this.cookieBannerService.isFunctionalCookieEnabled()) {
|
|
13090
|
+
// Enable personalized product experience tracking option
|
|
13091
|
+
this.currentUsageTrackingState =
|
|
13092
|
+
!(await this.gainsightService.isGainsightPreferenceDisabledInUserPreferences(this.gainsightService.USER_PREFERENCES_GAINSIGHT_KEY));
|
|
13093
|
+
// Enable in-product information & communication option
|
|
13094
|
+
this.currentUserEngagementPreferenceInitialState =
|
|
13095
|
+
this.userEngagementsService.userEngagementsEnabled$.value;
|
|
12823
13096
|
}
|
|
12824
13097
|
}
|
|
12825
13098
|
async onDismiss() {
|
|
@@ -12832,11 +13105,11 @@ class UserEditModalComponent {
|
|
|
12832
13105
|
this.changedLang = lang;
|
|
12833
13106
|
await this.translate.switchToLanguage(this.changedLang);
|
|
12834
13107
|
}
|
|
12835
|
-
|
|
12836
|
-
this.usageTrackingState =
|
|
13108
|
+
onUsageTrackingChange(isEnabled) {
|
|
13109
|
+
this.usageTrackingState = isEnabled;
|
|
12837
13110
|
}
|
|
12838
|
-
|
|
12839
|
-
this.
|
|
13111
|
+
onUserEngagementPreferenceChange(isEnabled) {
|
|
13112
|
+
this.userEngagementPreferenceNewState = isEnabled;
|
|
12840
13113
|
}
|
|
12841
13114
|
async updateAndClose(user) {
|
|
12842
13115
|
this.loading = true;
|
|
@@ -12858,16 +13131,7 @@ class UserEditModalComponent {
|
|
|
12858
13131
|
if (this.changedLang && this.changedLang !== this.lang) {
|
|
12859
13132
|
reloadRequired = await this.persistLanguage(this.changedLang);
|
|
12860
13133
|
}
|
|
12861
|
-
|
|
12862
|
-
await this.userPreferences.set(this.gainsightService.USER_PREFERENCES_GAINSIGHT_ENGAGEMENTS_KEY, this.gainsightEngagementsState);
|
|
12863
|
-
}
|
|
12864
|
-
if (this.currentUsageTrackingState !== this.usageTrackingState) {
|
|
12865
|
-
await this.userPreferences.set(this.gainsightService.USER_PREFERENCES_GAINSIGHT_KEY, this.usageTrackingState);
|
|
12866
|
-
this.gainsightService.setFunctionalCookie(this.usageTrackingState);
|
|
12867
|
-
this.usageTrackingState
|
|
12868
|
-
? await this.gainsightService.loadTag(this.client.tenant)
|
|
12869
|
-
: await this.gainsightTrackingAppReload();
|
|
12870
|
-
}
|
|
13134
|
+
await this.updateProductExperienceOptions();
|
|
12871
13135
|
if (user.customProperties.userOrigin !== 'OAUTH2') {
|
|
12872
13136
|
await this.user.updateCurrent(omit(user, 'password'));
|
|
12873
13137
|
await this.updateUserInAppState();
|
|
@@ -12919,6 +13183,34 @@ class UserEditModalComponent {
|
|
|
12919
13183
|
// do nothing
|
|
12920
13184
|
}
|
|
12921
13185
|
}
|
|
13186
|
+
async updateProductExperienceOptions() {
|
|
13187
|
+
this.updateUserEngagementsPreference();
|
|
13188
|
+
await this.updateTrackingOption();
|
|
13189
|
+
}
|
|
13190
|
+
/**
|
|
13191
|
+
* Updates the user engagement preference if it has changed from the initial state.
|
|
13192
|
+
* Calls the user engagements service to update the preference.
|
|
13193
|
+
*
|
|
13194
|
+
* The update only occurs if the current preference differs from the new state.
|
|
13195
|
+
*/
|
|
13196
|
+
updateUserEngagementsPreference() {
|
|
13197
|
+
if (this.currentUserEngagementPreferenceInitialState !== this.userEngagementPreferenceNewState) {
|
|
13198
|
+
this.userEngagementsService.updateUserEngagementPreference(this.userEngagementPreferenceNewState);
|
|
13199
|
+
}
|
|
13200
|
+
}
|
|
13201
|
+
/**
|
|
13202
|
+
* Asynchronously updates the tracking option for user preferences.
|
|
13203
|
+
* If the current usage tracking state differs from the new state,
|
|
13204
|
+
* it updates the Gainsight preferences and sets a functional cookie
|
|
13205
|
+
* before triggering a reload of the application.
|
|
13206
|
+
*/
|
|
13207
|
+
async updateTrackingOption() {
|
|
13208
|
+
if (this.currentUsageTrackingState !== this.usageTrackingState) {
|
|
13209
|
+
await this.userPreferences.set(this.gainsightService.USER_PREFERENCES_GAINSIGHT_KEY, this.usageTrackingState);
|
|
13210
|
+
this.gainsightService.setFunctionalCookie(this.usageTrackingState);
|
|
13211
|
+
await this.gainsightTrackingAppReload();
|
|
13212
|
+
}
|
|
13213
|
+
}
|
|
12922
13214
|
async updateUserInAppState() {
|
|
12923
13215
|
const currentUserResult = await this.user.current();
|
|
12924
13216
|
this.ui.currentUser.next(currentUserResult.data);
|
|
@@ -12932,12 +13224,12 @@ class UserEditModalComponent {
|
|
|
12932
13224
|
this.auth.updateCredentials(newCredentials);
|
|
12933
13225
|
}
|
|
12934
13226
|
}
|
|
12935
|
-
UserEditModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UserEditModalComponent, deps: [{ token: i1$8.BsModalRef }, { token: i1$2.UserService }, { token: AppStateService }, { token: i1$2.BasicAuth }, { token: i1$2.FetchClient }, { token: AlertService }, { token: TranslateService }, { token: UserPreferencesService }, { token: ModalService }, { token: GainsightService }, { token: CookieBannerService }, { token: LoginService }, { token: PasswordService }], target: i0.ɵɵFactoryTarget.Component });
|
|
12936
|
-
UserEditModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: UserEditModalComponent, selector: "c8y-user-edit-modal", ngImport: i0, template: "<c8y-modal
|
|
13227
|
+
UserEditModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UserEditModalComponent, deps: [{ token: i1$8.BsModalRef }, { token: i1$2.UserService }, { token: AppStateService }, { token: i1$2.BasicAuth }, { token: i1$2.FetchClient }, { token: AlertService }, { token: TranslateService }, { token: UserPreferencesService }, { token: ModalService }, { token: GainsightService }, { token: CookieBannerService }, { token: LoginService }, { token: PasswordService }, { token: UserEngagementsService }], target: i0.ɵɵFactoryTarget.Component });
|
|
13228
|
+
UserEditModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: UserEditModalComponent, selector: "c8y-user-edit-modal", ngImport: i0, template: "<c8y-modal\n [title]=\"'Edit user' | translate\"\n [customFooter]=\"true\"\n (onDismiss)=\"onDismiss()\"\n>\n <c8y-user-edit\n [lang]=\"lang\"\n [user]=\"ui.currentUser | async\"\n [loading]=\"loading\"\n [isUsageTrackingEnabled]=\"currentUsageTrackingState\"\n [isUserEngagementPreferenceEnabled]=\"currentUserEngagementPreferenceInitialState\"\n [showProductExperienceOptions]=\"showProductExperienceOptions\"\n (onUsageTrackingChange)=\"onUsageTrackingChange($event)\"\n (onUserEngagementPreferenceChange)=\"onUserEngagementPreferenceChange($event)\"\n (onUser)=\"updateAndClose($event)\"\n (onCancel)=\"onDismiss()\"\n (onLanguage)=\"onLanguage($event)\"\n ></c8y-user-edit>\n</c8y-modal>\n", dependencies: [{ kind: "component", type: ModalComponent, selector: "c8y-modal", inputs: ["disabled", "close", "dismiss", "title", "body", "customFooter", "headerClasses", "labels"], outputs: ["onDismiss", "onClose"] }, { kind: "component", type: UserEditComponent, selector: "c8y-user-edit", inputs: ["lang", "loading", "user", "showProductExperienceOptions", "isUsageTrackingEnabled", "isUserEngagementPreferenceEnabled"], outputs: ["onUser", "onUsageTrackingChange", "onUserEngagementPreferenceChange", "onCancel", "onLanguage"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }] });
|
|
12937
13229
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UserEditModalComponent, decorators: [{
|
|
12938
13230
|
type: Component,
|
|
12939
|
-
args: [{ selector: 'c8y-user-edit-modal', template: "<c8y-modal
|
|
12940
|
-
}], ctorParameters: function () { return [{ type: i1$8.BsModalRef }, { type: i1$2.UserService }, { type: AppStateService }, { type: i1$2.BasicAuth }, { type: i1$2.FetchClient }, { type: AlertService }, { type: TranslateService }, { type: UserPreferencesService }, { type: ModalService }, { type: GainsightService }, { type: CookieBannerService }, { type: LoginService }, { type: PasswordService }]; } });
|
|
13231
|
+
args: [{ selector: 'c8y-user-edit-modal', template: "<c8y-modal\n [title]=\"'Edit user' | translate\"\n [customFooter]=\"true\"\n (onDismiss)=\"onDismiss()\"\n>\n <c8y-user-edit\n [lang]=\"lang\"\n [user]=\"ui.currentUser | async\"\n [loading]=\"loading\"\n [isUsageTrackingEnabled]=\"currentUsageTrackingState\"\n [isUserEngagementPreferenceEnabled]=\"currentUserEngagementPreferenceInitialState\"\n [showProductExperienceOptions]=\"showProductExperienceOptions\"\n (onUsageTrackingChange)=\"onUsageTrackingChange($event)\"\n (onUserEngagementPreferenceChange)=\"onUserEngagementPreferenceChange($event)\"\n (onUser)=\"updateAndClose($event)\"\n (onCancel)=\"onDismiss()\"\n (onLanguage)=\"onLanguage($event)\"\n ></c8y-user-edit>\n</c8y-modal>\n" }]
|
|
13232
|
+
}], ctorParameters: function () { return [{ type: i1$8.BsModalRef }, { type: i1$2.UserService }, { type: AppStateService }, { type: i1$2.BasicAuth }, { type: i1$2.FetchClient }, { type: AlertService }, { type: TranslateService }, { type: UserPreferencesService }, { type: ModalService }, { type: GainsightService }, { type: CookieBannerService }, { type: LoginService }, { type: PasswordService }, { type: UserEngagementsService }]; } });
|
|
12941
13233
|
|
|
12942
13234
|
class UserMenuItemComponent {
|
|
12943
13235
|
constructor(userService) {
|
|
@@ -13430,6 +13722,7 @@ class RightDrawerComponent {
|
|
|
13430
13722
|
this.appState = appState;
|
|
13431
13723
|
this.userMenuService = userMenuService;
|
|
13432
13724
|
this.options = options;
|
|
13725
|
+
this.PRODUCT_EXPERIENCE = PRODUCT_EXPERIENCE;
|
|
13433
13726
|
this.closeDrawer = new EventEmitter();
|
|
13434
13727
|
this.quickLinks = [];
|
|
13435
13728
|
this.helpAndSupport = [];
|
|
@@ -13459,10 +13752,10 @@ class RightDrawerComponent {
|
|
|
13459
13752
|
}
|
|
13460
13753
|
}
|
|
13461
13754
|
RightDrawerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: RightDrawerComponent, deps: [{ token: AppStateService }, { token: UserMenuService }, { token: OptionsService }], target: i0.ɵɵFactoryTarget.Component });
|
|
13462
|
-
RightDrawerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: RightDrawerComponent, selector: "c8y-right-drawer", inputs: { _quickLinks: ["quickLinks", "_quickLinks"], _helpAndSupport: ["helpAndSupport", "_helpAndSupport"], app: "app", drawerOpen: "drawerOpen" }, outputs: { closeDrawer: "closeDrawer" }, ngImport: i0, template: "<aside class=\"c8y-right-drawer\" [cdkTrapFocus]=\"drawerOpen\">\n<!-- drawer header -->\n <div class=\"c8y-right-drawer__header separator-bottom\">\n <button type=\"button\" class=\"close\" title=\"{{'Close' | translate}}\" (click)=\"close()\">×</button>\n <div class=\"d-flex a-i-center\">\n <div class=\"user-dot\"> {{appState.currentUser | async | userNameInitials}}</div>\n <div class=\"min-width-0\">\n <p\n *ngIf=\"appState.currentUser | async\"\n class=\"text-truncate text-medium text-16\"\n title=\"{{appState.currentUser | async | shortenUserName}}\"\n >\n {{appState.currentUser | async | shortenUserName}}\n </p>\n <small *ngIf=\"appState.currentUser | async | userRolesList as userRoles\" [title]=\"userRoles\" class=\"text-truncate\">{{ userRoles }}</small>\n </div>\n </div>\n </div>\n\n <!-- user menu -->\n <c8y-user-menu-outlet\n [items]=\"(userMenuService.items$ | async)\"\n class=\"c8y-right-drawer__container\"\n ></c8y-user-menu-outlet>\n\n <!-- Version list -->\n <c8y-version-list *ngIf=\"showPlatformInformation\"></c8y-version-list>\n\n<!-- quicklinks > bookmarks -->\n <div *ngIf=\"(appState$ | async).showRightDrawer && quickLinks.length\"\n class=\"separator-top p-t-8 p-b-8\">\n <div class=\"c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"bookmark\"></i>\n <span class=\"text-bold\">{{ 'Quick links' | translate }}</span>\n </div>\n\n <ng-container *ngFor=\"let quickLink of quickLinks\">\n <ng-container *ngIf=\"quickLink.component\">\n <ng-container\n *ngComponentOutlet=\"quickLink.component; injector: quickLink.injector\"\n ></ng-container>\n </ng-container>\n <a\n *ngIf=\"!quickLink.component\"\n title=\"{{ quickLink.label | translate }}\"\n type=\"button\"\n class=\"c8y-right-drawer__link\"\n [href]=\"quickLink.url || '#'\"\n (click)=\"quickLink.click && $event.preventDefault(); quickLink.click && quickLink.click()\"\n c8yProductExperience\n [actionName]=\"
|
|
13755
|
+
RightDrawerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: RightDrawerComponent, selector: "c8y-right-drawer", inputs: { _quickLinks: ["quickLinks", "_quickLinks"], _helpAndSupport: ["helpAndSupport", "_helpAndSupport"], app: "app", drawerOpen: "drawerOpen" }, outputs: { closeDrawer: "closeDrawer" }, ngImport: i0, template: "<aside class=\"c8y-right-drawer\" [cdkTrapFocus]=\"drawerOpen\">\n<!-- drawer header -->\n <div class=\"c8y-right-drawer__header separator-bottom\">\n <button type=\"button\" class=\"close\" title=\"{{'Close' | translate}}\" (click)=\"close()\">×</button>\n <div class=\"d-flex a-i-center\">\n <div class=\"user-dot\"> {{appState.currentUser | async | userNameInitials}}</div>\n <div class=\"min-width-0\">\n <p\n *ngIf=\"appState.currentUser | async\"\n class=\"text-truncate text-medium text-16\"\n title=\"{{appState.currentUser | async | shortenUserName}}\"\n >\n {{appState.currentUser | async | shortenUserName}}\n </p>\n <small *ngIf=\"appState.currentUser | async | userRolesList as userRoles\" [title]=\"userRoles\" class=\"text-truncate\">{{ userRoles }}</small>\n </div>\n </div>\n </div>\n\n <!-- user menu -->\n <c8y-user-menu-outlet\n [items]=\"(userMenuService.items$ | async)\"\n class=\"c8y-right-drawer__container\"\n ></c8y-user-menu-outlet>\n\n <!-- Version list -->\n <c8y-version-list *ngIf=\"showPlatformInformation\"></c8y-version-list>\n\n<!-- quicklinks > bookmarks -->\n <div *ngIf=\"(appState$ | async).showRightDrawer && quickLinks.length\"\n class=\"separator-top p-t-8 p-b-8\">\n <div class=\"c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"bookmark\"></i>\n <span class=\"text-bold\">{{ 'Quick links' | translate }}</span>\n </div>\n\n <ng-container *ngFor=\"let quickLink of quickLinks\">\n <ng-container *ngIf=\"quickLink.component\">\n <ng-container\n *ngComponentOutlet=\"quickLink.component; injector: quickLink.injector\"\n ></ng-container>\n </ng-container>\n <a\n *ngIf=\"!quickLink.component\"\n title=\"{{ quickLink.label | translate }}\"\n type=\"button\"\n class=\"c8y-right-drawer__link\"\n [href]=\"quickLink.url || '#'\"\n (click)=\"quickLink.click && $event.preventDefault(); quickLink.click && quickLink.click()\"\n c8yProductExperience\n [actionName]=\"PRODUCT_EXPERIENCE.QUICK_LINKS.EVENTS.QUICK_LINK_RIGHT_DRAWER\"\n [actionData]=\"{\n component: PRODUCT_EXPERIENCE.QUICK_LINKS.COMPONENTS.RIGHT_DRAWER_COMPONENT,\n action: quickLink.label\n }\"\n tabindex=\"{{ drawerOpen ? '0' : '-1' }}\"\n >\n <i *ngIf=\"quickLink.icon\" class=\"{{ quickLink.icon }} c8y-icon-duocolor\"></i>\n <img\n *ngIf=\"quickLink.iconSrc\"\n [src]=\"quickLink.iconSrc\"\n style=\"max-width: 20px\"\n class=\"img-responsive\"\n onerror=\"this.style.display = 'none'\"\n />\n <span>{{ quickLink.label | translate }}</span>\n </a>\n </ng-container>\n\n </div>\n\n <div *ngIf=\"(appState$ | async).showRightDrawer && helpAndSupport.length\"\n class=\"separator-top p-t-8 p-b-8\">\n <button type=\"button\" class=\"c8y-right-drawer__link sticky-top\" (click)=\"documentationOpen = !documentationOpen\"\n [attr.aria-expanded]=\"!documentationCol.isCollapsed\" [attr.aria-controls]=\"'collapseDocs'\">\n <i c8yIcon=\"book-shelf\"></i>\n <span class=\"text-bold\">{{ 'Documentation' | translate }}</span>\n <i c8yIcon=\"angle-down\" class=\"m-l-auto\" [ngClass]=\"{'icon-rotate-180': documentationOpen }\"></i>\n </button>\n <div class=\"collapse\" id=\"collapseDocs\" [collapse]=\"!documentationOpen\" [isAnimated]=\"true\" #documentationCol=\"bs-collapse\">\n <ng-container *ngFor=\"let link of helpAndSupport\">\n <ng-container *ngIf=\"link.component\">\n <ng-container *ngComponentOutlet=\"link.component; injector: link.injector\"></ng-container>\n </ng-container>\n <a\n *ngIf=\"!link.component\"\n title=\"{{ link.label | translate }}\"\n type=\"button\"\n class=\"c8y-right-drawer__link\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n [href]=\"link.url\"\n c8yProductExperience\n [actionName]=\"PRODUCT_EXPERIENCE.QUICK_LINKS.EVENTS.QUICK_LINK_RIGHT_DRAWER\"\n [actionData]=\"{\n component: PRODUCT_EXPERIENCE.QUICK_LINKS.COMPONENTS.RIGHT_DRAWER_COMPONENT,\n action: link.label\n }\"\n tabindex=\"{{ drawerOpen ? '0' : '-1' }}\"\n >\n <span title=\"{{ link.label | translate }}\" class=\"text-truncate text-12\">\n {{ link.label | translate }}\n </span>\n </a>\n </ng-container>\n </div>\n </div>\n\n <!-- TODO: move legal notices here -->\n <!-- <div class=\"separator-top p-t-8 m-t-auto\">\n <a href=\"#\" class=\"c8y-right-drawer__link\">\n <small>Legal notices</small>\n </a>\n </div> -->\n</aside>\n", dependencies: [{ kind: "directive", type: i4.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: UserMenuOutletComponent, selector: "c8y-user-menu-outlet", inputs: ["items"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: VersionListComponent, selector: "c8y-version-list" }, { kind: "directive", type: i1$9.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "directive", type: ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "pipe", type: ShortenUserNamePipe, name: "shortenUserName" }, { kind: "pipe", type: UserNameInitialsPipe, name: "userNameInitials" }, { kind: "pipe", type: UserRolesListPipe, name: "userRolesList" }] });
|
|
13463
13756
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: RightDrawerComponent, decorators: [{
|
|
13464
13757
|
type: Component,
|
|
13465
|
-
args: [{ selector: 'c8y-right-drawer', template: "<aside class=\"c8y-right-drawer\" [cdkTrapFocus]=\"drawerOpen\">\n<!-- drawer header -->\n <div class=\"c8y-right-drawer__header separator-bottom\">\n <button type=\"button\" class=\"close\" title=\"{{'Close' | translate}}\" (click)=\"close()\">×</button>\n <div class=\"d-flex a-i-center\">\n <div class=\"user-dot\"> {{appState.currentUser | async | userNameInitials}}</div>\n <div class=\"min-width-0\">\n <p\n *ngIf=\"appState.currentUser | async\"\n class=\"text-truncate text-medium text-16\"\n title=\"{{appState.currentUser | async | shortenUserName}}\"\n >\n {{appState.currentUser | async | shortenUserName}}\n </p>\n <small *ngIf=\"appState.currentUser | async | userRolesList as userRoles\" [title]=\"userRoles\" class=\"text-truncate\">{{ userRoles }}</small>\n </div>\n </div>\n </div>\n\n <!-- user menu -->\n <c8y-user-menu-outlet\n [items]=\"(userMenuService.items$ | async)\"\n class=\"c8y-right-drawer__container\"\n ></c8y-user-menu-outlet>\n\n <!-- Version list -->\n <c8y-version-list *ngIf=\"showPlatformInformation\"></c8y-version-list>\n\n<!-- quicklinks > bookmarks -->\n <div *ngIf=\"(appState$ | async).showRightDrawer && quickLinks.length\"\n class=\"separator-top p-t-8 p-b-8\">\n <div class=\"c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"bookmark\"></i>\n <span class=\"text-bold\">{{ 'Quick links' | translate }}</span>\n </div>\n\n <ng-container *ngFor=\"let quickLink of quickLinks\">\n <ng-container *ngIf=\"quickLink.component\">\n <ng-container\n *ngComponentOutlet=\"quickLink.component; injector: quickLink.injector\"\n ></ng-container>\n </ng-container>\n <a\n *ngIf=\"!quickLink.component\"\n title=\"{{ quickLink.label | translate }}\"\n type=\"button\"\n class=\"c8y-right-drawer__link\"\n [href]=\"quickLink.url || '#'\"\n (click)=\"quickLink.click && $event.preventDefault(); quickLink.click && quickLink.click()\"\n c8yProductExperience\n [actionName]=\"
|
|
13758
|
+
args: [{ selector: 'c8y-right-drawer', template: "<aside class=\"c8y-right-drawer\" [cdkTrapFocus]=\"drawerOpen\">\n<!-- drawer header -->\n <div class=\"c8y-right-drawer__header separator-bottom\">\n <button type=\"button\" class=\"close\" title=\"{{'Close' | translate}}\" (click)=\"close()\">×</button>\n <div class=\"d-flex a-i-center\">\n <div class=\"user-dot\"> {{appState.currentUser | async | userNameInitials}}</div>\n <div class=\"min-width-0\">\n <p\n *ngIf=\"appState.currentUser | async\"\n class=\"text-truncate text-medium text-16\"\n title=\"{{appState.currentUser | async | shortenUserName}}\"\n >\n {{appState.currentUser | async | shortenUserName}}\n </p>\n <small *ngIf=\"appState.currentUser | async | userRolesList as userRoles\" [title]=\"userRoles\" class=\"text-truncate\">{{ userRoles }}</small>\n </div>\n </div>\n </div>\n\n <!-- user menu -->\n <c8y-user-menu-outlet\n [items]=\"(userMenuService.items$ | async)\"\n class=\"c8y-right-drawer__container\"\n ></c8y-user-menu-outlet>\n\n <!-- Version list -->\n <c8y-version-list *ngIf=\"showPlatformInformation\"></c8y-version-list>\n\n<!-- quicklinks > bookmarks -->\n <div *ngIf=\"(appState$ | async).showRightDrawer && quickLinks.length\"\n class=\"separator-top p-t-8 p-b-8\">\n <div class=\"c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"bookmark\"></i>\n <span class=\"text-bold\">{{ 'Quick links' | translate }}</span>\n </div>\n\n <ng-container *ngFor=\"let quickLink of quickLinks\">\n <ng-container *ngIf=\"quickLink.component\">\n <ng-container\n *ngComponentOutlet=\"quickLink.component; injector: quickLink.injector\"\n ></ng-container>\n </ng-container>\n <a\n *ngIf=\"!quickLink.component\"\n title=\"{{ quickLink.label | translate }}\"\n type=\"button\"\n class=\"c8y-right-drawer__link\"\n [href]=\"quickLink.url || '#'\"\n (click)=\"quickLink.click && $event.preventDefault(); quickLink.click && quickLink.click()\"\n c8yProductExperience\n [actionName]=\"PRODUCT_EXPERIENCE.QUICK_LINKS.EVENTS.QUICK_LINK_RIGHT_DRAWER\"\n [actionData]=\"{\n component: PRODUCT_EXPERIENCE.QUICK_LINKS.COMPONENTS.RIGHT_DRAWER_COMPONENT,\n action: quickLink.label\n }\"\n tabindex=\"{{ drawerOpen ? '0' : '-1' }}\"\n >\n <i *ngIf=\"quickLink.icon\" class=\"{{ quickLink.icon }} c8y-icon-duocolor\"></i>\n <img\n *ngIf=\"quickLink.iconSrc\"\n [src]=\"quickLink.iconSrc\"\n style=\"max-width: 20px\"\n class=\"img-responsive\"\n onerror=\"this.style.display = 'none'\"\n />\n <span>{{ quickLink.label | translate }}</span>\n </a>\n </ng-container>\n\n </div>\n\n <div *ngIf=\"(appState$ | async).showRightDrawer && helpAndSupport.length\"\n class=\"separator-top p-t-8 p-b-8\">\n <button type=\"button\" class=\"c8y-right-drawer__link sticky-top\" (click)=\"documentationOpen = !documentationOpen\"\n [attr.aria-expanded]=\"!documentationCol.isCollapsed\" [attr.aria-controls]=\"'collapseDocs'\">\n <i c8yIcon=\"book-shelf\"></i>\n <span class=\"text-bold\">{{ 'Documentation' | translate }}</span>\n <i c8yIcon=\"angle-down\" class=\"m-l-auto\" [ngClass]=\"{'icon-rotate-180': documentationOpen }\"></i>\n </button>\n <div class=\"collapse\" id=\"collapseDocs\" [collapse]=\"!documentationOpen\" [isAnimated]=\"true\" #documentationCol=\"bs-collapse\">\n <ng-container *ngFor=\"let link of helpAndSupport\">\n <ng-container *ngIf=\"link.component\">\n <ng-container *ngComponentOutlet=\"link.component; injector: link.injector\"></ng-container>\n </ng-container>\n <a\n *ngIf=\"!link.component\"\n title=\"{{ link.label | translate }}\"\n type=\"button\"\n class=\"c8y-right-drawer__link\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n [href]=\"link.url\"\n c8yProductExperience\n [actionName]=\"PRODUCT_EXPERIENCE.QUICK_LINKS.EVENTS.QUICK_LINK_RIGHT_DRAWER\"\n [actionData]=\"{\n component: PRODUCT_EXPERIENCE.QUICK_LINKS.COMPONENTS.RIGHT_DRAWER_COMPONENT,\n action: link.label\n }\"\n tabindex=\"{{ drawerOpen ? '0' : '-1' }}\"\n >\n <span title=\"{{ link.label | translate }}\" class=\"text-truncate text-12\">\n {{ link.label | translate }}\n </span>\n </a>\n </ng-container>\n </div>\n </div>\n\n <!-- TODO: move legal notices here -->\n <!-- <div class=\"separator-top p-t-8 m-t-auto\">\n <a href=\"#\" class=\"c8y-right-drawer__link\">\n <small>Legal notices</small>\n </a>\n </div> -->\n</aside>\n" }]
|
|
13466
13759
|
}], ctorParameters: function () { return [{ type: AppStateService }, { type: UserMenuService }, { type: OptionsService }]; }, propDecorators: { _quickLinks: [{
|
|
13467
13760
|
type: Input,
|
|
13468
13761
|
args: ['quickLinks']
|
|
@@ -16576,50 +16869,68 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
|
|
|
16576
16869
|
/**
|
|
16577
16870
|
* This module enables an tenant to activate the product experience
|
|
16578
16871
|
* software [Gainsight](https://www.gainsight.com/product-experience/) to help
|
|
16579
|
-
* and track user actions.
|
|
16580
|
-
* property `gainsightEnabled` is set to true.
|
|
16872
|
+
* and track user actions.
|
|
16581
16873
|
*/
|
|
16582
16874
|
class ProductExperienceModule {
|
|
16583
|
-
constructor(appState, gainsightService, cookieBannerService,
|
|
16875
|
+
constructor(appState, gainsightService, cookieBannerService,
|
|
16876
|
+
// Don't remove it, otherwise UserEngagementsService won't be initialized.
|
|
16877
|
+
userEngagementsService) {
|
|
16584
16878
|
this.appState = appState;
|
|
16585
16879
|
this.gainsightService = gainsightService;
|
|
16586
16880
|
this.cookieBannerService = cookieBannerService;
|
|
16587
|
-
this.
|
|
16881
|
+
this.userEngagementsService = userEngagementsService;
|
|
16882
|
+
/**
|
|
16883
|
+
* Check if the Gainsight tracking is disabled in the application apptions. If so, exit early without processing further.
|
|
16884
|
+
*/
|
|
16885
|
+
if (this.gainsightService.isTrackingDisabled()) {
|
|
16886
|
+
return;
|
|
16887
|
+
}
|
|
16888
|
+
this.toggleUserTrackingObservable();
|
|
16889
|
+
}
|
|
16890
|
+
/**
|
|
16891
|
+
* Observes several factors to determine the state of user tracking and manages the visibility of Gainsight engagements.
|
|
16892
|
+
* It watches for changes in the current tenant, the state of the cookie banner, and user's preferences for Gainsight engagements.
|
|
16893
|
+
*
|
|
16894
|
+
* 1. If the cookie banner is being displayed, it returns without making any changes.
|
|
16895
|
+
* 2. If Gainsight is disabled at the tenant level via custom properties, it returns without making any changes.
|
|
16896
|
+
* 3. If the conditions are met for loading the Gainsight tag, it loads the tag.
|
|
16897
|
+
*/
|
|
16898
|
+
toggleUserTrackingObservable() {
|
|
16588
16899
|
combineLatest([
|
|
16589
16900
|
this.appState.currentTenant.pipe(filter(Boolean)),
|
|
16590
|
-
this.cookieBannerService.isCookieBannerShowed
|
|
16591
|
-
|
|
16592
|
-
]).subscribe(async ([currentTenant, isCookieBannerShowed, showGainsightEngagements]) => {
|
|
16901
|
+
this.cookieBannerService.isCookieBannerShowed$
|
|
16902
|
+
]).subscribe(async ([currentTenant, isCookieBannerShowed]) => {
|
|
16593
16903
|
if (isCookieBannerShowed) {
|
|
16594
16904
|
return;
|
|
16595
16905
|
}
|
|
16596
16906
|
const { customProperties } = currentTenant;
|
|
16597
|
-
if (this.gainsightService.
|
|
16598
|
-
|
|
16599
|
-
this.gainsightService.loadTag(currentTenant);
|
|
16907
|
+
if (this.gainsightService.isGainsightDisabledAtTenantCustomProperties(customProperties)) {
|
|
16908
|
+
return;
|
|
16600
16909
|
}
|
|
16601
|
-
|
|
16602
|
-
|
|
16603
|
-
*/
|
|
16604
|
-
if (showGainsightEngagements === undefined) {
|
|
16605
|
-
showGainsightEngagements = true;
|
|
16606
|
-
userPreferencesService.set(this.gainsightService.USER_PREFERENCES_GAINSIGHT_ENGAGEMENTS_KEY, showGainsightEngagements);
|
|
16910
|
+
if (this.shouldLoadTag()) {
|
|
16911
|
+
await this.gainsightService.loadTag(currentTenant, await this.gainsightService.shouldSendPiiData());
|
|
16607
16912
|
}
|
|
16608
|
-
this.gainsightService.switchGainsightEngagementsVisibility(showGainsightEngagements);
|
|
16609
16913
|
});
|
|
16610
16914
|
}
|
|
16915
|
+
/**
|
|
16916
|
+
* Determines if a tracking tag should be loaded based on cookie preferences.
|
|
16917
|
+
* @returns `true` if user cookie preferences exist, otherwise `false`.
|
|
16918
|
+
*/
|
|
16919
|
+
shouldLoadTag() {
|
|
16920
|
+
return !!this.cookieBannerService.getUserCookiePreferences();
|
|
16921
|
+
}
|
|
16611
16922
|
}
|
|
16612
|
-
ProductExperienceModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ProductExperienceModule, deps: [{ token: AppStateService }, { token: GainsightService }, { token: CookieBannerService }, { token:
|
|
16923
|
+
ProductExperienceModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ProductExperienceModule, deps: [{ token: AppStateService }, { token: GainsightService }, { token: CookieBannerService }, { token: UserEngagementsService }], target: i0.ɵɵFactoryTarget.NgModule });
|
|
16613
16924
|
ProductExperienceModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.6", ngImport: i0, type: ProductExperienceModule, declarations: [ProductExperienceDirective], exports: [ProductExperienceDirective] });
|
|
16614
|
-
ProductExperienceModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ProductExperienceModule, providers: [GainsightService] });
|
|
16925
|
+
ProductExperienceModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ProductExperienceModule, providers: [GainsightService, UserEngagementsService] });
|
|
16615
16926
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ProductExperienceModule, decorators: [{
|
|
16616
16927
|
type: NgModule,
|
|
16617
16928
|
args: [{
|
|
16618
16929
|
declarations: [ProductExperienceDirective],
|
|
16619
16930
|
exports: [ProductExperienceDirective],
|
|
16620
|
-
providers: [GainsightService]
|
|
16931
|
+
providers: [GainsightService, UserEngagementsService]
|
|
16621
16932
|
}]
|
|
16622
|
-
}], ctorParameters: function () { return [{ type: AppStateService }, { type: GainsightService }, { type: CookieBannerService }, { type:
|
|
16933
|
+
}], ctorParameters: function () { return [{ type: AppStateService }, { type: GainsightService }, { type: CookieBannerService }, { type: UserEngagementsService }]; } });
|
|
16623
16934
|
|
|
16624
16935
|
class SearchComponent {
|
|
16625
16936
|
constructor(searchService) {
|
|
@@ -27461,5 +27772,5 @@ class RealtimeMessage {
|
|
|
27461
27772
|
* Generated bundle index. Do not edit.
|
|
27462
27773
|
*/
|
|
27463
27774
|
|
|
27464
|
-
export { ACTIONS, AbstractConfigurationStrategy, ActionBarComponent, ActionBarItemComponent, ActionBarModule, ActionBarService, ActionComponent, ActionModule, ActionOutletComponent, ActionService, AlarmRealtimeService, AlertComponent, AlertDetailsComponent, AlertModule, AlertOutletBase, AlertOutletComponent, AlertService, AlertTextComponent, AppIconComponent, AppStateService, AppSwitcherComponent, AppSwitcherService, ApplicationOptions, ApplicationPluginStatus, AssetTypesModule, AssetTypesService, AuditLogComponent, AuditLogModule, AuthenticationModule, BackendVersionFactory, BaseColumn, BaseFilteringFormRendererComponent, BootstrapComponent, BootstrapModule, BreadcrumbComponent, BreadcrumbItemComponent, BreadcrumbModule, BreadcrumbOutletComponent, BreadcrumbService, BytesPipe, C8yJSONSchema, C8yStepper, C8yStepperButtons, C8yStepperIcon, C8yStepperProgress, C8yTranslateDirective, C8yTranslateModule, C8yTranslatePipe, C8yValidators, CachedLocaleDictionaryService, CellRendererComponent, CellRendererContext, CellRendererDefDirective, ChangePasswordComponent, ClipboardModule, ClipboardService, ColorService, ColumnDirective, CommonModule, ConditionalTabsOutletComponent, ConfigureCustomColumnComponent, ConfirmModalComponent, ContextRouteComponent, ContextRouteGuard, ContextRouteService, CookieBannerComponent, CoreModule, CredentialsComponent, CurrentPasswordModalComponent, CustomColumn, DATA_GRID_CONFIGURATION_CONTEXT, DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER, DATA_GRID_CONFIGURATION_STRATEGY, DashboardChildActionComponent, DashboardChildChange, DashboardChildComponent, DashboardChildTitleComponent, DashboardComponent, DashboardModule, DataGridComponent, DataGridModule, DataGridService, DatapointLibraryValidationErrors, DatePickerComponent, DatePickerModule, DatePipe, DateTimePickerComponent, DateTimePickerModule, DefaultValidationDirective, DeviceBootstrapRealtimeService, DeviceService, DeviceStatusComponent, DeviceStatusModule, DismissAlertStrategy, DocsModule, DocsService, DropAreaComponent, DropAreaModule, DropdownDirectionDirective, DynamicBulkDetailsResolver, DynamicBulkIIdentifiedResolver, DynamicComponentAlert, DynamicComponentAlertAggregator, DynamicComponentComponent, DynamicComponentErrorStrategy, DynamicComponentModule, DynamicComponentService, DynamicDatapointsResolver, DynamicFormsModule, DynamicManagedObjectResolver, DynamicResolverService, ES_MAX_TIME_MILLISECONDS, EmailsValidatorDirective, EmptyComponent, EmptyStateComponent, EventRealtimeService, FilePickerComponent, FilePickerModule, FilesService, FilterInputComponent, FilteringActionType, FilteringFormRendererComponent, FilteringFormRendererContext, FilteringFormRendererDefDirective, ForOfDirective, FormGroupComponent, FormsModule, GENERIC_FILE_TYPE, GainsightService, GetGroupIconPipe, GridDataSource, GroupFragment, GroupService, GuideDocsComponent, GuideHrefDirective, HOOK_ACTION, HOOK_ACTION_BAR, HOOK_BREADCRUMB, HOOK_COMPONENTS, HOOK_DOCS, HOOK_DYNAMIC_PROVIDER_CONFIG, HOOK_NAVIGATOR_NODES, HOOK_OPTIONS, HOOK_PATTERN_MESSAGES, HOOK_ROUTE, HOOK_SEARCH, HOOK_STEPPER, HOOK_TABS, HOOK_VERSION, HOOK_WIZARD, HeaderBarComponent, HeaderCellRendererDefDirective, HeaderModule, HeaderService, HelpComponent, HelpModule, HighlightComponent, HookProviderTypes, HumanizeAppNamePipe, HumanizePipe, I18nModule$1 as I18nModule, ICONS, ICON_LIST, IconDirective, IfAllowedDirective, InjectionType, InputGroupListComponent, InputGroupListContainerDirective, InventorySearchService, IpRangeInputListComponent, IsControlVisiblePipe, JsonValidationPrettifierDirective, LANGUAGES, LOCALE_PATH, LegacyGridConfigMapperService, ListDisplaySwitchComponent, ListDisplaySwitchModule, ListGroupComponent, ListGroupModule, ListItemActionComponent, ListItemBodyComponent, ListItemCheckboxComponent, ListItemCollapseComponent, ListItemComponent, ListItemDragHandleComponent, ListItemFooterComponent, ListItemIconComponent, ListItemRadioComponent, ListItemTimelineComponent, LoadMoreComponent, LoadingComponent, LoginComponent, LoginModule, LoginService, LoginViews, MAX_PAGE_SIZE, MESSAGES, ManagedObjectRealtimeService, ManagedObjectType, MapFunctionPipe, MarkdownToHtmlPipe, MaxValidationDirective, MeasurementRealtimeService, MessageDirective, MessagesComponent, MinValidationDirective, MissingTranslationCustomHandler, ModalComponent, ModalModule, ModalSelectionMode, ModalService, NEEDED_ROLE_FOR_SETUP, NUMBER_FORMAT_REGEXP, NavigatorIconComponent, NavigatorModule, NavigatorNode, NavigatorNodeComponent, NavigatorNodeRoot, NavigatorOutletComponent, NavigatorService, NewPasswordComponent, NumberPipe, OperationBulkRealtimeService, OperationRealtimeService, OperationResultComponent, OptionsService, OutletDirective, PRODUCT_EXPERIENCE_EVENT_SOURCE, PX_ACTIONS, PX_EVENT_NAME, PasswordCheckListComponent, PasswordConfirm, PasswordConfirmModalComponent, PasswordService, PasswordStrengthCheckerService, PasswordStrengthComponent, PasswordStrengthValidatorDirective, PatternMessagesService, Permissions, PhoneValidationDirective, PlatformDetailsService, PluginsModule, PluginsResolveService, PluginsService, PopoverConfirmComponent, ProductExperienceDirective, ProductExperienceModule, ProgressBarComponent, PropertiesListComponent, PropertiesListModule, ProvidePhoneNumberComponent, ProviderConfigurationComponent, ProviderConfigurationModule, ProviderConfigurationNodeFactory, ProviderConfigurationRouteFactory, ProviderConfigurationService, ProviderDefinitionsService, PushStatus, PushStatusLabels, QuickLinkComponent, QuickLinkModule, RESOLVING_COMPONENT_WAIT_TIME, RangeComponent, RangeDirective, RangeDisplayComponent, RangeDisplayModule, RealtimeButtonComponent, RealtimeMessage, RealtimeModule, RealtimeService, RealtimeSubjectService, RecoverPasswordComponent, RequiredInputPlaceholderDirective, RightDrawerComponent, RouterModule, RouterService, RouterTabsResolver, SETUP_FINISHED_STEP_ID, SearchComponent, SearchFilters, SearchInputComponent, SearchModule, SearchOutletComponent, SearchResultEmptyComponent, SearchService, SelectComponent$1 as SelectComponent, SelectModalComponent, SelectModalFilterPipe, SelectModalModule, SelectModule, SendStatus, SendStatusLabels, SetupCompletedComponent, SetupComponent, SetupModule, SetupService, SetupState, SetupStepperFactory, ShortenUserNamePipe, ShouldShowMoPipe, ShowIfFilterPipe, SimpleJsonPathValidatorDirective, SkipLinkDirective, SmsChallengeComponent, StateService, Status, StepperModule, StepperOutletComponent, StepperService, Steppers, StrengthValidatorService, StringifyObjectPipe, TabComponent, TabsModule, TabsOutletComponent, TabsService, TabsetAriaDirective, TenantUiService, TextAreaRowHeightDirective, TextareaAutoresizeDirective, TitleComponent, TitleOutletComponent, TotpAuthComponent, TotpChallengeComponent, TotpSetupComponent, TranslateCustomLoader, TranslateParserCustom, TranslateService, TypeaheadComponent, UniqueInCollectionByPathValidationDirective, UserEditComponent, UserEditModalComponent, UserMenuItemComponent, UserMenuOutletComponent, UserMenuService, UserModule, UserNameInitialsPipe, UserPreferencesConfigurationStrategy, UserPreferencesService, UserPreferencesStorageInventory, UserPreferencesStorageLocal, UserTotpRevokeComponent, UserTotpSetupComponent, VERSION_MODULE_CONFIG, ValidationPattern, VersionDetailsModalComponent, VersionListComponent, VersionModule, VersionService, ViewContext, ViewContextServices, VirtualScrollWindowDirective, VirtualScrollWindowStrategy, VirtualScrollerWrapperComponent, WebSDKVersionFactory, WidgetTimeContextComponent, WidgetsDashboardComponent, WizardBodyComponent, WizardComponent, WizardFooterComponent, WizardHeaderComponent, WizardModalService, WizardModule, WizardOutletComponent, WizardService, ZipService, _, _virtualScrollWindowStrategyFactory, allEntriesAreEqual, deviceAvailabilityIconMap, extraRoutes, fromFactories, fromTrigger, fromTriggerOnce, getActivatedRoute, getAngularLocalesLanguageString, getBasicInputArrayFormFieldConfig, getInjectedHooks, gettext, hookAction, hookActionBar, hookBreadcrumb, hookComponent, hookDocs, hookDynamicProviderConfig, hookGeneric, hookNavigator, hookOptions, hookPatternMessages, hookRoute, hookSearch, hookStepper, hookTab, hookVersion, hookWizard, initializeServices, isEagerDynamicComponents, isExtensionFactory, isLazyDynamicComponents, isPromise, languagesFactory, loadLocale, localeId, localePathFactory, memoize, minColumnGridTrackSize, operationStatusClasses, operationStatusIcons, ratiosByColumnTypes, resolveInjectedFactories, retryWithDelay, simpleJsonPathValidator, sortByPriority, stateToFactory, statusAlert, statusClasses, statusIcons, throttle, toObservable, toObservableOfArrays, tooltips, translateLoaderFactory, trimTranslationKey, uniqueInCollectionByPathValidator };
|
|
27775
|
+
export { ACTIONS, AbstractConfigurationStrategy, ActionBarComponent, ActionBarItemComponent, ActionBarModule, ActionBarService, ActionComponent, ActionModule, ActionOutletComponent, ActionService, AlarmRealtimeService, AlertComponent, AlertDetailsComponent, AlertModule, AlertOutletBase, AlertOutletComponent, AlertService, AlertTextComponent, AppIconComponent, AppStateService, AppSwitcherComponent, AppSwitcherService, ApplicationOptions, ApplicationPluginStatus, AssetTypesModule, AssetTypesService, AuditLogComponent, AuditLogModule, AuthenticationModule, BackendVersionFactory, BaseColumn, BaseFilteringFormRendererComponent, BootstrapComponent, BootstrapModule, BreadcrumbComponent, BreadcrumbItemComponent, BreadcrumbModule, BreadcrumbOutletComponent, BreadcrumbService, BytesPipe, C8yJSONSchema, C8yStepper, C8yStepperButtons, C8yStepperIcon, C8yStepperProgress, C8yTranslateDirective, C8yTranslateModule, C8yTranslatePipe, C8yValidators, CachedLocaleDictionaryService, CellRendererComponent, CellRendererContext, CellRendererDefDirective, ChangePasswordComponent, ClipboardModule, ClipboardService, ColorService, ColumnDirective, CommonModule, ConditionalTabsOutletComponent, ConfigureCustomColumnComponent, ConfirmModalComponent, ContextRouteComponent, ContextRouteGuard, ContextRouteService, CookieBannerComponent, CoreModule, CredentialsComponent, CurrentPasswordModalComponent, CustomColumn, DATA_GRID_CONFIGURATION_CONTEXT, DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER, DATA_GRID_CONFIGURATION_STRATEGY, DashboardChildActionComponent, DashboardChildChange, DashboardChildComponent, DashboardChildTitleComponent, DashboardComponent, DashboardModule, DataGridComponent, DataGridModule, DataGridService, DatapointLibraryValidationErrors, DatePickerComponent, DatePickerModule, DatePipe, DateTimePickerComponent, DateTimePickerModule, DefaultValidationDirective, DeviceBootstrapRealtimeService, DeviceService, DeviceStatusComponent, DeviceStatusModule, DismissAlertStrategy, DocsModule, DocsService, DropAreaComponent, DropAreaModule, DropdownDirectionDirective, DynamicBulkDetailsResolver, DynamicBulkIIdentifiedResolver, DynamicComponentAlert, DynamicComponentAlertAggregator, DynamicComponentComponent, DynamicComponentErrorStrategy, DynamicComponentModule, DynamicComponentService, DynamicDatapointsResolver, DynamicFormsModule, DynamicManagedObjectResolver, DynamicResolverService, ES_MAX_TIME_MILLISECONDS, EmailsValidatorDirective, EmptyComponent, EmptyStateComponent, EventRealtimeService, FilePickerComponent, FilePickerModule, FilesService, FilterInputComponent, FilteringActionType, FilteringFormRendererComponent, FilteringFormRendererContext, FilteringFormRendererDefDirective, ForOfDirective, FormGroupComponent, FormsModule, GENERIC_FILE_TYPE, GainsightService, GetGroupIconPipe, GridDataSource, GroupFragment, GroupService, GuideDocsComponent, GuideHrefDirective, HOOK_ACTION, HOOK_ACTION_BAR, HOOK_BREADCRUMB, HOOK_COMPONENTS, HOOK_DOCS, HOOK_DYNAMIC_PROVIDER_CONFIG, HOOK_NAVIGATOR_NODES, HOOK_OPTIONS, HOOK_PATTERN_MESSAGES, HOOK_ROUTE, HOOK_SEARCH, HOOK_STEPPER, HOOK_TABS, HOOK_VERSION, HOOK_WIZARD, HeaderBarComponent, HeaderCellRendererDefDirective, HeaderModule, HeaderService, HelpComponent, HelpModule, HighlightComponent, HookProviderTypes, HumanizeAppNamePipe, HumanizePipe, I18nModule$1 as I18nModule, ICONS, ICON_LIST, IconDirective, IfAllowedDirective, InjectionType, InputGroupListComponent, InputGroupListContainerDirective, InventorySearchService, IpRangeInputListComponent, IsControlVisiblePipe, JsonValidationPrettifierDirective, LANGUAGES, LOCALE_PATH, LegacyGridConfigMapperService, ListDisplaySwitchComponent, ListDisplaySwitchModule, ListGroupComponent, ListGroupModule, ListItemActionComponent, ListItemBodyComponent, ListItemCheckboxComponent, ListItemCollapseComponent, ListItemComponent, ListItemDragHandleComponent, ListItemFooterComponent, ListItemIconComponent, ListItemRadioComponent, ListItemTimelineComponent, LoadMoreComponent, LoadingComponent, LoginComponent, LoginModule, LoginService, LoginViews, MAX_PAGE_SIZE, MESSAGES, ManagedObjectRealtimeService, ManagedObjectType, MapFunctionPipe, MarkdownToHtmlPipe, MaxValidationDirective, MeasurementRealtimeService, MessageDirective, MessagesComponent, MinValidationDirective, MissingTranslationCustomHandler, ModalComponent, ModalModule, ModalSelectionMode, ModalService, NEEDED_ROLE_FOR_SETUP, NUMBER_FORMAT_REGEXP, NavigatorIconComponent, NavigatorModule, NavigatorNode, NavigatorNodeComponent, NavigatorNodeRoot, NavigatorOutletComponent, NavigatorService, NewPasswordComponent, NumberPipe, OperationBulkRealtimeService, OperationRealtimeService, OperationResultComponent, OptionsService, OutletDirective, PRODUCT_EXPERIENCE_EVENT_SOURCE, PX_ACTIONS, PX_EVENT_NAME, PasswordCheckListComponent, PasswordConfirm, PasswordConfirmModalComponent, PasswordService, PasswordStrengthCheckerService, PasswordStrengthComponent, PasswordStrengthValidatorDirective, PatternMessagesService, Permissions, PhoneValidationDirective, PlatformDetailsService, PluginsModule, PluginsResolveService, PluginsService, PopoverConfirmComponent, ProductExperienceDirective, ProductExperienceModule, ProgressBarComponent, PropertiesListComponent, PropertiesListModule, ProvidePhoneNumberComponent, ProviderConfigurationComponent, ProviderConfigurationModule, ProviderConfigurationNodeFactory, ProviderConfigurationRouteFactory, ProviderConfigurationService, ProviderDefinitionsService, PushStatus, PushStatusLabels, QuickLinkComponent, QuickLinkModule, RESOLVING_COMPONENT_WAIT_TIME, RangeComponent, RangeDirective, RangeDisplayComponent, RangeDisplayModule, RealtimeButtonComponent, RealtimeMessage, RealtimeModule, RealtimeService, RealtimeSubjectService, RecoverPasswordComponent, RequiredInputPlaceholderDirective, RightDrawerComponent, RouterModule, RouterService, RouterTabsResolver, SETUP_FINISHED_STEP_ID, SearchComponent, SearchFilters, SearchInputComponent, SearchModule, SearchOutletComponent, SearchResultEmptyComponent, SearchService, SelectComponent$1 as SelectComponent, SelectModalComponent, SelectModalFilterPipe, SelectModalModule, SelectModule, SendStatus, SendStatusLabels, SetupCompletedComponent, SetupComponent, SetupModule, SetupService, SetupState, SetupStepperFactory, ShortenUserNamePipe, ShouldShowMoPipe, ShowIfFilterPipe, SimpleJsonPathValidatorDirective, SkipLinkDirective, SmsChallengeComponent, StateService, Status, StepperModule, StepperOutletComponent, StepperService, Steppers, StrengthValidatorService, StringifyObjectPipe, TabComponent, TabsModule, TabsOutletComponent, TabsService, TabsetAriaDirective, TenantUiService, TextAreaRowHeightDirective, TextareaAutoresizeDirective, TitleComponent, TitleOutletComponent, TotpAuthComponent, TotpChallengeComponent, TotpSetupComponent, TranslateCustomLoader, TranslateParserCustom, TranslateService, TypeaheadComponent, UniqueInCollectionByPathValidationDirective, UserEditComponent, UserEditModalComponent, UserEngagementsService, UserMenuItemComponent, UserMenuOutletComponent, UserMenuService, UserModule, UserNameInitialsPipe, UserPreferencesConfigurationStrategy, UserPreferencesService, UserPreferencesStorageInventory, UserPreferencesStorageLocal, UserTotpRevokeComponent, UserTotpSetupComponent, VERSION_MODULE_CONFIG, ValidationPattern, VersionDetailsModalComponent, VersionListComponent, VersionModule, VersionService, ViewContext, ViewContextServices, VirtualScrollWindowDirective, VirtualScrollWindowStrategy, VirtualScrollerWrapperComponent, WebSDKVersionFactory, WidgetTimeContextComponent, WidgetsDashboardComponent, WizardBodyComponent, WizardComponent, WizardFooterComponent, WizardHeaderComponent, WizardModalService, WizardModule, WizardOutletComponent, WizardService, ZipService, _, _virtualScrollWindowStrategyFactory, allEntriesAreEqual, deviceAvailabilityIconMap, extraRoutes, fromFactories, fromTrigger, fromTriggerOnce, getActivatedRoute, getAngularLocalesLanguageString, getBasicInputArrayFormFieldConfig, getInjectedHooks, gettext, hookAction, hookActionBar, hookBreadcrumb, hookComponent, hookDocs, hookDynamicProviderConfig, hookGeneric, hookNavigator, hookOptions, hookPatternMessages, hookRoute, hookSearch, hookStepper, hookTab, hookVersion, hookWizard, initializeServices, isEagerDynamicComponents, isExtensionFactory, isLazyDynamicComponents, isPromise, languagesFactory, loadLocale, localeId, localePathFactory, memoize, minColumnGridTrackSize, operationStatusClasses, operationStatusIcons, ratiosByColumnTypes, resolveInjectedFactories, retryWithDelay, simpleJsonPathValidator, sortByPriority, stateToFactory, statusAlert, statusClasses, statusIcons, throttle, toObservable, toObservableOfArrays, tooltips, translateLoaderFactory, trimTranslationKey, uniqueInCollectionByPathValidator };
|
|
27465
27776
|
//# sourceMappingURL=c8y-ngx-components.mjs.map
|