@c8y/ng1-modules 1023.90.1 → 1023.92.0

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.
@@ -3130,6 +3130,9 @@ msgstr "居中"
3130
3130
  msgid "Certificate"
3131
3131
  msgstr "证书"
3132
3132
 
3133
+ msgid "Certificate (PEM)"
3134
+ msgstr "证书 (PEM)"
3135
+
3133
3136
  msgid "Certificate ID field"
3134
3137
  msgstr "证书 ID 字段"
3135
3138
 
@@ -4900,6 +4903,12 @@ msgstr "当前"
4900
4903
  msgid "Currently installed"
4901
4904
  msgstr "当前已安装"
4902
4905
 
4906
+ msgid "Currently saved certificate"
4907
+ msgstr "当前已保存的证书"
4908
+
4909
+ msgid "Currently saved private key"
4910
+ msgstr "当前已保存的私钥"
4911
+
4903
4912
  msgid "Custom"
4904
4913
  msgstr "自定义"
4905
4914
 
@@ -6496,6 +6505,12 @@ msgstr "在表格单元格周围绘制边框"
6496
6505
  msgid "Drop"
6497
6506
  msgstr "放置"
6498
6507
 
6508
+ msgid "Drop a new certificate to replace"
6509
+ msgstr "发布一份新证书以替换"
6510
+
6511
+ msgid "Drop a new private key to replace"
6512
+ msgstr "放置一个新的私钥以替换"
6513
+
6499
6514
  msgid "Drop file here"
6500
6515
  msgstr "将文件放在此处"
6501
6516
 
@@ -6508,6 +6523,12 @@ msgstr "将文件放在此处"
6508
6523
  msgid "Drop files here or click to browse"
6509
6524
  msgstr "将文件放置在此处或单击以浏览"
6510
6525
 
6526
+ msgid "Drop the certificate in PEM format."
6527
+ msgstr "请上传 PEM 格式的证书。"
6528
+
6529
+ msgid "Drop the private key in PEM format."
6530
+ msgstr "请提供 PEM 格式的私钥。"
6531
+
6511
6532
  msgid "Due to the large number, only a subset of alarms are displayed. Use search to narrow down the number of results."
6512
6533
  msgstr "由于数量众多,仅显示警报的子集。请使用搜索缩小结果数量。"
6513
6534
 
@@ -6784,6 +6805,9 @@ msgstr "启用深色主题支持"
6784
6805
  msgid "Enable in-product information & communication"
6785
6806
  msgstr "启用产品中信息和通信"
6786
6807
 
6808
+ msgid "Enable mTLS authentication"
6809
+ msgstr "启用 mTLS 身份验证"
6810
+
6787
6811
  msgid "Enable message banner"
6788
6812
  msgstr "启用消息横幅"
6789
6813
 
@@ -8031,11 +8055,11 @@ msgstr "若要连接模拟设备,请在已安装\n"
8031
8055
  " <a href=\"https://github.com/thin-edge/tedge-demo-container\" target=\"_blank\" rel=\"noopener noreferrer\"> tedge-demo-container</a>。"
8032
8056
 
8033
8057
  msgid "For correct application behavior you can use only \"{{ host }}\" or \"{{\n"
8034
- " defaultRedirectUrl\n"
8035
- " }}\", the latter one is recommended."
8036
- msgstr "要获得正确的应用程序行为,您只能使用 \"{{ host }}\" 或 \"{{\n"
8037
- " defaultRedirectUrl\n"
8038
- " }}\",建议使用后者。"
8058
+ " defaultRedirectUrl\n"
8059
+ " }}\", the latter one is recommended."
8060
+ msgstr "为了确保应用程序正常运行,您只能使用“{{ host }}”或“{{\n"
8061
+ " defaultRedirectUrl\n"
8062
+ " }}”,建议使用后者。"
8039
8063
 
8040
8064
  msgid "For details refer to the\n"
8041
8065
  " <a c8y-guide-href=\"/docs/standard-tenant/standard-tenant-introduction\">\n"
@@ -10301,11 +10325,21 @@ msgstr "主要警报"
10301
10325
  msgid "Major`alarm`"
10302
10326
  msgstr "主要"
10303
10327
 
