@descope/web-components-ui 1.0.290 → 1.0.292
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/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;
|