@descope/web-components-ui 1.0.290 → 1.0.292
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/cjs/index.cjs.js +1336 -912
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +1565 -967
- package/dist/index.esm.js.map +1 -1
- package/dist/umd/1000.js +1 -1
- package/dist/umd/descope-grid-index-js.js +1 -1
- package/dist/umd/descope-new-password-descope-new-password-internal-index-js.js +1 -1
- package/dist/umd/descope-new-password-index-js.js +1 -1
- package/dist/umd/descope-policy-validation-index-js.js +1 -0
- package/dist/umd/index.js +1 -1
- package/dist/umd/mapping-fields-descope-mappings-field-descope-mapping-item-index-js.js +1 -1
- package/dist/umd/mapping-fields-descope-mappings-field-descope-mappings-field-internal-index-js.js +1 -1
- package/dist/umd/mapping-fields-descope-mappings-field-index-js.js +2 -2
- package/dist/umd/mapping-fields-descope-saml-group-mappings-descope-saml-group-mappings-internal-index-js.js +1 -0
- package/dist/umd/mapping-fields-descope-saml-group-mappings-index-js.js +1 -0
- package/package.json +1 -1
- package/src/components/descope-new-password/NewPasswordClass.js +30 -2
- package/src/components/descope-new-password/descope-new-password-internal/NewPasswordInternal.js +51 -3
- package/src/components/descope-new-password/index.js +1 -0
- package/src/components/descope-policy-validation/PolicyValidationClass.js +220 -0
- package/src/components/descope-policy-validation/helpers.js +2 -0
- package/src/components/descope-policy-validation/index.js +5 -0
- package/src/components/mapping-fields/descope-mappings-field/MappingsFieldClass.js +14 -1
- package/src/components/mapping-fields/descope-mappings-field/descope-mapping-item/MappingItem.js +1 -1
- package/src/components/mapping-fields/descope-mappings-field/descope-mappings-field-internal/MappingsFieldInternal.js +2 -2
- package/src/components/mapping-fields/descope-saml-group-mappings/SamlGroupMappingsClass.js +110 -0
- package/src/components/mapping-fields/descope-saml-group-mappings/descope-saml-group-mappings-internal/SamlGroupMappingsInternal.js +136 -0
- package/src/components/mapping-fields/descope-saml-group-mappings/descope-saml-group-mappings-internal/index.js +3 -0
- package/src/components/mapping-fields/descope-saml-group-mappings/index.js +10 -0
- package/src/index.cjs.js +2 -0
- package/src/index.d.ts +2 -0
- package/src/index.js +2 -0
- package/src/mixins/proxyInputMixin.js +7 -0
- package/src/theme/components/index.js +4 -0
- package/src/theme/components/inputWrapper.js +3 -1
- package/src/theme/components/mappingsField.js +3 -1
- package/src/theme/components/newPassword.js +5 -0
- package/src/theme/components/policyValidation.js +29 -0
- package/src/theme/components/samlGroupMappings.js +13 -0
@@ -0,0 +1 @@
|
|
1
|
+
"use strict";(self.webpackChunkDescopeUI=self.webpackChunkDescopeUI||[]).push([[9476,9656],{6867:(e,t,i)=>{i.d(t,{Z:()=>p,f:()=>a});var n=i(3878),s=i(4567);const a=(0,s.iY)("saml-group-mappings-internal"),l=(0,n.P)({componentName:a,baseSelector:""}),p=class extends l{static get observedAttributes(){return["invalid"].concat(l.observedAttributes||[])}constructor(){super(),this.innerHTML='\n <descope-text-field variant="body2" bordered="true"></descope-text-field>\n <descope-mappings-field></descope-mappings-field>\n ',this.groupInputElement=this.querySelector("descope-text-field"),this.mappingsElement=this.querySelector("descope-mappings-field")}resetInvalidIndication(){this.removeAttribute("invalid")}handleMappingsInvalidChange(e){e.includes("invalid")&&(this.mappingsElement.hasAttribute("invalid")||this.resetInvalidIndication())}initFocusHandler(){this.addEventListener("focus",(e=>{e.isTrusted&&(this.mappingsElement.checkValidity()?this.groupInputElement:this.mappingsElement).focus()}))}init(){this.initFocusHandler(),super.init?.(),(0,s.oP)(this,this.groupInputElement,{mapAttrs:{"label-group":"label"},includeAttrs:["size","label-group","readonly","disabled"]}),(0,s.oP)(this,this.mappingsElement,{includeAttrs:["size","full-width","label-value","label-attr","button-label","separator","options","readonly","disabled","data-errormessage-pattern-mismatch"]}),(0,s.FX)(this.mappingsElement,this.handleMappingsInvalidChange.bind(this),{includeAttrs:["invalid"]})}get value(){return{group:this.groupInputElement.value,mappings:this.mappingsElement.value}}set value(e){e?.group&&"string"==typeof e.group&&(this.groupInputElement.value=e.group),Array.isArray(e?.mappings)&&(this.mappingsElement.value=e.mappings)}getValidity(){return this.groupInputElement.checkValidity()?this.mappingsElement.checkValidity()?{}:this.mappingsElement.validity:this.groupInputElement.validity}#e(e){if(e){if(!this.groupInputElement.checkValidity())return void this.groupInputElement.setAttribute("invalid","true");this.mappingsElement.checkValidity()||this.mappingsElement.setAttribute("invalid","true")}}attributeChangedCallback(e,t,i){super.attributeChangedCallback?.(e,t,i),"invalid"===e&&this.#e("true"===i)}}},4115:(e,t,i)=>{i.r(t);var n=i(6867);customElements.define(n.f,n.Z)},3277:(e,t,i)=>{i.r(t),i.d(t,{SamlGroupMappingsClass:()=>d}),i(9381);var n=i(1e3),s=i(2061),a=i(4567),l=i(6867);const p=(0,a.iY)("saml-group-mappings"),{host:r,groupInput:o}={host:{selector:()=>":host"},groupInput:{selector:"descope-text-field"}},d=(0,s.qC)((0,n.yk)({mappings:{hostWidth:{...r,property:"width"},hostDirection:{...r,property:"direction"},groupNameInputMarginBottom:{...o,property:"margin-bottom"}}}),n.e4,(0,n.dj)({proxyProps:["value","selectionStart"],inputEvent:"input",triggerValidationEvents:["mapping-item-added","mapping-item-removed"],proxyParentValidation:!0}),n.Ae,(e=>class extends e{init(){super.init?.();const e=document.createElement("template");e.innerHTML=`\n <${l.f}\n tabindex="-1"\n ></${l.f}>\n `,this.baseElement.appendChild(e.content.cloneNode(!0)),this.inputElement=this.shadowRoot.querySelector(l.f),(0,a.oP)(this,this.inputElement,{includeAttrs:["size","full-width","label-group","label-value","label-attr","button-label","separator","options","readonly","disabled"]}),(0,a.tg)(this,this.inputElement,{includeAttrs:["invalid"]})}}))((0,n.DM)({slots:[],wrappedEleName:"vaadin-custom-field",style:()=>"\n :host {\n display: inline-flex;\n max-width: 100%;\n direction: ltr;\n }\n\n vaadin-custom-field {\n line-height: unset;\n width: 100%;\n }\n\n descope-text-field {\n width: auto;\n }\n\n descope-mappings-field {\n display: block;\n }\n ",excludeAttrsSync:["tabindex","label-group","label-value","label-attr","button-label","separator","options","error-message"],componentName:p}));i(9357),i(5894),i(4115),customElements.define(p,d)}}]);
|
package/package.json
CHANGED
@@ -4,9 +4,12 @@ import { createStyleMixin, proxyInputMixin, draggableMixin, createProxy } from '
|
|
4
4
|
import { componentName as descopeInternalComponentName } from './descope-new-password-internal/componentName';
|
5
5
|
import { PasswordClass } from '../descope-password/PasswordClass';
|
6
6
|
import { useHostExternalPadding } from '../../helpers/themeHelpers/resetHelpers';
|
7
|
+
import { PolicyValidationClass } from '../descope-policy-validation';
|
7
8
|
|
8
9
|
export const componentName = getComponentName('new-password');
|
9
10
|
|
11
|
+
const policyPreviewVars = PolicyValidationClass.cssVarList;
|
12
|
+
|
10
13
|
const customMixin = (superclass) =>
|
11
14
|
class NewPasswordMixinClass extends superclass {
|
12
15
|
init() {
|
@@ -40,18 +43,32 @@ const customMixin = (superclass) =>
|
|
40
43
|
'invalid',
|
41
44
|
'readonly',
|
42
45
|
'draggable',
|
46
|
+
'has-validation',
|
47
|
+
'policy-label',
|
48
|
+
'active-policies',
|
49
|
+
'available-policies',
|
50
|
+
'data-password-policy-value-minlength',
|
43
51
|
],
|
44
52
|
});
|
45
53
|
}
|
46
54
|
};
|
47
55
|
|
48
|
-
const {
|
56
|
+
const {
|
57
|
+
host,
|
58
|
+
label,
|
59
|
+
internalInputsWrapper,
|
60
|
+
errorMessage,
|
61
|
+
helperText,
|
62
|
+
passwordInput,
|
63
|
+
policyPreview,
|
64
|
+
} = {
|
49
65
|
host: { selector: () => ':host' },
|
50
66
|
label: { selector: '::part(label)' },
|
51
67
|
internalInputsWrapper: { selector: 'descope-new-password-internal .wrapper' },
|
52
68
|
helperText: { selector: '::part(helper-text)' },
|
53
69
|
errorMessage: { selector: '::part(error-message)' },
|
54
70
|
passwordInput: { selector: 'descope-password' },
|
71
|
+
policyPreview: { selector: 'descope-policy-validation' },
|
55
72
|
};
|
56
73
|
|
57
74
|
export const NewPasswordClass = compose(
|
@@ -75,6 +92,11 @@ export const NewPasswordClass = compose(
|
|
75
92
|
],
|
76
93
|
inputsRequiredIndicator: { ...host, property: 'content' },
|
77
94
|
spaceBetweenInputs: { ...internalInputsWrapper, property: 'gap' },
|
95
|
+
policyPreviewBackgroundColor: {
|
96
|
+
...policyPreview,
|
97
|
+
property: policyPreviewVars.backgroundColor,
|
98
|
+
},
|
99
|
+
policyPreviewPadding: { ...policyPreview, property: policyPreviewVars.padding },
|
78
100
|
},
|
79
101
|
}),
|
80
102
|
draggableMixin,
|
@@ -113,7 +135,6 @@ export const NewPasswordClass = compose(
|
|
113
135
|
-webkit-mask-image: none;
|
114
136
|
min-height: 0;
|
115
137
|
width: 100%;
|
116
|
-
height: 100%;
|
117
138
|
padding: 0;
|
118
139
|
}
|
119
140
|
descope-new-password-internal > .wrapper {
|
@@ -129,6 +150,13 @@ export const NewPasswordClass = compose(
|
|
129
150
|
descope-new-password-internal vaadin-password-field::before {
|
130
151
|
height: initial;
|
131
152
|
}
|
153
|
+
descope-policy-validation {
|
154
|
+
margin-top: 8px;
|
155
|
+
display: flex;
|
156
|
+
}
|
157
|
+
descope-policy-validation.hidden {
|
158
|
+
display: none;
|
159
|
+
}
|
132
160
|
`,
|
133
161
|
excludeAttrsSync: ['tabindex'],
|
134
162
|
componentName,
|
package/src/components/descope-new-password/descope-new-password-internal/NewPasswordInternal.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { createBaseInputClass } from '../../../baseClasses/createBaseInputClass';
|
2
|
-
import { observeAttributes } from '../../../helpers/componentHelpers';
|
2
|
+
import { forwardAttrs, observeAttributes } from '../../../helpers/componentHelpers';
|
3
3
|
import { NewPasswordClass } from '../NewPasswordClass';
|
4
4
|
import { componentName } from './componentName';
|
5
5
|
|
@@ -10,6 +10,7 @@ const removeAttrPrefix = (attr, prefix) => attr.replace(prefix, '');
|
|
10
10
|
|
11
11
|
const passwordInputAttrs = ['password-label', 'password-placeholder'];
|
12
12
|
const confirmInputAttrs = ['confirm-label', 'confirm-placeholder'];
|
13
|
+
const policyPanelAttrs = ['has-validation'];
|
13
14
|
const commonAttrs = [
|
14
15
|
'disabled',
|
15
16
|
'bordered',
|
@@ -22,7 +23,12 @@ const commonAttrs = [
|
|
22
23
|
'autocomplete',
|
23
24
|
];
|
24
25
|
|
25
|
-
const inputRelatedAttrs = [].concat(
|
26
|
+
const inputRelatedAttrs = [].concat(
|
27
|
+
commonAttrs,
|
28
|
+
passwordInputAttrs,
|
29
|
+
confirmInputAttrs,
|
30
|
+
policyPanelAttrs
|
31
|
+
);
|
26
32
|
|
27
33
|
const BaseInputClass = createBaseInputClass({ componentName, baseSelector: 'div' });
|
28
34
|
|
@@ -54,7 +60,15 @@ class NewPasswordInternal extends BaseInputClass {
|
|
54
60
|
return this.getAttribute('has-confirm') === 'true';
|
55
61
|
}
|
56
62
|
|
63
|
+
get hasValidation() {
|
64
|
+
return this.getAttribute('has-validation') === 'true';
|
65
|
+
}
|
66
|
+
|
57
67
|
getValidity() {
|
68
|
+
if (!this.policyPanel.isValid) {
|
69
|
+
return { patternMismatch: true };
|
70
|
+
}
|
71
|
+
|
58
72
|
if (this.isRequired && !this.value) {
|
59
73
|
return { valueMissing: true };
|
60
74
|
}
|
@@ -85,7 +99,12 @@ class NewPasswordInternal extends BaseInputClass {
|
|
85
99
|
}
|
86
100
|
|
87
101
|
renderInputs(shouldRenderConfirm) {
|
88
|
-
let template =
|
102
|
+
let template = `
|
103
|
+
<div>
|
104
|
+
<descope-password data-id="password"></descope-password>
|
105
|
+
<descope-policy-validation></descope-policy-validation>
|
106
|
+
</div>
|
107
|
+
`;
|
89
108
|
|
90
109
|
if (shouldRenderConfirm) {
|
91
110
|
template += `<descope-password data-id="confirm"></descope-password>`;
|
@@ -95,6 +114,7 @@ class NewPasswordInternal extends BaseInputClass {
|
|
95
114
|
|
96
115
|
this.passwordInput = this.querySelector('[data-id="password"]');
|
97
116
|
this.confirmInput = this.querySelector('[data-id="confirm"]');
|
117
|
+
this.policyPanel = this.querySelector('descope-policy-validation');
|
98
118
|
|
99
119
|
this.inputs = [this.passwordInput, this.confirmInput];
|
100
120
|
|
@@ -105,6 +125,23 @@ class NewPasswordInternal extends BaseInputClass {
|
|
105
125
|
[...passwordInputAttrs, ...confirmInputAttrs, ...commonAttrs].forEach((attr) => {
|
106
126
|
this.attributeChangedCallback(attr, null, this.getAttribute(attr));
|
107
127
|
});
|
128
|
+
|
129
|
+
this.passwordInput.addEventListener('input', (e) => {
|
130
|
+
this.policyPanel.setAttribute('value', e.target.value);
|
131
|
+
});
|
132
|
+
|
133
|
+
forwardAttrs(this, this.policyPanel, {
|
134
|
+
includeAttrs: [
|
135
|
+
'policy-label',
|
136
|
+
'available-policies',
|
137
|
+
'active-policies',
|
138
|
+
'data-password-policy-value-minlength',
|
139
|
+
],
|
140
|
+
mapAttrs: {
|
141
|
+
'policy-label': 'label',
|
142
|
+
'available-policies': 'data',
|
143
|
+
},
|
144
|
+
});
|
108
145
|
}
|
109
146
|
|
110
147
|
// the inputs are not required but we still want it to have a required
|
@@ -164,6 +201,14 @@ class NewPasswordInternal extends BaseInputClass {
|
|
164
201
|
value === null ? ele?.removeAttribute(name) : ele?.setAttribute(name, value);
|
165
202
|
}
|
166
203
|
|
204
|
+
hidePolicy() {
|
205
|
+
this.policyPanel.classList.add('hidden');
|
206
|
+
}
|
207
|
+
|
208
|
+
showPolicy() {
|
209
|
+
this.policyPanel.classList.remove('hidden');
|
210
|
+
}
|
211
|
+
|
167
212
|
attributeChangedCallback(attrName, oldValue, newValue) {
|
168
213
|
super.attributeChangedCallback?.(attrName, oldValue, newValue);
|
169
214
|
|
@@ -185,6 +230,9 @@ class NewPasswordInternal extends BaseInputClass {
|
|
185
230
|
newValue
|
186
231
|
);
|
187
232
|
}
|
233
|
+
if (attrName === 'has-validation') {
|
234
|
+
newValue === 'true' ? this.showPolicy() : this.hidePolicy();
|
235
|
+
}
|
188
236
|
}
|
189
237
|
}
|
190
238
|
}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import { componentName, NewPasswordClass } from './NewPasswordClass';
|
2
2
|
import '../descope-text-field';
|
3
3
|
import '../descope-password';
|
4
|
+
import '../descope-policy-validation';
|
4
5
|
import './descope-new-password-internal';
|
5
6
|
|
6
7
|
customElements.define(componentName, NewPasswordClass);
|
@@ -0,0 +1,220 @@
|
|
1
|
+
// eslint-disable-next-line max-classes-per-file
|
2
|
+
import { createStyleMixin, draggableMixin, componentNameValidationMixin } from '../../mixins';
|
3
|
+
import { createBaseClass } from '../../baseClasses/createBaseClass';
|
4
|
+
import { compose } from '../../helpers';
|
5
|
+
import { getComponentName } from '../../helpers/componentHelpers';
|
6
|
+
import { interpolateString } from './helpers';
|
7
|
+
|
8
|
+
export const componentName = getComponentName('policy-validation');
|
9
|
+
|
10
|
+
const overrideAttrs = ['data-password-policy-value-minlength'];
|
11
|
+
const dataAttrs = ['data', 'active-policies', 'overrides', ...overrideAttrs];
|
12
|
+
const policyAttrs = ['label', 'value', ...dataAttrs];
|
13
|
+
|
14
|
+
class RawPolicyValidation extends createBaseClass({ componentName, baseSelector: ':host > div' }) {
|
15
|
+
#availablePolicies;
|
16
|
+
|
17
|
+
#activePolicies = [];
|
18
|
+
|
19
|
+
#overrides;
|
20
|
+
|
21
|
+
static get observedAttributes() {
|
22
|
+
return policyAttrs;
|
23
|
+
}
|
24
|
+
|
25
|
+
constructor() {
|
26
|
+
super();
|
27
|
+
|
28
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
29
|
+
<div>
|
30
|
+
<div class="label"></div>
|
31
|
+
<ul></ul>
|
32
|
+
</div>
|
33
|
+
<style>
|
34
|
+
:host > div {
|
35
|
+
width: 100%;
|
36
|
+
display: flex;
|
37
|
+
flex-direction: column;
|
38
|
+
box-sizing: border-box;
|
39
|
+
}
|
40
|
+
.label {
|
41
|
+
max-width: 100%;
|
42
|
+
text-wrap: wrap;
|
43
|
+
overflow-wrap: break-word;
|
44
|
+
}
|
45
|
+
.hide-label .label {
|
46
|
+
display: none;
|
47
|
+
}
|
48
|
+
ul {
|
49
|
+
display: flex;
|
50
|
+
flex-direction: column;
|
51
|
+
padding: 0;
|
52
|
+
margin: 0;
|
53
|
+
}
|
54
|
+
ul, li {
|
55
|
+
margin: 0;
|
56
|
+
padding: 0;
|
57
|
+
list-style: none;
|
58
|
+
}
|
59
|
+
li::before {
|
60
|
+
display: inline-block;
|
61
|
+
width: 1em;
|
62
|
+
text-align: center;
|
63
|
+
}
|
64
|
+
</style>
|
65
|
+
`;
|
66
|
+
|
67
|
+
this.panel = this.shadowRoot.querySelector(':host > div');
|
68
|
+
this.label = this.shadowRoot.querySelector('.label');
|
69
|
+
this.list = this.shadowRoot.querySelector('ul');
|
70
|
+
}
|
71
|
+
|
72
|
+
attributeChangedCallback(attrName, oldValue, newValue) {
|
73
|
+
super.attributeChangedCallback?.(attrName, oldValue, newValue);
|
74
|
+
if (oldValue !== newValue) {
|
75
|
+
if (attrName === 'label') {
|
76
|
+
this.updateLabel(newValue);
|
77
|
+
}
|
78
|
+
|
79
|
+
// we're don't know the order in which the attributes are forwarded, so we're trying to render every time
|
80
|
+
// once `data` and `active-policies` are populated, the render will be executed.
|
81
|
+
// once the `overrides` object is updated, we want to re-render the panel.
|
82
|
+
if (dataAttrs.includes(attrName)) {
|
83
|
+
if (attrName === 'data') {
|
84
|
+
try {
|
85
|
+
this.availablePolicies = JSON.parse(newValue);
|
86
|
+
} catch {
|
87
|
+
// eslint-disable-next-line no-console
|
88
|
+
console.error('Failed to set available policies');
|
89
|
+
}
|
90
|
+
}
|
91
|
+
if (attrName === 'active-policies') {
|
92
|
+
this.#activePolicies = (newValue || '').split(',');
|
93
|
+
}
|
94
|
+
|
95
|
+
if (attrName === 'data-password-policy-value-minlength') {
|
96
|
+
const ln = Number(newValue);
|
97
|
+
if (!Number.isNaN(ln) && ln > 0) {
|
98
|
+
this.#overrides = { ...this.#overrides, minlength: { value: `${ln}` } };
|
99
|
+
}
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
this.renderItems(this.#availablePolicies, this.#activePolicies, this.#overrides);
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
get availablePolicies() {
|
108
|
+
return this.#availablePolicies || [];
|
109
|
+
}
|
110
|
+
|
111
|
+
set availablePolicies(val) {
|
112
|
+
this.#availablePolicies = val;
|
113
|
+
}
|
114
|
+
|
115
|
+
get value() {
|
116
|
+
return this.getAttribute('value') || '';
|
117
|
+
}
|
118
|
+
|
119
|
+
validate() {
|
120
|
+
let policies = this.#availablePolicies;
|
121
|
+
|
122
|
+
if (this.#overrides) {
|
123
|
+
policies = this.#availablePolicies.map((policy) =>
|
124
|
+
this.#overrides[policy.id] ? { ...policy, data: this.#overrides[policy.id] } : policy
|
125
|
+
);
|
126
|
+
}
|
127
|
+
|
128
|
+
return this.#activePolicies.reduce((results, id) => {
|
129
|
+
const policy = policies.find((p) => p.id === id);
|
130
|
+
|
131
|
+
if (!policy) {
|
132
|
+
return results;
|
133
|
+
}
|
134
|
+
|
135
|
+
const { pattern, message, data } = policy;
|
136
|
+
|
137
|
+
if (!pattern || !message) {
|
138
|
+
return results;
|
139
|
+
}
|
140
|
+
|
141
|
+
const exp = new RegExp(interpolateString(pattern, data));
|
142
|
+
|
143
|
+
const validationResult = {
|
144
|
+
valid: exp.test(this.value),
|
145
|
+
message: interpolateString(message, data),
|
146
|
+
id,
|
147
|
+
};
|
148
|
+
|
149
|
+
results.push(validationResult);
|
150
|
+
|
151
|
+
return results;
|
152
|
+
}, []);
|
153
|
+
}
|
154
|
+
|
155
|
+
get isValid() {
|
156
|
+
return !this.validate().some(({ valid }) => valid === false);
|
157
|
+
}
|
158
|
+
|
159
|
+
getValidationItemTemplate({ valid, message }) {
|
160
|
+
const status = !this.value ? 'none' : valid;
|
161
|
+
return `
|
162
|
+
<li class="item" data-valid="${status}">
|
163
|
+
<span class="message">${message}</span>
|
164
|
+
</li>
|
165
|
+
`;
|
166
|
+
}
|
167
|
+
|
168
|
+
renderItems(availablePolicies, activePolicies) {
|
169
|
+
if (!availablePolicies || !activePolicies.length) {
|
170
|
+
return;
|
171
|
+
}
|
172
|
+
|
173
|
+
this.list.innerHTML = this.validate().map(this.getValidationItemTemplate.bind(this)).join('');
|
174
|
+
}
|
175
|
+
|
176
|
+
updateLabel(val) {
|
177
|
+
if (!val) {
|
178
|
+
this.classList.add('hide-label');
|
179
|
+
this.label.innerHTML = '';
|
180
|
+
} else {
|
181
|
+
this.label.innerHTML = val;
|
182
|
+
this.classList.remove('hide-label');
|
183
|
+
}
|
184
|
+
}
|
185
|
+
}
|
186
|
+
|
187
|
+
const { host, item, symbolDefault, symbolSuccess, symbolError } = {
|
188
|
+
host: { selector: () => ':host > div' },
|
189
|
+
item: { selector: () => '.item' },
|
190
|
+
symbolDefault: { selector: () => '.item[data-valid="none"]::before' },
|
191
|
+
symbolSuccess: { selector: () => '.item[data-valid="true"]::before' },
|
192
|
+
symbolError: { selector: () => '.item[data-valid="false"]::before' },
|
193
|
+
};
|
194
|
+
|
195
|
+
export const PolicyValidationClass = compose(
|
196
|
+
createStyleMixin({ componentNameOverride: getComponentName('input-wrapper') }),
|
197
|
+
createStyleMixin({
|
198
|
+
mappings: {
|
199
|
+
hostDirection: { selector: () => ':host', property: 'direction' },
|
200
|
+
fontSize: {},
|
201
|
+
fontFamily: {},
|
202
|
+
padding: {},
|
203
|
+
borderWidth: { ...host, property: 'border-width' },
|
204
|
+
borderStyle: { ...host, property: 'border-style' },
|
205
|
+
borderColor: { ...host, property: 'border-color' },
|
206
|
+
borderRadius: { ...host, property: 'border-radius' },
|
207
|
+
backgroundColor: { ...host, property: 'background-color' },
|
208
|
+
textColor: { property: 'color' },
|
209
|
+
labelMargin: { ...host, property: 'gap' },
|
210
|
+
itemsSpacing: { ...item, property: 'line-height' },
|
211
|
+
itemSymbolSuccessColor: { ...symbolSuccess, property: 'color' },
|
212
|
+
itemSymbolErrorColor: { ...symbolError, property: 'color' },
|
213
|
+
itemSymbolDefault: { ...symbolDefault, property: 'content' },
|
214
|
+
itemSymbolSuccess: { ...symbolSuccess, property: 'content' },
|
215
|
+
itemSymbolError: { ...symbolError, property: 'content' },
|
216
|
+
},
|
217
|
+
}),
|
218
|
+
draggableMixin,
|
219
|
+
componentNameValidationMixin
|
220
|
+
)(RawPolicyValidation);
|
@@ -7,7 +7,7 @@ import {
|
|
7
7
|
} from '../../../mixins';
|
8
8
|
import { TextClass } from '../../descope-text/TextClass';
|
9
9
|
import { compose } from '../../../helpers';
|
10
|
-
import { forwardAttrs, getComponentName } from '../../../helpers/componentHelpers';
|
10
|
+
import { forwardAttrs, getComponentName, syncAttrs } from '../../../helpers/componentHelpers';
|
11
11
|
import { componentName as descopeInternalComponentName } from './descope-mappings-field-internal/MappingsFieldInternal';
|
12
12
|
|
13
13
|
export const componentName = getComponentName('mappings-field');
|
@@ -64,6 +64,10 @@ const customMixin = (superclass) =>
|
|
64
64
|
],
|
65
65
|
});
|
66
66
|
|
67
|
+
// This is required since when we remove the invalid attribute from the internal mappings field,
|
68
|
+
// we want to reflect the change in the parent component
|
69
|
+
syncAttrs(this, this.inputElement, { includeAttrs: ['invalid'] });
|
70
|
+
|
67
71
|
this.setDefaultValues();
|
68
72
|
}
|
69
73
|
};
|
@@ -74,6 +78,7 @@ const {
|
|
74
78
|
errorMessage,
|
75
79
|
mappingItem,
|
76
80
|
labels,
|
81
|
+
labelsText,
|
77
82
|
valueLabel,
|
78
83
|
attrLabel,
|
79
84
|
separator,
|
@@ -84,6 +89,9 @@ const {
|
|
84
89
|
errorMessage: { selector: '::part(error-message)' },
|
85
90
|
mappingItem: { selector: 'descope-mapping-item::part(wrapper)' },
|
86
91
|
labels: { selector: 'descope-mappings-field-internal [part="labels"] descope-text' },
|
92
|
+
labelsText: {
|
93
|
+
selector: 'descope-mappings-field-internal [part="labels"] descope-text::part(text-wrapper)',
|
94
|
+
},
|
87
95
|
valueLabel: { selector: 'descope-mappings-field-internal [part="labels"] [part="value-label"]' },
|
88
96
|
attrLabel: { selector: 'descope-mappings-field-internal [part="labels"] [part="attr-label"]' },
|
89
97
|
separator: { selector: 'descope-mapping-item::part(separator)' },
|
@@ -99,6 +107,11 @@ export const MappingsFieldClass = compose(
|
|
99
107
|
fontSize: [{}, host, { ...separator, property: 'margin-top' }],
|
100
108
|
fontFamily: [helperText, errorMessage, labels],
|
101
109
|
separatorFontSize: { ...separator, property: 'font-size' },
|
110
|
+
labelsFontSize: { ...labelsText, property: 'font-size' },
|
111
|
+
labelsLineHeight: [
|
112
|
+
{ ...labelsText, property: 'line-height' },
|
113
|
+
{ ...labels, property: 'line-height' },
|
114
|
+
],
|
102
115
|
labelTextColor: { ...labels, property: TextClass.cssVarList.textColor },
|
103
116
|
itemMarginBottom: { ...mappingItem, property: 'margin-bottom' },
|
104
117
|
valueLabelMinWidth: { ...valueLabel, property: 'min-width' },
|
package/src/components/mapping-fields/descope-mappings-field/descope-mapping-item/MappingItem.js
CHANGED
@@ -92,7 +92,7 @@ class MappingItem extends BaseInputClass {
|
|
92
92
|
|
93
93
|
initRemoveButton() {
|
94
94
|
this.removeButton.addEventListener('click', () =>
|
95
|
-
this.dispatchEvent(new CustomEvent('mapping-item-removed'))
|
95
|
+
this.dispatchEvent(new CustomEvent('mapping-item-removed', { bubbles: true, composed: true }))
|
96
96
|
);
|
97
97
|
}
|
98
98
|
|
@@ -66,7 +66,7 @@ class MappingsFieldInternal extends BaseInputClass {
|
|
66
66
|
// before the new item is added and thus returns a wrong result
|
67
67
|
setTimeout(() => {
|
68
68
|
this.setCustomValidity('');
|
69
|
-
newMappingItem.addEventListener('mapping-item-removed', (
|
69
|
+
newMappingItem.addEventListener('mapping-item-removed', () => {
|
70
70
|
// If the removed item was the one that was invalid, we need to reset the invalid indication for the internal
|
71
71
|
if (newMappingItem === this.#errorItem) {
|
72
72
|
this.resetInvalidIndication();
|
@@ -74,8 +74,8 @@ class MappingsFieldInternal extends BaseInputClass {
|
|
74
74
|
}
|
75
75
|
newMappingItem.remove();
|
76
76
|
this.setCustomValidity('');
|
77
|
-
e.stopPropagation();
|
78
77
|
});
|
78
|
+
this.dispatchEvent(new CustomEvent('mapping-item-added', { bubbles: true, composed: true }));
|
79
79
|
if (focusNewItem) {
|
80
80
|
newMappingItem.focus();
|
81
81
|
}
|
@@ -0,0 +1,110 @@
|
|
1
|
+
import {
|
2
|
+
createStyleMixin,
|
3
|
+
draggableMixin,
|
4
|
+
createProxy,
|
5
|
+
proxyInputMixin,
|
6
|
+
componentNameValidationMixin,
|
7
|
+
} from '../../../mixins';
|
8
|
+
import { compose } from '../../../helpers';
|
9
|
+
import { forwardAttrs, getComponentName, syncAttrs } from '../../../helpers/componentHelpers';
|
10
|
+
import { componentName as descopeInternalComponentName } from './descope-saml-group-mappings-internal/SamlGroupMappingsInternal';
|
11
|
+
|
12
|
+
export const componentName = getComponentName('saml-group-mappings');
|
13
|
+
|
14
|
+
const customMixin = (superclass) =>
|
15
|
+
class SamlGroupMappingsMixinClass extends superclass {
|
16
|
+
init() {
|
17
|
+
super.init?.();
|
18
|
+
|
19
|
+
const template = document.createElement('template');
|
20
|
+
|
21
|
+
template.innerHTML = `
|
22
|
+
<${descopeInternalComponentName}
|
23
|
+
tabindex="-1"
|
24
|
+
></${descopeInternalComponentName}>
|
25
|
+
`;
|
26
|
+
|
27
|
+
this.baseElement.appendChild(template.content.cloneNode(true));
|
28
|
+
|
29
|
+
this.inputElement = this.shadowRoot.querySelector(descopeInternalComponentName);
|
30
|
+
|
31
|
+
forwardAttrs(this, this.inputElement, {
|
32
|
+
includeAttrs: [
|
33
|
+
'size',
|
34
|
+
'full-width',
|
35
|
+
'label-group',
|
36
|
+
'label-value',
|
37
|
+
'label-attr',
|
38
|
+
'button-label',
|
39
|
+
'separator',
|
40
|
+
'options',
|
41
|
+
'readonly',
|
42
|
+
'disabled',
|
43
|
+
],
|
44
|
+
});
|
45
|
+
|
46
|
+
syncAttrs(this, this.inputElement, { includeAttrs: ['invalid'] });
|
47
|
+
}
|
48
|
+
};
|
49
|
+
|
50
|
+
const { host, groupInput } = {
|
51
|
+
host: { selector: () => ':host' },
|
52
|
+
groupInput: { selector: 'descope-text-field' },
|
53
|
+
};
|
54
|
+
|
55
|
+
export const SamlGroupMappingsClass = compose(
|
56
|
+
createStyleMixin({
|
57
|
+
mappings: {
|
58
|
+
hostWidth: { ...host, property: 'width' },
|
59
|
+
hostDirection: { ...host, property: 'direction' },
|
60
|
+
groupNameInputMarginBottom: { ...groupInput, property: 'margin-bottom' },
|
61
|
+
},
|
62
|
+
}),
|
63
|
+
draggableMixin,
|
64
|
+
proxyInputMixin({
|
65
|
+
proxyProps: ['value', 'selectionStart'],
|
66
|
+
inputEvent: 'input',
|
67
|
+
triggerValidationEvents: ['mapping-item-added', 'mapping-item-removed'],
|
68
|
+
proxyParentValidation: true,
|
69
|
+
}),
|
70
|
+
componentNameValidationMixin,
|
71
|
+
customMixin
|
72
|
+
)(
|
73
|
+
createProxy({
|
74
|
+
slots: [],
|
75
|
+
wrappedEleName: 'vaadin-custom-field',
|
76
|
+
style: () => `
|
77
|
+
:host {
|
78
|
+
display: inline-flex;
|
79
|
+
max-width: 100%;
|
80
|
+
direction: ltr;
|
81
|
+
}
|
82
|
+
|
83
|
+
vaadin-custom-field {
|
84
|
+
line-height: unset;
|
85
|
+
width: 100%;
|
86
|
+
}
|
87
|
+
|
88
|
+
descope-text-field {
|
89
|
+
width: auto;
|
90
|
+
}
|
91
|
+
|
92
|
+
descope-mappings-field {
|
93
|
+
display: block;
|
94
|
+
}
|
95
|
+
`,
|
96
|
+
excludeAttrsSync: [
|
97
|
+
'tabindex',
|
98
|
+
'label-group',
|
99
|
+
'label-value',
|
100
|
+
'label-attr',
|
101
|
+
'button-label',
|
102
|
+
'separator',
|
103
|
+
'options',
|
104
|
+
'error-message',
|
105
|
+
],
|
106
|
+
componentName,
|
107
|
+
})
|
108
|
+
);
|
109
|
+
|
110
|
+
export default SamlGroupMappingsClass;
|