10304
- msgid "Make sure that \"Valid Redirect URIs\" in the authorization server is set to \"{{ redirectURI }}\" or to the full URIs of the used applications if the authorization server does not support patterns."
10305
- msgstr "确保授权服务器中的 \"有效重定向 URI \"设置为 \"{{ redirectURI }}\",如果授权服务器不支持模式,则设置为所用应用程序的完整 URI。"
10306
-
10307
- msgid "Make sure that \"Valid Redirect URIs\" in the authorization server is set to \"{{ redirectURI }}\"."
10308
- msgstr "确保授权服务器中的 \"有效重定向 URI \"设置为 \"{{ redirectURI }}\"。"
10328
+ msgid "Make sure that \"Valid Redirect URIs\" in the authorization server is set to \"{{\n"
10329
+ " redirectURI\n"
10330
+ " }}\" or to the full URIs of the used applications if the authorization server\n"
10331
+ " does not support patterns."
10332
+ msgstr "请确保授权服务器中的“有效重定向 URI”设置为“{{\n"
10333
+ " redirectURI\n"
10334
+ " }}”,或者如果授权服务器\n"
10335
+ " 不支持模式,则设置为使用应用程序的完整 URI。"
10336
+
10337
+ msgid "Make sure that \"Valid Redirect URIs\" in the authorization server is set to \"{{\n"
10338
+ " redirectURI\n"
10339
+ " }}\"."
10340
+ msgstr "请确保授权服务器中的“有效重定向 URI”设置为“{{\n"
10341
+ " redirectURI\n"
10342
+ " }}”。"
10309
10343
 
10310
10344
  msgid "Make sure that:"
10311
10345
  msgstr "确保:"
@@ -13101,9 +13135,15 @@ msgstr "面板的打印屏幕"
13101
13135
  msgid "Private key"
13102
13136
  msgstr "私钥"
13103
13137
 
13138
+ msgid "Private key (PEM)"
13139
+ msgstr "私钥(PEM)"
13140
+
13104
13141
  msgid "Private key cipher does not match"
13105
13142
  msgstr "私钥密码不匹配"
13106
13143
 
13144
+ msgid "Private key matching the client certificate, in PEM format (PKCS#8). The platform encrypts the key at rest after the first save and will return only an encrypted value on subsequent loads. Accepted file extensions: .pem, .key."
13145
+ msgstr "与客户端证书匹配的私钥,格式为PEM(PKCS#8)。平台会在首次保存后对静止状态下的密钥进行加密,后续加载时仅返回加密后的值。支持的文件扩展名:.pem、.key。"
13146
+
13107
13147
  msgid "Private key must be provided when \"Public/private keys\" option is selected."
13108
13148
  msgstr "选择 \"公钥/私钥\" 选项时,必须提供私钥。"
13109
13149
 
@@ -13242,6 +13282,9 @@ msgstr "预置证书"
13242
13282
  msgid "Provisioned certificates removed from user object: \"{{ userName }}\""
13243
13283
  msgstr "已从用户对象中移除预配置证书:\"{{ userName }}\""
13244
13284
 
13285
+ msgid "Public X.509 client certificate in PEM format, issued for this tenant by a CA trusted by your authorization server. Accepted file extension: .pem."
13286
+ msgstr "由您的授权服务器信任的证书颁发机构(CA)为此租户签发的、采用 PEM 格式的公共 X.509 客户端证书。接受的文件扩展名:.pem。"
13287
+
13245
13288
  msgid "Public key"
13246
13289
  msgstr "公钥"
13247
13290
 
@@ -17413,6 +17456,12 @@ msgstr "预览显示了来自单一来源的原始文件的结构。"
17413
17456
  msgid "The preview shows the structure of the raw file from all sources."
17414
17457
  msgstr "预览显示了全部来源的原始文件的结构。"
17415
17458
 
17459
+ msgid "The private key is encrypted for security reasons."
17460
+ msgstr "出于安全考虑,私钥已被加密。"
17461
+
17462
+ msgid "The private key will be encrypted on the server after saving."
17463
+ msgstr "私钥在保存后将在服务器上进行加密。"
17464
+
17416
17465
  msgid "The provided name is already taken."
17417
17466
  msgstr "提供的名称已被使用。"
17418
17467
 
@@ -18745,6 +18794,9 @@ msgstr "使用 * 以允许任意值。"
18745
18794
  msgid "Use [Enter] or <br> tag to add a new line"
18746
18795
  msgstr "使用 [Enter] 或 <br> 标签添加新行"
18747
18796
 
18797
+ msgid "Use a client certificate (mTLS) instead of a client secret to authenticate the platform with the authorization server. Use this option only if the authorization server enforces certificate-based client authentication."
18798
+ msgstr "使用客户端证书(mTLS)代替客户端密码,向授权服务器验证平台身份。仅当授权服务器强制要求基于证书的客户端身份验证时,才应使用此选项。"
18799
+
18748
18800
  msgid "Use alarms to create smart rules for microservice availability."
