-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathembed-customizations.html
More file actions
549 lines (536 loc) · 17 KB
/
embed-customizations.html
File metadata and controls
549 lines (536 loc) · 17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Data Contract Editor - Customization Example</title>
<link rel="stylesheet" href="./dist/datacontract-editor.css">
<style>
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
}
html, body {
height: 100%;
}
#editor {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="editor"></div>
<script type="module">
import { init } from './dist/datacontract-editor.es.js';
// Sample customizations configuration demonstrating all features
const customizations = {
dataContract: {
// Root level customizations
root: {
standardProperties: [
// Hide tenant field
{ property: 'tenant', hidden: true },
// Customize status with fixed enum
{
property: 'status',
title: 'Contract Status',
description: 'Current lifecycle stage of this contract',
enum: ['draft', 'review', 'approved', 'active', 'deprecated']
},
// Customize domain with enum
{
property: 'domain',
title: 'Business Domain',
enum: [{
value: "finance",
label: "Finance",
},
{
value: "operations",
label: "Operations",
}]
},
// Pattern on name
{
property: 'name',
title: 'Contract Name',
pattern: '^[A-Z][a-zA-Z0-9 ]*$',
patternMessage: 'Must start with uppercase letter, only letters/numbers/spaces allowed.',
minLength: 3,
maxLength: 80,
placeholder: 'My Data Contract'
},
// Pattern on id
{
property: 'id',
pattern: '^[a-z][a-z0-9-]*$',
patternMessage: 'Must be lowercase kebab-case (e.g., my-contract-id).',
required: true
},
// Version pattern
{
property: 'version',
pattern: '^\\d+\\.\\d+\\.\\d+$',
patternMessage: 'Must follow semver format: X.Y.Z'
}
],
customProperties: [
{
property: 'dataOwner',
title: 'Data Owner',
type: 'text',
description: 'Person responsible for the data',
required: true,
placeholder: 'john.doe@company.com'
},
{
property: 'costCenter',
title: 'Cost Center',
type: 'select',
description: 'Department cost center',
enum: ['CC-100', 'CC-200', 'CC-300', 'CC-400']
},
{
property: 'complianceFrameworks',
title: 'Compliance Frameworks',
type: 'multiselect',
description: 'Applicable compliance frameworks',
enum: ['GDPR', 'CCPA', 'HIPAA', 'SOX', 'PCI-DSS'],
minItems: 1,
maxItems: 3
},
{
property: 'retentionDays',
title: 'Retention Period (Days)',
type: 'integer',
description: 'How long to retain data',
minimum: 1,
maximum: 3650,
placeholder: '365'
},
{
property: 'isPublic',
title: 'Public Dataset',
type: 'boolean',
description: 'Is this dataset publicly accessible?'
},
{
property: 'effectiveDate',
title: 'Effective Date',
type: 'date',
description: 'When this contract becomes effective'
},
{
property: 'notes',
title: 'Internal Notes',
type: 'textarea',
description: 'Internal notes about this contract',
rows: 4
}
],
customSections: [
{
section: 'governance',
title: 'Governance',
customProperties: ['dataOwner', 'costCenter', 'complianceFrameworks']
},
{
section: 'lifecycle',
title: 'Lifecycle',
customProperties: ['retentionDays', 'effectiveDate', 'isPublic']
}
]
},
// Schema properties level customizations
'schema.properties': {
standardProperties: [
// Hide some advanced fields
{ property: 'encryptedName', hidden: true },
{ property: 'name',
pattern: "^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$",
patternMessage: "Must be lowercase snake_case (e.g., user_id, created_at)."
},
{
property: 'physicalName',
title: 'DB Column Name',
pattern: '^[A-Z][A-Z0-9_]*$',
patternMessage: 'Must be uppercase SNAKE_CASE (e.g., CUSTOMER_ID).',
placeholder: 'COLUMN_NAME'
},
{
property: 'businessName',
title: 'Business Field Name',
minLength: 2,
maxLength: 60,
placeholder: 'Customer Identifier'
},
{ property: 'transformSourceObjects', hidden: true },
// Customize classification with fixed options
{
property: 'classification',
title: 'Data Classification',
enum: ['public', 'internal', 'confidential', 'restricted']
}
],
customProperties: [
{
property: 'piiCategory',
title: 'PII Category',
type: 'select',
description: 'Type of personally identifiable information',
enum: ['none', 'direct', 'indirect', 'sensitive']
},
{
property: 'piiHandling',
title: 'PII Handling Instructions',
type: 'textarea',
description: 'How to handle this PII data',
condition: "piiCategory != 'none'"
},
{
property: 'maskingRequired',
title: 'Masking Required',
type: 'boolean',
description: 'Does this field require data masking?',
condition: "classification == 'confidential' || classification == 'restricted'"
},
{
property: 'gdprLegalBasis',
title: 'GDPR Legal Basis',
type: 'select',
description: 'Legal basis for processing under GDPR',
enum: ['consent', 'contract', 'legal_obligation', 'vital_interests', 'public_task', 'legitimate_interests'],
condition: "piiCategory != 'none'"
}
],
customSections: [
{
section: 'privacy',
title: 'Privacy & Compliance',
customProperties: ['piiCategory', 'piiHandling', 'maskingRequired', 'gdprLegalBasis']
}
]
},
// Description (Terms of Use) level customizations
description: {
standardProperties: [
// Hide limitations field
{ property: 'limitations', hidden: true },
// Customize purpose field
{
property: 'purpose',
title: 'Business Purpose',
description: 'Why this data exists and its intended business use'
}
],
customProperties: [
{
property: 'dataClassification',
title: 'Data Classification',
type: 'select',
description: 'Classification level for this data',
enum: ['Public', 'Internal', 'Confidential', 'Restricted']
},
{
property: 'retentionPolicy',
title: 'Retention Policy',
type: 'text',
description: 'Data retention requirements',
placeholder: 'e.g., 7 years per compliance'
}
],
customSections: [
{
section: 'compliance',
title: 'Compliance Info',
customProperties: ['dataClassification', 'retentionPolicy']
}
]
},
// Schema level customizations
schema: {
standardProperties: [
{
property: 'physicalName',
title: 'Physical Name',
description: 'Use an uppercase first letter for each word, with underscores for spaces. Well-known acronyms can remain fully uppercase. The PhysicalName must always be the same as the Name.',
pattern: '^(?:[A-Z]+|[A-Z][a-z]+)(?:_[A-Z][a-z]+)*$',
patternMessage: 'Must be snake_case with capitalized words. First word must be Title Case, well known acroynms can be ALL CAPS; subsequent words must be Title Case (e.g., Customer_Account_Name or AR_Customers).',
required: true
},
{
property: 'name',
title: 'Schema Name',
description: 'Use an uppercase first letter for each word, with underscores for spaces. Well-known acronyms can remain fully uppercase. The Name must always be the same as the PhysicalName.',
pattern: '^(?:[A-Z]+|[A-Z][a-z]+)(?:_[A-Z][a-z]+)*$',
patternMessage: 'Must be snake_case with capitalized words. First word must be Title Case, well known acroynms can be ALL CAPS; subsequent words must be Title Case (e.g., Customer_Account_Name or AR_Customers).',
required: true
},
{
property: 'businessName',
required: true
},
{
property: 'description',
required: true
}
],
customProperties: [
{
property: 'dataRetentionPolicy',
title: 'Data Retention Policy',
type: 'select',
enum: ['30days', '90days', '1year', '3years', '7years', 'indefinite']
}
]
},
// Server level customizations
servers: {
standardProperties: [
{
property: 'server',
title: 'Server Name',
pattern: '^[a-z][a-z0-9-]*$',
patternMessage: 'Must be lowercase with hyphens only (e.g., prod-db).',
required: true,
placeholder: 'my-server'
},
{
property: 'type',
title: 'Platform Type',
enum: ['snowflake', 'bigquery', 'postgres', 'databricks', 's3']
},
{
property: 'environment',
title: 'Deployment Environment',
enum: ['production', 'staging', 'development']
}
],
customProperties: [
{
property: 'slaLevel',
title: 'SLA Level',
type: 'select',
enum: ['gold', 'silver', 'bronze']
},
{
property: 'maintenanceWindow',
title: 'Maintenance Window',
type: 'text',
placeholder: 'Sunday 2:00-4:00 UTC'
}
]
},
// Team level customizations
team: {
standardProperties: [
{
property: 'name',
title: 'Team Name',
pattern: '^[A-Z]',
patternMessage: 'Team name must start with an uppercase letter.',
required: true,
minLength: 3,
placeholder: 'Data Engineering'
}
],
customProperties: [
{
property: 'slackChannel',
title: 'Slack Channel',
type: 'text',
placeholder: '#data-team'
}
]
},
// Team members level customizations
'team.members': {
standardProperties: [
{ property: 'dateOut', hidden: true },
{
property: 'username',
title: 'Email',
pattern: '^[^@]+@[^@]+\\.[^@]+$',
patternMessage: 'Must be a valid email address.',
required: true,
placeholder: 'user@company.com'
},
{
property: 'name',
title: 'Display Name',
minLength: 2,
maxLength: 50
},
{
property: 'role',
title: 'Team Role',
pattern: '^[a-z][a-z_ ]*$',
patternMessage: 'Role must be lowercase.',
placeholder: 'data steward'
}
],
customProperties: [
{
property: 'department',
title: 'Department',
type: 'select',
enum: ['Engineering', 'Data Science', 'Analytics', 'Platform']
}
]
},
// Roles level customizations
roles: {
standardProperties: [
{
property: 'role',
title: 'IAM Role ARN',
pattern: '^arn:',
patternMessage: 'Must start with "arn:" (e.g., arn:aws:iam::123456789:role/Reader).',
required: true
},
{
property: 'access',
title: 'Access Level',
placeholder: 'read / write / admin'
},
{
property: 'firstLevelApprovers',
title: 'Primary Approver',
pattern: '^[^@]+@[^@]+\\.[^@]+$',
patternMessage: 'Must be a valid email address.',
placeholder: 'approver@company.com'
},
{
property: 'secondLevelApprovers',
title: 'Secondary Approver',
pattern: '^[^@]+@[^@]+\\.[^@]+$',
patternMessage: 'Must be a valid email address.',
placeholder: 'director@company.com'
}
]
},
// Support level customizations
support: {
standardProperties: [
{
property: 'channel',
title: 'Channel Name',
pattern: '^#?[a-z][a-z0-9-]*$',
patternMessage: 'Must be lowercase with hyphens (e.g., #data-support).',
required: true,
placeholder: '#data-support'
},
{
property: 'url',
title: 'Channel URL',
pattern: '^https?://',
patternMessage: 'Must start with http:// or https://.',
placeholder: 'https://slack.com/channels/data-support'
},
{
property: 'invitationUrl',
title: 'Invite Link',
pattern: '^https?://',
patternMessage: 'Must be a valid URL starting with http:// or https://.'
},
{
property: 'tool',
title: 'Platform',
enum: ['slack', 'teams', 'email', 'ticket']
},
{
property: 'scope',
title: 'Usage Scope'
}
]
}
}
};
// Sample YAML with some custom properties pre-filled (using ODCS array format)
const sampleYaml = `apiVersion: "v3.1.0"
kind: "DataContract"
id: customization-test
name: Customization Test Contract
version: "1.0.0"
status: draft
domain: finance
customProperties:
- property: dataOwner
value: jane.doe@company.com
- property: costCenter
value: CC-200
- property: complianceFrameworks
value:
- GDPR
- SOX
- property: retentionDays
value: 365
- property: isPublic
value: false
schema:
- name: transactions
description: Financial transactions
physicalType: table
properties:
- name: customer_id
logicalType: string
description: Customer identifier
classification: confidential
customProperties:
- property: piiCategory
value: direct
- property: maskingRequired
value: true
- name: amount
logicalType: number
description: Transaction amount
servers:
- server: prod-db
type: snowflake
environment: production
account: xy12345
database: ANALYTICS
schema: PUBLIC
team:
name: Data Engineering
description: Responsible for data pipelines
members:
- username: jane@company.com
name: Jane Doe
role: data steward
dateIn: "2024-01-15"
- username: bob@company.com
name: Bob Smith
role: owner
roles:
- role: arn:aws:iam::123456789:role/DataReader
access: read
description: Read-only access to analytics tables
firstLevelApprovers: manager@company.com
secondLevelApprovers: director@company.com
support:
- channel: "#data-support"
url: https://slack.com/channels/data-support
tool: slack
scope: interactive
`;
// Initialize the editor with customizations
const editor = init({
container: '#editor',
yaml: sampleYaml,
customizations: customizations,
initialView: 'form',
showPreview: true,
tests: {
enabled: false
},
persistence: 'none'
});
console.log('Editor initialized with customizations');
console.log('Customizations config:', customizations);
</script>
</body>
</html>