@api-client/ui 0.6.8 → 0.6.10
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/build/src/md/button/internals/group.styles.d.ts.map +1 -1
- package/build/src/md/button/internals/group.styles.js +1 -0
- package/build/src/md/button/internals/group.styles.js.map +1 -1
- package/build/src/modeling/dialogs/CountryTaxonomy.d.ts +24 -0
- package/build/src/modeling/dialogs/CountryTaxonomy.d.ts.map +1 -0
- package/build/src/modeling/dialogs/CountryTaxonomy.js +174 -0
- package/build/src/modeling/dialogs/CountryTaxonomy.js.map +1 -0
- package/build/src/modeling/dialogs/PostalCodeTaxonomy.d.ts +24 -0
- package/build/src/modeling/dialogs/PostalCodeTaxonomy.d.ts.map +1 -0
- package/build/src/modeling/dialogs/PostalCodeTaxonomy.js +167 -0
- package/build/src/modeling/dialogs/PostalCodeTaxonomy.js.map +1 -0
- package/build/src/modeling/domain-template-browser.d.ts.map +1 -1
- package/build/src/modeling/domain-template-browser.js +2 -1
- package/build/src/modeling/domain-template-browser.js.map +1 -1
- package/build/src/modeling/internals/DomainAutoFieldsDialog.d.ts.map +1 -1
- package/build/src/modeling/internals/DomainAutoFieldsDialog.js +30 -0
- package/build/src/modeling/internals/DomainAutoFieldsDialog.js.map +1 -1
- package/build/src/modeling/internals/DomainPropertyEditor.d.ts.map +1 -1
- package/build/src/modeling/internals/DomainPropertyEditor.js +8 -0
- package/build/src/modeling/internals/DomainPropertyEditor.js.map +1 -1
- package/build/src/modeling/internals/DomainTemplateBrowser.d.ts +10 -6
- package/build/src/modeling/internals/DomainTemplateBrowser.d.ts.map +1 -1
- package/build/src/modeling/internals/DomainTemplateBrowser.js +75 -8
- package/build/src/modeling/internals/DomainTemplateBrowser.js.map +1 -1
- package/build/src/modeling/internals/styles/DomainTemplateBrowser.styles.d.ts.map +1 -1
- package/build/src/modeling/internals/styles/DomainTemplateBrowser.styles.js +12 -0
- package/build/src/modeling/internals/styles/DomainTemplateBrowser.styles.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/src/md/button/internals/group.styles.ts +1 -0
- package/src/modeling/dialogs/CountryTaxonomy.ts +176 -0
- package/src/modeling/dialogs/PostalCodeTaxonomy.ts +169 -0
- package/src/modeling/domain-template-browser.ts +2 -1
- package/src/modeling/internals/DomainAutoFieldsDialog.ts +30 -0
- package/src/modeling/internals/DomainPropertyEditor.ts +6 -0
- package/src/modeling/internals/DomainTemplateBrowser.ts +87 -18
- package/src/modeling/internals/styles/DomainTemplateBrowser.styles.ts +12 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@api-client/ui",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.10",
|
|
4
4
|
"description": "Internal UI component library for the API Client ecosystem.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"main": "build/src/index.js",
|
|
@@ -195,6 +195,7 @@
|
|
|
195
195
|
"dependencies": {
|
|
196
196
|
"@adonisjs/transmit-client": "^1.0.0",
|
|
197
197
|
"@api-client/core": "^0.18.0",
|
|
198
|
+
"@api-client/domain-templates": "^0.1.2",
|
|
198
199
|
"@api-client/graph": "^0.3.6",
|
|
199
200
|
"@api-client/json": "^0.2.0",
|
|
200
201
|
"@codemirror/autocomplete": "^6.18.6",
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import type { DomainProperty } from '@api-client/core/modeling/DomainProperty.js'
|
|
2
|
+
import { type CountryConfig, DEFAULT_COUNTRY_CONFIG } from '@api-client/core/modeling/definitions/Country.js'
|
|
3
|
+
import { bound } from '../../decorators/bound.js'
|
|
4
|
+
import { html, TemplateResult } from 'lit'
|
|
5
|
+
import { SemanticType } from '@api-client/core/modeling/Semantics.js'
|
|
6
|
+
import { renderHelp } from '../../help/render.js'
|
|
7
|
+
import { TaxonomyDialog } from './TaxonomyDialog.js'
|
|
8
|
+
|
|
9
|
+
import '../../md/chip/ui-chip-set.js'
|
|
10
|
+
import '../../md/chip/ui-chip.js'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A class that generates a dialog that allows the user to configure the taxonomy of a Country annotated association.
|
|
14
|
+
*/
|
|
15
|
+
export class CountryTaxonomy extends TaxonomyDialog<CountryConfig> {
|
|
16
|
+
static override title = `Configure Country Taxonomy`
|
|
17
|
+
|
|
18
|
+
constructor(public domainElement: DomainProperty) {
|
|
19
|
+
let config: CountryConfig
|
|
20
|
+
const semantic = domainElement.semantics.find((s) => s.id === SemanticType.Country)
|
|
21
|
+
if (semantic && semantic.config) {
|
|
22
|
+
config = structuredClone(semantic.config)
|
|
23
|
+
} else {
|
|
24
|
+
config = {}
|
|
25
|
+
}
|
|
26
|
+
super(config)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
protected override formCallback(event: Event): Promise<void> {
|
|
30
|
+
const semantic = this.domainElement.semantics.find((s) => s.id === SemanticType.Country)
|
|
31
|
+
if (semantic) {
|
|
32
|
+
semantic.config = this.config
|
|
33
|
+
} else {
|
|
34
|
+
this.domainElement.semantics.push({
|
|
35
|
+
id: SemanticType.Country,
|
|
36
|
+
config: this.config,
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
this.domainElement.domain.notifyChange()
|
|
40
|
+
return super.formCallback(event)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
protected handleAllowedCountriesChange(event: Event): void {
|
|
44
|
+
const input = event.target as HTMLInputElement
|
|
45
|
+
const value = input.value.trim()
|
|
46
|
+
if (value) {
|
|
47
|
+
const countries = this.config?.allowedCountries ?? DEFAULT_COUNTRY_CONFIG.allowedCountries ?? []
|
|
48
|
+
if (!countries.includes(value)) {
|
|
49
|
+
countries.push(value)
|
|
50
|
+
this.config = { ...this.config, allowedCountries: countries }
|
|
51
|
+
this.requestUpdate()
|
|
52
|
+
}
|
|
53
|
+
input.value = ''
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected handleRemoveAllowedCountry(event: Event): void {
|
|
58
|
+
const chip = event.currentTarget as HTMLElement
|
|
59
|
+
const index = parseInt(chip.dataset.index || '-1', 10)
|
|
60
|
+
if (index >= 0 && this.config?.allowedCountries) {
|
|
61
|
+
this.config.allowedCountries.splice(index, 1)
|
|
62
|
+
this.requestUpdate()
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
protected handleDisallowedCountriesChange(event: Event): void {
|
|
67
|
+
const input = event.target as HTMLInputElement
|
|
68
|
+
const value = input.value.trim()
|
|
69
|
+
if (value) {
|
|
70
|
+
const countries = this.config?.disallowedCountries ?? DEFAULT_COUNTRY_CONFIG.disallowedCountries ?? []
|
|
71
|
+
if (!countries.includes(value)) {
|
|
72
|
+
countries.push(value)
|
|
73
|
+
this.config = { ...this.config, disallowedCountries: countries }
|
|
74
|
+
this.requestUpdate()
|
|
75
|
+
}
|
|
76
|
+
input.value = ''
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
protected handleRemoveDisallowedCountry(event: Event): void {
|
|
81
|
+
const chip = event.currentTarget as HTMLElement
|
|
82
|
+
const index = parseInt(chip.dataset.index || '-1', 10)
|
|
83
|
+
if (index >= 0 && this.config?.disallowedCountries) {
|
|
84
|
+
this.config.disallowedCountries.splice(index, 1)
|
|
85
|
+
this.requestUpdate()
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@bound
|
|
90
|
+
render(): TemplateResult {
|
|
91
|
+
return html`
|
|
92
|
+
<div class="input-group">
|
|
93
|
+
${this.renderFormatSelect()} ${this.renderAllowedCountries()} ${this.renderDisallowedCountries()}
|
|
94
|
+
</div>
|
|
95
|
+
`
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
protected renderFormatSelect(): TemplateResult {
|
|
99
|
+
const value = this.config?.format ?? DEFAULT_COUNTRY_CONFIG.format
|
|
100
|
+
return html`
|
|
101
|
+
<div class="row">
|
|
102
|
+
<ui-select
|
|
103
|
+
label="Country format"
|
|
104
|
+
class="input"
|
|
105
|
+
name="format"
|
|
106
|
+
.value="${value as string}"
|
|
107
|
+
@change="${this.handleSelectChange}"
|
|
108
|
+
>
|
|
109
|
+
<ui-option value="ISO_3166_Alpha_2">
|
|
110
|
+
<div>ISO 3166 Alpha-2 (Recommended)</div>
|
|
111
|
+
<div slot="supporting-text">Store as ISO 3166 Alpha-2 (e.g., US)</div>
|
|
112
|
+
</ui-option>
|
|
113
|
+
<ui-option value="ISO_3166_Alpha_3">
|
|
114
|
+
<div>ISO 3166 Alpha-3</div>
|
|
115
|
+
<div slot="supporting-text">Store as ISO 3166 Alpha-3 (e.g., USA)</div>
|
|
116
|
+
</ui-option>
|
|
117
|
+
<ui-option value="Name">
|
|
118
|
+
<div>Name</div>
|
|
119
|
+
<div slot="supporting-text">Store as country name (e.g., United States)</div>
|
|
120
|
+
</ui-option>
|
|
121
|
+
</ui-select>
|
|
122
|
+
${renderHelp('taxonomy', 'country:format')}
|
|
123
|
+
</div>
|
|
124
|
+
`
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
protected renderAllowedCountries(): TemplateResult {
|
|
128
|
+
const value = this.config?.allowedCountries ?? DEFAULT_COUNTRY_CONFIG.allowedCountries
|
|
129
|
+
const chips = (value || []).map(
|
|
130
|
+
(country, index) =>
|
|
131
|
+
html`<ui-chip type="input" removable data-index="${index}" @remove="${this.handleRemoveAllowedCountry}"
|
|
132
|
+
>${country}</ui-chip
|
|
133
|
+
>`
|
|
134
|
+
)
|
|
135
|
+
return html`
|
|
136
|
+
<div class="row input-row">
|
|
137
|
+
<div class="input chips-input">
|
|
138
|
+
<ui-outlined-text-field
|
|
139
|
+
class="input"
|
|
140
|
+
name="allowedCountries"
|
|
141
|
+
label="Allowed Countries"
|
|
142
|
+
@change="${this.handleAllowedCountriesChange}"
|
|
143
|
+
supportingText="Add a country and press Enter to add it to the list. Use the selected format."
|
|
144
|
+
></ui-outlined-text-field>
|
|
145
|
+
<ui-chip-set>${chips}</ui-chip-set>
|
|
146
|
+
</div>
|
|
147
|
+
${renderHelp('taxonomy', 'country:allowedCountries')}
|
|
148
|
+
</div>
|
|
149
|
+
`
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
protected renderDisallowedCountries(): TemplateResult {
|
|
153
|
+
const value = this.config?.disallowedCountries ?? DEFAULT_COUNTRY_CONFIG.disallowedCountries
|
|
154
|
+
const chips = (value || []).map(
|
|
155
|
+
(country, index) =>
|
|
156
|
+
html`<ui-chip type="input" removable data-index="${index}" @remove="${this.handleRemoveDisallowedCountry}"
|
|
157
|
+
>${country}</ui-chip
|
|
158
|
+
>`
|
|
159
|
+
)
|
|
160
|
+
return html`
|
|
161
|
+
<div class="row input-row">
|
|
162
|
+
<div class="input chips-input">
|
|
163
|
+
<ui-outlined-text-field
|
|
164
|
+
class="input"
|
|
165
|
+
name="disallowedCountries"
|
|
166
|
+
label="Disallowed Countries"
|
|
167
|
+
@change="${this.handleDisallowedCountriesChange}"
|
|
168
|
+
supportingText="Add a country and press Enter to add it to the list. Use the selected format."
|
|
169
|
+
></ui-outlined-text-field>
|
|
170
|
+
<ui-chip-set>${chips}</ui-chip-set>
|
|
171
|
+
</div>
|
|
172
|
+
${renderHelp('taxonomy', 'country:disallowedCountries')}
|
|
173
|
+
</div>
|
|
174
|
+
`
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import type { DomainProperty } from '@api-client/core/modeling/DomainProperty.js'
|
|
2
|
+
import { type PostalCodeConfig, DEFAULT_POSTAL_CODE_CONFIG } from '@api-client/core/modeling/definitions/PostalCode.js'
|
|
3
|
+
import { bound } from '../../decorators/bound.js'
|
|
4
|
+
import { html, TemplateResult } from 'lit'
|
|
5
|
+
import { SemanticType } from '@api-client/core/modeling/Semantics.js'
|
|
6
|
+
import { renderHelp } from '../../help/render.js'
|
|
7
|
+
import { TaxonomyDialog } from './TaxonomyDialog.js'
|
|
8
|
+
|
|
9
|
+
import '../../md/chip/ui-chip-set.js'
|
|
10
|
+
import '../../md/chip/ui-chip.js'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A class that generates a dialog that allows the user to configure the taxonomy of a PostalCode annotated association.
|
|
14
|
+
*/
|
|
15
|
+
export class PostalCodeTaxonomy extends TaxonomyDialog<PostalCodeConfig> {
|
|
16
|
+
static override title = `Configure Postal Code Taxonomy`
|
|
17
|
+
|
|
18
|
+
constructor(public domainElement: DomainProperty) {
|
|
19
|
+
let config: PostalCodeConfig
|
|
20
|
+
const semantic = domainElement.semantics.find((s) => s.id === SemanticType.PostalCode)
|
|
21
|
+
if (semantic && semantic.config) {
|
|
22
|
+
config = structuredClone(semantic.config)
|
|
23
|
+
} else {
|
|
24
|
+
config = {}
|
|
25
|
+
}
|
|
26
|
+
super(config)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
protected override formCallback(event: Event): Promise<void> {
|
|
30
|
+
const semantic = this.domainElement.semantics.find((s) => s.id === SemanticType.PostalCode)
|
|
31
|
+
if (semantic) {
|
|
32
|
+
semantic.config = this.config
|
|
33
|
+
} else {
|
|
34
|
+
this.domainElement.semantics.push({
|
|
35
|
+
id: SemanticType.PostalCode,
|
|
36
|
+
config: this.config,
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
this.domainElement.domain.notifyChange()
|
|
40
|
+
return super.formCallback(event)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
protected handleAllowedPostalCodesChange(event: Event): void {
|
|
44
|
+
const input = event.target as HTMLInputElement
|
|
45
|
+
const value = input.value.trim()
|
|
46
|
+
if (value) {
|
|
47
|
+
const postalCodes = this.config?.allowedPostalCodes ?? DEFAULT_POSTAL_CODE_CONFIG.allowedPostalCodes ?? []
|
|
48
|
+
if (!postalCodes.includes(value)) {
|
|
49
|
+
postalCodes.push(value)
|
|
50
|
+
this.config = { ...this.config, allowedPostalCodes: postalCodes }
|
|
51
|
+
this.requestUpdate()
|
|
52
|
+
}
|
|
53
|
+
input.value = ''
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected handleRemovePostalCode(event: Event): void {
|
|
58
|
+
const chip = event.currentTarget as HTMLElement
|
|
59
|
+
const index = parseInt(chip.dataset.index || '-1', 10)
|
|
60
|
+
if (index >= 0 && this.config?.allowedPostalCodes) {
|
|
61
|
+
this.config.allowedPostalCodes.splice(index, 1)
|
|
62
|
+
this.requestUpdate()
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
protected handleDisallowedPostalCodesChange(event: Event): void {
|
|
67
|
+
const input = event.target as HTMLInputElement
|
|
68
|
+
const value = input.value.trim()
|
|
69
|
+
if (value) {
|
|
70
|
+
const postalCodes = this.config?.disallowedPostalCodes ?? DEFAULT_POSTAL_CODE_CONFIG.disallowedPostalCodes ?? []
|
|
71
|
+
if (!postalCodes.includes(value)) {
|
|
72
|
+
postalCodes.push(value)
|
|
73
|
+
this.config = { ...this.config, disallowedPostalCodes: postalCodes }
|
|
74
|
+
this.requestUpdate()
|
|
75
|
+
}
|
|
76
|
+
input.value = ''
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
protected handleRemoveDisallowedPostalCode(event: Event): void {
|
|
81
|
+
const chip = event.currentTarget as HTMLElement
|
|
82
|
+
const index = parseInt(chip.dataset.index || '-1', 10)
|
|
83
|
+
if (index >= 0 && this.config?.disallowedPostalCodes) {
|
|
84
|
+
this.config.disallowedPostalCodes.splice(index, 1)
|
|
85
|
+
this.requestUpdate()
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@bound
|
|
90
|
+
render(): TemplateResult {
|
|
91
|
+
return html`
|
|
92
|
+
<div class="checkbox-group">${this.renderValidate()}</div>
|
|
93
|
+
<div class="input-group">${this.renderAllowedPostalCodes()} ${this.renderDisallowedPostalCodes()}</div>
|
|
94
|
+
`
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
protected renderValidate(): TemplateResult {
|
|
98
|
+
const enabled = this.config?.validate ?? DEFAULT_POSTAL_CODE_CONFIG.validate
|
|
99
|
+
return html`
|
|
100
|
+
<div class="row">
|
|
101
|
+
<div class="input checkbox metadata">
|
|
102
|
+
<ui-checkbox
|
|
103
|
+
id="validate"
|
|
104
|
+
.checked="${enabled}"
|
|
105
|
+
name="validate"
|
|
106
|
+
@change="${this.handleBooleanChange}"
|
|
107
|
+
></ui-checkbox>
|
|
108
|
+
<div class="label">
|
|
109
|
+
<label for="validate" class="body-medium">Validate</label>
|
|
110
|
+
<span class="body-small meta"
|
|
111
|
+
>Enable strict validation of the postal code. This is an experimental feature.</span
|
|
112
|
+
>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
${renderHelp('taxonomy', 'postalCode:validate')}
|
|
116
|
+
</div>
|
|
117
|
+
`
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
protected renderAllowedPostalCodes(): TemplateResult {
|
|
121
|
+
const value = this.config?.allowedPostalCodes ?? DEFAULT_POSTAL_CODE_CONFIG.allowedPostalCodes
|
|
122
|
+
const chips = (value || []).map(
|
|
123
|
+
(postalCode, index) =>
|
|
124
|
+
html`<ui-chip type="input" removable data-index="${index}" @remove="${this.handleRemovePostalCode}"
|
|
125
|
+
>${postalCode}</ui-chip
|
|
126
|
+
>`
|
|
127
|
+
)
|
|
128
|
+
return html`
|
|
129
|
+
<div class="row input-row">
|
|
130
|
+
<div class="input chips-input">
|
|
131
|
+
<ui-outlined-text-field
|
|
132
|
+
class="input"
|
|
133
|
+
name="allowedPostalCodes"
|
|
134
|
+
label="Allowed Postal Codes"
|
|
135
|
+
@change="${this.handleAllowedPostalCodesChange}"
|
|
136
|
+
supportingText="Add a postal code and press Enter to add it to the list."
|
|
137
|
+
></ui-outlined-text-field>
|
|
138
|
+
<ui-chip-set>${chips}</ui-chip-set>
|
|
139
|
+
</div>
|
|
140
|
+
${renderHelp('taxonomy', 'postalCode:allowedPostalCodes')}
|
|
141
|
+
</div>
|
|
142
|
+
`
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
protected renderDisallowedPostalCodes(): TemplateResult {
|
|
146
|
+
const value = this.config?.disallowedPostalCodes ?? DEFAULT_POSTAL_CODE_CONFIG.disallowedPostalCodes
|
|
147
|
+
const chips = (value || []).map(
|
|
148
|
+
(postalCode, index) =>
|
|
149
|
+
html`<ui-chip type="input" removable data-index="${index}" @remove="${this.handleRemoveDisallowedPostalCode}"
|
|
150
|
+
>${postalCode}</ui-chip
|
|
151
|
+
>`
|
|
152
|
+
)
|
|
153
|
+
return html`
|
|
154
|
+
<div class="row input-row">
|
|
155
|
+
<div class="input chips-input">
|
|
156
|
+
<ui-outlined-text-field
|
|
157
|
+
class="input"
|
|
158
|
+
name="disallowedPostalCodes"
|
|
159
|
+
label="Disallowed Postal Codes"
|
|
160
|
+
@change="${this.handleDisallowedPostalCodesChange}"
|
|
161
|
+
supportingText="Add a postal code and press Enter to add it to the list."
|
|
162
|
+
></ui-outlined-text-field>
|
|
163
|
+
<ui-chip-set>${chips}</ui-chip-set>
|
|
164
|
+
</div>
|
|
165
|
+
${renderHelp('taxonomy', 'postalCode:disallowedPostalCodes')}
|
|
166
|
+
</div>
|
|
167
|
+
`
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { customElement } from 'lit/decorators.js'
|
|
2
2
|
import Element from './internals/DomainTemplateBrowser.js'
|
|
3
3
|
import styles from './internals/styles/DomainTemplateBrowser.styles.js'
|
|
4
|
+
import typography from '../styles/m3/typography.module.js'
|
|
4
5
|
|
|
5
6
|
import '../md/button/ui-button.js'
|
|
6
7
|
import '../md/button/ui-button-group.js'
|
|
@@ -9,7 +10,7 @@ import '../md/text-field/ui-outlined-text-field.js'
|
|
|
9
10
|
|
|
10
11
|
@customElement('domain-template-browser')
|
|
11
12
|
export class DomainTemplateBrowserElement extends Element {
|
|
12
|
-
static override styles = [styles]
|
|
13
|
+
static override styles = [styles, typography]
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
declare global {
|
|
@@ -86,6 +86,36 @@ export default class DomainAutoFieldsDialog extends LitElement {
|
|
|
86
86
|
},
|
|
87
87
|
],
|
|
88
88
|
},
|
|
89
|
+
{
|
|
90
|
+
name: 'Contact & Address',
|
|
91
|
+
fields: [
|
|
92
|
+
{
|
|
93
|
+
id: 'street-address',
|
|
94
|
+
name: 'Street Address',
|
|
95
|
+
description: 'The street address.',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
id: 'city',
|
|
99
|
+
name: 'City',
|
|
100
|
+
description: 'The city.',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: 'region',
|
|
104
|
+
name: 'Region',
|
|
105
|
+
description: 'The region/state/province.',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
id: 'postal-code',
|
|
109
|
+
name: 'Postal/Zip Code',
|
|
110
|
+
description: 'The international postal/zip code.',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: 'country',
|
|
114
|
+
name: 'Country',
|
|
115
|
+
description: 'The country.',
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
},
|
|
89
119
|
{
|
|
90
120
|
name: 'Lifecycle & Status',
|
|
91
121
|
fields: [
|
|
@@ -30,6 +30,8 @@ import { UrlTaxonomy } from '../dialogs/UrlTaxonomy.js'
|
|
|
30
30
|
import { PublicUniqueNameTaxonomy } from '../dialogs/PublicUniqueNameTaxonomy.js'
|
|
31
31
|
import { GeospatialCoordinatesTaxonomy } from '../dialogs/GeospatialCoordinatesTaxonomy.js'
|
|
32
32
|
import { CalculatedTaxonomy } from '../dialogs/CalculatedTaxonomy.js'
|
|
33
|
+
import { PostalCodeTaxonomy } from '../dialogs/PostalCodeTaxonomy.js'
|
|
34
|
+
import { CountryTaxonomy } from '../dialogs/CountryTaxonomy.js'
|
|
33
35
|
import type { UiSelectElement } from '../../md/select/ui-select.js'
|
|
34
36
|
|
|
35
37
|
/**
|
|
@@ -658,6 +660,10 @@ export default class DomainPropertyEditor extends ModelingElement {
|
|
|
658
660
|
dialog = new GeospatialCoordinatesTaxonomy(element)
|
|
659
661
|
} else if (id === SemanticType.Calculated) {
|
|
660
662
|
dialog = new CalculatedTaxonomy(element)
|
|
663
|
+
} else if (id === SemanticType.PostalCode) {
|
|
664
|
+
dialog = new PostalCodeTaxonomy(element)
|
|
665
|
+
} else if (id === SemanticType.Country) {
|
|
666
|
+
dialog = new CountryTaxonomy(element)
|
|
661
667
|
} else {
|
|
662
668
|
throw new TypeError(`Unsupported taxonomy type: ${id}.`)
|
|
663
669
|
}
|
|
@@ -1,22 +1,50 @@
|
|
|
1
|
+
/* eslint-disable max-len */
|
|
1
2
|
import { html, type TemplateResult, LitElement } from 'lit'
|
|
2
3
|
import { state, property } from 'lit/decorators.js'
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
import type { IconType } from '../../md/icons/Icons.js'
|
|
5
|
+
// Template metadata imports
|
|
6
|
+
import ecommercePlatformMetadata from '@api-client/domain-templates/meta/ecommerce-platform.json' with { type: 'json' }
|
|
7
|
+
import blogPublishingPlatformMetadata from '@api-client/domain-templates/meta/blog-publishing-platform.json' with { type: 'json' }
|
|
8
|
+
import healthcareManagementPlatformMetadata from '@api-client/domain-templates/meta/healthcare-management-platform.json' with { type: 'json' }
|
|
9
|
+
import financialServicesPlatformMetadata from '@api-client/domain-templates/meta/financial-services-platform.json' with { type: 'json' }
|
|
10
|
+
import educationManagementPlatformMetadata from '@api-client/domain-templates/meta/education-management-platform.json' with { type: 'json' }
|
|
11
|
+
import realEstateManagementPlatformMetadata from '@api-client/domain-templates/meta/real-estate-management-platform.json' with { type: 'json' }
|
|
12
|
+
import manufacturingPlatformMetadata from '@api-client/domain-templates/meta/manufacturing-platform.json' with { type: 'json' }
|
|
13
|
+
import hospitalityPlatformMetadata from '@api-client/domain-templates/meta/hospitality-platform.json' with { type: 'json' }
|
|
14
|
+
import legalServicesPlatformMetadata from '@api-client/domain-templates/meta/legal-services-platform.json' with { type: 'json' }
|
|
15
|
+
import nonProfitPlatformMetadata from '@api-client/domain-templates/meta/non-profit-platform.json' with { type: 'json' }
|
|
16
|
+
import iotSmartHomePlatformMetadata from '@api-client/domain-templates/meta/iot-smart-home-platform.json' with { type: 'json' }
|
|
17
|
+
import gamingPlatformMetadata from '@api-client/domain-templates/meta/gaming-platform.json' with { type: 'json' }
|
|
18
|
+
import { templatesByVertical } from '@api-client/domain-templates'
|
|
9
19
|
import type {
|
|
10
20
|
AssociationInfo,
|
|
11
21
|
DomainTemplate,
|
|
22
|
+
DomainTemplateMetadata,
|
|
12
23
|
EntityInfo,
|
|
13
24
|
ModelInfo,
|
|
14
25
|
NamespaceInfo,
|
|
15
26
|
PropertyInfo,
|
|
16
|
-
} from '@api-client/
|
|
17
|
-
import type { IconType } from '../../md/icons/Icons.js'
|
|
27
|
+
} from '@api-client/domain-templates/types.js'
|
|
18
28
|
|
|
19
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Registry of all available template metadata
|
|
31
|
+
*/
|
|
32
|
+
export const TEMPLATE_METADATA_REGISTRY: Record<string, DomainTemplate> = {
|
|
33
|
+
'ecommerce-platform': ecommercePlatformMetadata as DomainTemplate,
|
|
34
|
+
'blog-publishing-platform': blogPublishingPlatformMetadata as DomainTemplate,
|
|
35
|
+
'healthcare-management-platform': healthcareManagementPlatformMetadata as DomainTemplate,
|
|
36
|
+
'financial-services-platform': financialServicesPlatformMetadata as DomainTemplate,
|
|
37
|
+
'education-management-platform': educationManagementPlatformMetadata as DomainTemplate,
|
|
38
|
+
'real-estate-management-platform': realEstateManagementPlatformMetadata as DomainTemplate,
|
|
39
|
+
'manufacturing-platform': manufacturingPlatformMetadata as DomainTemplate,
|
|
40
|
+
'hospitality-platform': hospitalityPlatformMetadata as DomainTemplate,
|
|
41
|
+
'legal-services-platform': legalServicesPlatformMetadata as DomainTemplate,
|
|
42
|
+
'non-profit-platform': nonProfitPlatformMetadata as DomainTemplate,
|
|
43
|
+
'iot-smart-home-platform': iotSmartHomePlatformMetadata as DomainTemplate,
|
|
44
|
+
'gaming-platform': gamingPlatformMetadata as DomainTemplate,
|
|
45
|
+
} as const
|
|
46
|
+
|
|
47
|
+
export const availableCategories = Object.keys(templatesByVertical) as (keyof typeof templatesByVertical)[]
|
|
20
48
|
|
|
21
49
|
/**
|
|
22
50
|
* The selection detail object dispatched by the `selectionchange` event.
|
|
@@ -54,6 +82,39 @@ export function getPropertyIcon(p: PropertyInfo): IconType {
|
|
|
54
82
|
}
|
|
55
83
|
}
|
|
56
84
|
|
|
85
|
+
function searchTemplates(query: string): DomainTemplateMetadata[] {
|
|
86
|
+
const searchTerm = query.toLowerCase()
|
|
87
|
+
return Object.values(templatesByVertical)
|
|
88
|
+
.flat()
|
|
89
|
+
.filter(
|
|
90
|
+
(template) =>
|
|
91
|
+
template.name.toLowerCase().includes(searchTerm) ||
|
|
92
|
+
template.description.toLowerCase().includes(searchTerm) ||
|
|
93
|
+
template.tags.some((tag) => tag.toLowerCase().includes(searchTerm))
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function getVerticalName(id: string): string {
|
|
98
|
+
switch (id) {
|
|
99
|
+
case 'businessServices':
|
|
100
|
+
return 'Business Services'
|
|
101
|
+
case 'educationTraining':
|
|
102
|
+
return 'Education & Training'
|
|
103
|
+
case 'healthcareLifeSciences':
|
|
104
|
+
return 'Healthcare & Life Sciences'
|
|
105
|
+
case 'manufacturingLogistics':
|
|
106
|
+
return 'Manufacturing & Logistics'
|
|
107
|
+
case 'publicSector':
|
|
108
|
+
return 'Public Sector'
|
|
109
|
+
case 'realEstateConstruction':
|
|
110
|
+
return 'Real Estate & Construction'
|
|
111
|
+
case 'technologyMedia':
|
|
112
|
+
return 'Technology & Media'
|
|
113
|
+
default:
|
|
114
|
+
return id
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
57
118
|
/**
|
|
58
119
|
* A browser component for exploring and selecting domain templates.
|
|
59
120
|
* It provides the UI for searching, filtering, previewing, and selecting data domain templates.
|
|
@@ -76,13 +137,13 @@ export default class DomainTemplateBrowser extends LitElement {
|
|
|
76
137
|
* If not set, all categories are included.
|
|
77
138
|
* @attribute
|
|
78
139
|
*/
|
|
79
|
-
@property({ type: String }) accessor category: keyof typeof
|
|
140
|
+
@property({ type: String }) accessor category: keyof typeof templatesByVertical | undefined
|
|
80
141
|
|
|
81
142
|
/**
|
|
82
143
|
* The internal list of filtered templates to render in the UI.
|
|
83
144
|
* This is computed based on `query` and `category`.
|
|
84
145
|
*/
|
|
85
|
-
@state() accessor templates:
|
|
146
|
+
@state() accessor templates: DomainTemplateMetadata[] = [...Object.values(templatesByVertical)].flat()
|
|
86
147
|
|
|
87
148
|
/**
|
|
88
149
|
* The currently previewed template. When set, the component renders the preview view instead of the list.
|
|
@@ -115,7 +176,7 @@ export default class DomainTemplateBrowser extends LitElement {
|
|
|
115
176
|
search(value?: string): void {
|
|
116
177
|
this.query = value
|
|
117
178
|
if (!value) {
|
|
118
|
-
this.templates = [...Object.values(
|
|
179
|
+
this.templates = [...Object.values(templatesByVertical)].flat()
|
|
119
180
|
} else {
|
|
120
181
|
this.templates = searchTemplates(value)
|
|
121
182
|
}
|
|
@@ -130,10 +191,10 @@ export default class DomainTemplateBrowser extends LitElement {
|
|
|
130
191
|
}
|
|
131
192
|
if (value === '') {
|
|
132
193
|
this.category = undefined
|
|
133
|
-
this.templates = [...Object.values(
|
|
194
|
+
this.templates = [...Object.values(templatesByVertical)].flat()
|
|
134
195
|
} else {
|
|
135
|
-
this.category = value as keyof typeof
|
|
136
|
-
this.templates =
|
|
196
|
+
this.category = value as keyof typeof templatesByVertical
|
|
197
|
+
this.templates = templatesByVertical[this.category].flat()
|
|
137
198
|
}
|
|
138
199
|
}
|
|
139
200
|
|
|
@@ -157,7 +218,11 @@ export default class DomainTemplateBrowser extends LitElement {
|
|
|
157
218
|
if (!templateId) {
|
|
158
219
|
return
|
|
159
220
|
}
|
|
160
|
-
|
|
221
|
+
const value = TEMPLATE_METADATA_REGISTRY[templateId]
|
|
222
|
+
if (!value) {
|
|
223
|
+
return
|
|
224
|
+
}
|
|
225
|
+
this.previewTemplate = value
|
|
161
226
|
}
|
|
162
227
|
|
|
163
228
|
protected handleClosePreview(): void {
|
|
@@ -222,7 +287,7 @@ export default class DomainTemplateBrowser extends LitElement {
|
|
|
222
287
|
?selected="${isSelected}"
|
|
223
288
|
@click="${this.handleFilterClick}"
|
|
224
289
|
>
|
|
225
|
-
${category}
|
|
290
|
+
${getVerticalName(category)}
|
|
226
291
|
</ui-button>`
|
|
227
292
|
})}
|
|
228
293
|
</ui-button-group>
|
|
@@ -236,13 +301,17 @@ export default class DomainTemplateBrowser extends LitElement {
|
|
|
236
301
|
`
|
|
237
302
|
}
|
|
238
303
|
|
|
239
|
-
protected renderTemplateCard(template:
|
|
304
|
+
protected renderTemplateCard(template: DomainTemplateMetadata): TemplateResult {
|
|
240
305
|
// Use available properties from DomainTemplate interface
|
|
241
306
|
const templateName = template.name || 'Unnamed Template'
|
|
242
307
|
const templateDescription = template.description || 'No description available'
|
|
243
308
|
|
|
244
309
|
return html`
|
|
245
310
|
<div class="template-card">
|
|
311
|
+
<div class="meta">
|
|
312
|
+
<span class="value body-small" title="Updated at">${new Date(template.updatedAt).toLocaleDateString()}</span>
|
|
313
|
+
<span class="value body-small" title="Version">v${template.version}</span>
|
|
314
|
+
</div>
|
|
246
315
|
<h3 class="template-title display-small">${templateName}</h3>
|
|
247
316
|
<p class="template-description body-medium">${templateDescription}</p>
|
|
248
317
|
|
|
@@ -71,6 +71,18 @@ export default css`
|
|
|
71
71
|
color: var(--md-sys-color-on-surface);
|
|
72
72
|
border: 1px solid var(--md-sys-color-outline-variant);
|
|
73
73
|
border-radius: var(--md-sys-shape-corner-medium);
|
|
74
|
+
|
|
75
|
+
.meta {
|
|
76
|
+
display: flex;
|
|
77
|
+
gap: 8px;
|
|
78
|
+
|
|
79
|
+
.value {
|
|
80
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
81
|
+
border: 1px var(--md-sys-color-outline-variant) solid;
|
|
82
|
+
border-radius: 8px;
|
|
83
|
+
padding: 0 4px;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
74
86
|
}
|
|
75
87
|
|
|
76
88
|
.template-description {
|