18749
18801
  msgstr "使用警报为微服务可用性创建智能规则。"
18750
18802
 
@@ -3130,6 +3130,9 @@ msgstr "居中"
3130
3130
  msgid "Certificate"
3131
3131
  msgstr "证书"
3132
3132
 
3133
+ msgid "Certificate (PEM)"
3134
+ msgstr "证书 (PEM)"
3135
+
3133
3136
  msgid "Certificate ID field"
3134
3137
  msgstr "证书 ID 字段"
3135
3138
 
@@ -4900,6 +4903,12 @@ msgstr "當前"
4900
4903
  msgid "Currently installed"
4901
4904
  msgstr "当前已安装"
4902
4905
 
4906
+ msgid "Currently saved certificate"
4907
+ msgstr "当前保存的证书"
4908
+
4909
+ msgid "Currently saved private key"
4910
+ msgstr "当前已保存的私钥"
4911
+
4903
4912
  msgid "Custom"
4904
4913
  msgstr "自定义"
4905
4914
 
@@ -6496,6 +6505,12 @@ msgstr "在表格儲存格周圍繪製邊框"
6496
6505
  msgid "Drop"
6497
6506
  msgstr "放置"
6498
6507
 
6508
+ msgid "Drop a new certificate to replace"
6509
+ msgstr "发行一张新证书以替换"
6510
+
6511
+ msgid "Drop a new private key to replace"
6512
+ msgstr "放置一個新的私钥以替换"
6513
+
6499
6514
  msgid "Drop file here"
6500
6515
  msgstr "将文件放在此处"
6501
6516
 
@@ -6508,6 +6523,12 @@ msgstr "将文件放在此处"
6508
6523
  msgid "Drop files here or click to browse"
6509
6524
  msgstr "將檔案放置在此處或按一下以瀏覽"
6510
6525
 
6526
+ msgid "Drop the certificate in PEM format."
6527
+ msgstr "請上傳 PEM 格式的证书。"
6528
+
6529
+ msgid "Drop the private key in PEM format."
6530
+ msgstr "請提供 PEM 格式的私钥。"
6531
+
6511
6532
  msgid "Due to the large number, only a subset of alarms are displayed. Use search to narrow down the number of results."
6512
6533
  msgstr "由於數量眾多,僅顯示報警的子集。請使用搜尋縮小結果數量。"
6513
6534
 
@@ -6784,6 +6805,9 @@ msgstr "啟用深色主題支援"
6784
6805
  msgid "Enable in-product information & communication"
6785
6806
  msgstr "啟用產品中資訊和通信"
6786
6807
 
6808
+ msgid "Enable mTLS authentication"
6809
+ msgstr "启用 mTLS 身份验证"
6810
+
6787
6811
  msgid "Enable message banner"
6788
6812
  msgstr "啟用消息橫幅"
6789
6813
 
@@ -8028,11 +8052,11 @@ msgstr "若要连接模拟设备,请在已安装 `\n"
8028
8052
  " <a href=\"https://github.com/thin-edge/tedge-demo-container\" target=\"_blank\" rel=\"noopener noreferrer\">tedge-demo-container</a>`。"
8029
8053
 
8030
8054
  msgid "For correct application behavior you can use only \"{{ host }}\" or \"{{\n"
8031
- " defaultRedirectUrl\n"
8032
- " }}\", the latter one is recommended."
8033
- msgstr "要獲得正確的應用程式列為,您只能使用 \"{{ host }}\" 或 \"{{\n"
8034
- " defaultRedirectUrl\n"
8035
- " }}\",建議使用後者。"
8055
+ " defaultRedirectUrl\n"
8056
+ " }}\", the latter one is recommended."
8057
+ msgstr "為確保应用程序能正確運作,您只能使用「{{ host }}」或「{{\n"
8058
+ " defaultRedirectUrl\n"
8059
+ " }}」,建議使用後者。"
8036
8060
 
8037
8061
  msgid "For details refer to the\n"
8038
8062
  " <a c8y-guide-href=\"/docs/standard-tenant/standard-tenant-introduction\">\n"
@@ -10298,11 +10322,21 @@ msgstr "主要警报"
10298
10322
  msgid "Major`alarm`"
10299
10323
  msgstr "主要"
10300
10324
 
10301
- msgid "Make sure that \"Valid Redirect URIs\" in the authorization server is set to \"{{ redirectURI }}\" or to the full URIs of the used applications if the authorization server does not support patterns."
10302
- msgstr "確保授權伺服器中的「有效重定向 URI」設定為 \"{{ redirectURI }}\" 或所使用應用程式的完整 URI (如果授權伺服器不支援模式)。"
10303
-
10304
- msgid "Make sure that \"Valid Redirect URIs\" in the authorization server is set to \"{{ redirectURI }}\"."
10305
- msgstr "確認授權伺服器中的「有效重定向 URI」設定為 \"{{ redirectURI }}\"。"
10325
+ msgid "Make sure that \"Valid Redirect URIs\" in the authorization server is set to \"{{\n"
10326
+ " redirectURI\n"
10327
+ " }}\" or to the full URIs of the used applications if the authorization server\n"
10328
+ " does not support patterns."
10329
+ msgstr "请确保授权服务器中的「有效重定向 URI」已设置为「{{\n"
10330
+ " redirectURI\n"
10331
+ " }}」,或若授权服务器\n"
10332
+ " 不支援模式,则应设置为所使用的应用程序的完整 URI。"
10333
+
10334
+ msgid "Make sure that \"Valid Redirect URIs\" in the authorization server is set to \"{{\n"
10335
+ " redirectURI\n"
10336
+ " }}\"."
10337
+ msgstr "請確認授權伺服器中的「有效重定向 URI」已設定為「{{\n"
10338
+ " redirectURI\n"
10339
+ " }}」。"
10306
10340
 
10307
10341
  msgid "Make sure that:"
10308
10342
  msgstr "確保:"
@@ -13098,9 +13132,15 @@ msgstr "面板的打印屏幕"
13098
13132
  msgid "Private key"
13099
13133
  msgstr "私钥"
13100
13134
 
13135
+ msgid "Private key (PEM)"
13136
+ msgstr "私钥 (PEM)"
13137
+
13101
13138
  msgid "Private key cipher does not match"
13102
13139
  msgstr "私钥密码不匹配"
13103
13140
 
13141
+ msgid "Private key matching the client certificate, in PEM format (PKCS#8). The platform encrypts the key at rest after the first save and will return only an encrypted value on subsequent loads. Accepted file extensions: .pem, .key."
13142
+ msgstr "與客戶端证书相符的私钥,格式為 PEM(PKCS#8)。平台會在首次保存後對靜態私钥進行加密,並在後續加载時僅返回加密後的值。可接受的檔案副檔名:.pem、.key。"
13143
+
13104
13144
  msgid "Private key must be provided when \"Public/private keys\" option is selected."
13105
13145
  msgstr "选择 \"公钥/私钥\" 选项时,必须提供私钥。"
13106
13146
 
@@ -13239,6 +13279,9 @@ msgstr "提供的憑證"
13239
13279
  msgid "Provisioned certificates removed from user object: \"{{ userName }}\""
13240
13280
  msgstr "已從使用者物件移除預先配置的憑證:\"{{ userName }}\""
13241
13281
 
13282
+ msgid "Public X.509 client certificate in PEM format, issued for this tenant by a CA trusted by your authorization server. Accepted file extension: .pem."
13283
+ msgstr "由您的授權伺服器所信任的憑證授權機構(CA)為此租戶簽發的、採用 PEM 格式的公開 X.509 客戶端憑證。接受的檔案副檔名:.pem。"
13284
+
13242
13285
  msgid "Public key"
13243
13286
  msgstr "公钥"
13244
13287
 
@@ -17410,6 +17453,12 @@ msgstr "预览显示来自单一来源的原始文件结构。"
17410
17453
  msgid "The preview shows the structure of the raw file from all sources."
17411
17454
  msgstr "预览画面显示了来自全部来源的原始文件结构。"
17412
17455
 
17456
+ msgid "The private key is encrypted for security reasons."
17457
+ msgstr "基於安全考量,私钥已進行加密。"
17458
+
17459
+ msgid "The private key will be encrypted on the server after saving."
17460
+ msgstr "私钥在保存後將於伺服器上進行加密。"
17461
+
17413
17462
  msgid "The provided name is already taken."
17414
17463
  msgstr "提供的名稱已被使用。"
17415
17464
 
@@ -18742,6 +18791,9 @@ msgstr "使用 * 以允许任意值。"
18742
18791
  msgid "Use [Enter] or <br> tag to add a new line"
18743
18792
  msgstr "使用 [Enter] 或 <br> 標籤添加新行"
18744
18793
 
18794
+ msgid "Use a client certificate (mTLS) instead of a client secret to authenticate the platform with the authorization server. Use this option only if the authorization server enforces certificate-based client authentication."
18795
+ msgstr "请使用客户端证书(mTLS)而非客户端密码,来让平台向授权伺服器进行身份验证。仅当授权伺服器强制执行基于证书的客户端身份验证时,才应使用此选项。"
18796
+
18745
18797
  msgid "Use alarms to create smart rules for microservice availability."
18746
18798
  msgstr "使用警报为微服务可用性创建智能规则。"
18747
18799
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c8y/ng1-modules",
3
- "version": "1023.90.1",
3
+ "version": "1023.92.0",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Cumulocity",
6
6
  "description": "AngularJS modules for Cumulocity IoT applications.",
@@ -1 +1 @@
1
- (()=>{function e(s,n,o,r,t,e,i,u,a,l,c,g){var f,d=this;function h(e){return f=e?[]:d.users,d.users=[],o.list((e=_.get(d.filters,"text"),n=(n=_.map(_.get(d.filters,"globalRoles"),"id")).length?n.join(","):void 0,{withSubusersCount:!0,username:e,groups:n,withApps:!1,withGroups:!1,withRoles:!1,onlyRoots:_.isEmpty(e)})).then(p);var n}function p(e){E(e),d.users.paging=e.paging}function E(e){var n=d.users,t=n.paging,r=o.getTfaStrategy();_.forEach(e,function(t){var e=_.find(f,{id:t.id});t.twoFactorAuthenticationEnabled||s.all({enforced:o.isTfaActive(t),strategy:r}).then(function(e){var n=e.enforced,e=e.strategy;"SMS"!==e&&e||n&&(t.twoFactorAuthenticationEnabled=n)}),e&&(t._expanded=e._expanded),_.some(n,{id:t.id})||(n=n.concat([t]))}),n.paging=t,d.users=n}function R(e){d.globalRoles=e}function A(e){return e._globalRoles=_.map(_.get(e,"groups.references"),function(e){return _.find(d.globalRoles,{id:e.group.id})}),e}function U(){o.current().then(function(e){d.canAddUser=o.hasRole(e,"ROLE_USER_MANAGEMENT_ADMIN")||d.FEATURE_USER_HIERARCHY&&o.hasRole(e,"ROLE_USER_MANAGEMENT_CREATE"),d.canRevokeTokens=o.hasRole(e,"ROLE_USER_MANAGEMENT_ADMIN")})}function v(e){return f=d.users,o.listAll({owner:e.id,withSubusersCount:!0}).then(E)}_.assign(d,{ROUTE_NEW_USER:t.ROUTE_NEW_USER,$onInit:function(){s.all([h(),e.global.list({pageSize:1e4}).then(R)]).then(function(){return _.forEach(d.users,A)}),t.userHierarchyActive().then(function(e){d.FEATURE_USER_HIERARCHY=e}).then(U)},loadMore:function(){d.users.paging.loading=!0,d.users.paging.next().then(p).finally(function(){d.users.paging.loading=!1})},loadUsers:h,loadSubusers:v,changeUser:function(s,e){var n="changeGlobalRoles"===e.name;return t.warnAboutUserLogOutIfNeeded(s,{rolesChanged:n}).then(function(){return t.changeUser(s,e)}).then(function(e){var n,t,r=s;return(e=e||{}).removeUser&&(d.users=_.reject(d.users,{id:r.id}),t=_.get(r,"_owner.id"),d.users=_.map(d.users,function(e){return t&&t===e.id?(e.subusersCount--,angular.copy(e)):e})),e.refresh||e.removeUser||(n=o.list({username:r.id,withSubusersCount:!0}).then(_.first).then(function(t){var r=t.id,e=_.map(d.users,function(e){var n=r===e.id;return n&&(t._expanded=e._expanded),n?A(t):e});_.assign(e,_.pick(d.users,["statistics","paging"])),d.users=e})),n=e.refresh?h():n})},showExpandCollapse:function(){return d.FEATURE_USER_HIERARCHY&&_.some(d.users,function(e){return 0<e.subusersCount||_.get(e,"_owns.length")})},collapseAll:function(){t.collapseAll(d.users)},expandAll:function(){t.expandAll(d.users),s.all(_.map(d.users,function(e){return e.subusersCount>e._owns.length?v(e).then(function(){return!0}):s.resolve(!1)})).then(function(e){_.some(e)&&n(d.expandAll)})},filters:{},applyFilters:function(){h(!0)},clearFilters:function(){d.filters={},h(!0)},isAnyFilterSelected:function(){return _.some(d.filters,_.identity)},refresh:function(){return h(!0).then(function(){return _.forEach(d.users,A)})},revokeTokens:function(){function e(){return o.current().then(function(e){return t(e)}).then(function(e){return e?r.logoutAndReloadPage():s.resolve()})}var n=g.get("c8yAuthBridgeService").getPreferredLoginOption(),t=function(e){return!(!o.hasExternalOrigin(e)&&"BASIC"===n.type)};i({title:l("Confirm log out all users?"),body:c.getString('You are about to log out all users currently logged with "OAI-Secure" or "Single sign-on redirect". The JWT tokens retrieved by all devices in the current tenant will also be invalidated. Do you want to proceed?'),status:"warning",size:"sm",labels:{ok:l("Confirm")}}).then(function(){return o.revokeTokens()}).then(e).then(function(){return u.success(l("Logged out all users and invalidated tokens."))}).catch(function(e){e&&u.danger(a.getResErrorMessage(e))})}})}e.$inject=["$q","$timeout","c8yUser","c8yUserUtil","c8yUsersUi","c8yRoles","c8yModal","c8yAlert","c8yBase","gettext","gettextCatalog","$injector"],angular.module("c8y.users").component("c8yUserListView",{templateUrl:":::PLUGIN_PATH:::/userListView/userListView.html",controller:e,controllerAs:"vm"})})();
1
+ (()=>{function e(s,t,n,o,r,i,e,u,l,a,c,g,f){var d,h=this,p=(_.assign(h,{ROUTE_NEW_USER:i.ROUTE_NEW_USER,$onInit:function(){s.all([E(),e.global.list({pageSize:1e4}).then(v)]).then(function(){return _.forEach(h.users,y)}),i.userHierarchyActive().then(function(e){h.FEATURE_USER_HIERARCHY=e}).then(U),t.$watch("vm.filters.text",function(e,n){e!==n&&(h.showSearchHint=e&&0<e.length&&e.length<3,!e||3<=e.length?p(!0):n&&3<=n.length&&p(!0,!0))})},loadMore:function(){h.users.paging.loading=!0,h.users.paging.next().then(R).finally(function(){h.users.paging.loading=!1})},loadUsers:E,loadSubusers:S,changeUser:function(s,e){var n="changeGlobalRoles"===e.name;return i.warnAboutUserLogOutIfNeeded(s,{rolesChanged:n}).then(function(){return i.changeUser(s,e)}).then(function(e){var n,t,r=s;return(e=e||{}).removeUser&&(h.users=_.reject(h.users,{id:r.id}),t=_.get(r,"_owner.id"),h.users=_.map(h.users,function(e){return t&&t===e.id?(e.subusersCount--,angular.copy(e)):e})),e.refresh||e.removeUser||(n=o.list({username:r.id,withSubusersCount:!0}).then(_.first).then(function(t){var r=t.id,e=_.map(h.users,function(e){var n=r===e.id;return n&&(t._expanded=e._expanded),n?y(t):e});_.assign(e,_.pick(h.users,["statistics","paging"])),h.users=e})),n=e.refresh?E():n})},showExpandCollapse:function(){return h.FEATURE_USER_HIERARCHY&&_.some(h.users,function(e){return 0<e.subusersCount||_.get(e,"_owns.length")})},collapseAll:function(){i.collapseAll(h.users)},expandAll:function(){i.expandAll(h.users),s.all(_.map(h.users,function(e){return e.subusersCount>e._owns.length?S(e).then(function(){return!0}):s.resolve(!1)})).then(function(e){_.some(e)&&n(h.expandAll)})},filters:{},applyFilters:function(){E(!0)},clearFilters:function(){h.filters.globalRoles=[],E(!0)},isAnyFilterSelected:function(){return 0<_.get(h.filters,"globalRoles.length",0)},refresh:function(){return E(!0).then(function(){return _.forEach(h.users,y)})},revokeTokens:function(){function e(){return o.current().then(function(e){return t(e)}).then(function(e){return e?r.logoutAndReloadPage():s.resolve()})}var n=f.get("c8yAuthBridgeService").getPreferredLoginOption(),t=function(e){return!(!o.hasExternalOrigin(e)&&"BASIC"===n.type)};u({title:c("Confirm log out all users?"),body:g.getString('You are about to log out all users currently logged with "OAI-Secure" or "Single sign-on redirect". The JWT tokens retrieved by all devices in the current tenant will also be invalidated. Do you want to proceed?'),status:"warning",size:"sm",labels:{ok:c("Confirm")}}).then(function(){return o.revokeTokens()}).then(e).then(function(){return l.success(c("Logged out all users and invalidated tokens."))}).catch(function(e){e&&l.danger(a.getResErrorMessage(e))})},onSearchKeydown:function(e){"Enter"===e.key&&(e.preventDefault(),p.cancel(),E(!0))},clearSearch:function(){h.filters.text="",p.cancel(),E(!0)}}),_.debounce(function(e,n){E(e,n),t.$applyAsync()},300));function E(e){var n=1<arguments.length&&void 0!==arguments[1]&&arguments[1];return d=e?[]:h.users,h.users=[],o.list(n?{}:(e=_.get(h.filters,"text"),n=(n=_.map(_.get(h.filters,"globalRoles"),"id")).length?n.join(","):void 0,{withSubusersCount:!0,usernameContains:e,groups:n,withApps:!1,withGroups:!1,withRoles:!1,onlyRoots:_.isEmpty(e)})).then(R)}function R(e){A(e),h.users.paging=e.paging}function A(e){var n=h.users,t=n.paging,r=o.getTfaStrategy();_.forEach(e,function(t){var e=_.find(d,{id:t.id});t.twoFactorAuthenticationEnabled||s.all({enforced:o.isTfaActive(t),strategy:r}).then(function(e){var n=e.enforced,e=e.strategy;"SMS"!==e&&e||n&&(t.twoFactorAuthenticationEnabled=n)}),e&&(t._expanded=e._expanded),_.some(n,{id:t.id})||(n=n.concat([t]))}),n.paging=t,h.users=n}function v(e){h.globalRoles=e}function y(e){return e._globalRoles=_.map(_.get(e,"groups.references"),function(e){return _.find(h.globalRoles,{id:e.group.id})}),e}function U(){o.current().then(function(e){h.canAddUser=o.hasRole(e,"ROLE_USER_MANAGEMENT_ADMIN")||h.FEATURE_USER_HIERARCHY&&o.hasRole(e,"ROLE_USER_MANAGEMENT_CREATE"),h.canRevokeTokens=o.hasRole(e,"ROLE_USER_MANAGEMENT_ADMIN")})}function S(e){return d=h.users,o.listAll({owner:e.id,withSubusersCount:!0}).then(A)}}e.$inject=["$q","$scope","$timeout","c8yUser","c8yUserUtil","c8yUsersUi","c8yRoles","c8yModal","c8yAlert","c8yBase","gettext","gettextCatalog","$injector"],angular.module("c8y.users").component("c8yUserListView",{templateUrl:":::PLUGIN_PATH:::/userListView/userListView.html",controller:e,controllerAs:"vm"})})();
@@ -21,21 +21,40 @@
21
21
  <div class="input-group input-group-search">
22
22
  <input
23
23
  class="form-control"
24
- title="{{ 'Filter users' | translate }}"
24
+ title="{{ 'Search users' | translate }}"
25
25
  id="Filter"
26
- placeholder="{{ 'Filter users' | translate }}"
26
+ placeholder="{{ 'Search users' | translate }}"
27
27
  type="search"
28
28
  ng-model="vm.filters.text"
29
+ ng-keydown="vm.onSearchKeydown($event)"
29
30
  />
30
- <span class="input-group-addon">
31
+ <span
32
+ class="input-group-addon"
33
+ ng-if="!vm.filters.text"
34
+ >
31
35
  <i c8y-icon="search"></i>
32
36
  </span>
37
+ <span
38
+ class="input-group-addon clickable"
39
+ title="{{ 'Clear search' | translate }}"
40
+ ng-if="vm.filters.text && !vm.showSearchHint"
41
+ ng-click="vm.clearSearch()"
42
+ >
43
+ <i c8y-icon="times"></i>
44
+ </span>
45
+ <span
46
+ class="input-group-addon text-warning"
47
+ title="{{ 'Enter at least 3 characters to search.' | translate }}"
48
+ ng-if="vm.showSearchHint"
49
+ >
50
+ <i c8y-icon="exclamation-circle"></i>
51
+ </span>
33
52
  <span
34
53
  class="sr-only"
35
54
  for="Filter"
36
55
  translate
37
56
  >
38
- Filter users
57
+ Search users
39
58
  </span>
40
59
  </div>
41
60
  </div>
@@ -57,7 +76,6 @@
57
76
  title="{{ 'Apply filters' | translate }}"
58
77
  type="button"
59
78
  ng-click="vm.applyFilters()"
60
- c8y-key-shortcut="Enter"
61
79
  >
62
80
  <i c8y-icon="filter"></i>
63
81
  <span
@@ -86,32 +104,6 @@
86
104
  </form>
87
105
  </li>
88
106
 
89
- <li>
90
- <button
91
- class="btn btn-link hidden-sm"
92
- title="{{ 'Expand all' | translate }}"
93
- type="button"
94
- ng-click="vm.expandAll()"
95
- ng-show="vm.showExpandCollapse()"
96
- >
97
- <i c8y-icon="window-maximize"></i>
98
- {{ 'Expand all' | translate }}
99
- </button>
100
- </li>
101
-
102
- <li>
103
- <button
104
- class="btn btn-link hidden-sm"
105
- title="{{ 'Collapse all' | translate }}"
106
- type="button"
107
- ng-click="vm.collapseAll()"
108
- ng-show="vm.showExpandCollapse()"
109
- >
110
- <i c8y-icon="minus"></i>
111
- {{ 'Collapse all' | translate }}
112
- </button>
113
- </li>
114
-
115
107
  <li
116
108
  title="{{ 'Add user' | translate }}"
117
109
  ng-show="vm.canAddUser"
@@ -129,19 +121,6 @@
129
121
  </a>
130
122
  </li>
131
123
 
132
- <li ng-show="vm.canRevokeTokens">
133
- <button
134
- class="btn btn-link"
135
- title="{{ 'Log out all users' | translate }}"
136
- type="button"
137
- data-cy="c8y-users--log-out-all-users"
138
- ng-click="vm.revokeTokens()"
139
- >
140
- <i c8y-icon="account-disable"></i>
141
- {{ 'Log out all users' | translate }}
142
- </button>
143
- </li>
144
-
145
124
  <li>
146
125
  <button
147
126
  class="btn btn-link"
@@ -153,6 +132,68 @@
153
132
  {{ 'Reload' | translate }}
154
133
  </button>
155
134
  </li>
135
+
136
+ <li ng-show="vm.showExpandCollapse() || vm.canRevokeTokens">
137
+ <div
138
+ class="dropdown"
139
+ uib-dropdown
140
+ >
141
+ <button
142
+ class="dropdown-toggle c8y-dropdown d-flex a-i-center"
143
+ title="{{ 'More' | translate }}…"
144
+ aria-haspopup="true"
145
+ type="button"
146
+ uib-dropdown-toggle
147
+ >
148
+ <span
149
+ class="text-truncate"
150
+ translate
151
+ >More…</span
152
+ >
153
+ <i c8y-icon="caret-down"></i>
154
+ </button>
155
+ <ul
156
+ class="dropdown-menu dropdown-menu-right"
157
+ uib-dropdown-menu
158
+ >
159
+ <li>
160
+ <button
161
+ class="btn btn-link hidden-sm"
162
+ title="{{ 'Expand all' | translate }}"
163
+ type="button"
164
+ ng-click="vm.expandAll()"
165
+ ng-show="vm.showExpandCollapse()"
166
+ >
167
+ <i c8y-icon="window-maximize"></i>
168
+ {{ 'Expand all' | translate }}
169
+ </button>
170
+ </li>
171
+ <li>
172
+ <button
173
+ class="btn btn-link hidden-sm"
174
+ title="{{ 'Collapse all' | translate }}"
175
+ type="button"
176
+ ng-click="vm.collapseAll()"
177
+ ng-show="vm.showExpandCollapse()"
178
+ >
179
+ <i c8y-icon="minus"></i>
180
+ {{ 'Collapse all' | translate }}
181
+ </button>
182
+ </li>
183
+ <li ng-show="vm.canRevokeTokens">
184
+ <button
185
+ title="{{ 'Log out all users' | translate }}"
186
+ type="button"
187
+ data-cy="c8y-users--log-out-all-users"
188
+ ng-click="vm.revokeTokens()"
189
+ >
190
+ <i c8y-icon="account-disable"></i>
191
+ {{ 'Log out all users' | translate }}
192
+ </button>
193
+ </li>
194
+ </ul>
195
+ </div>
196
+ </li>
156
197
  </c8y-ui-action-bar-set>
157
198
 
158
199
  <c8y-help src="/docs/standard-tenant/managing-users/#managing-users"></c8y-help>