821 lines
28 KiB
TypeScript
821 lines
28 KiB
TypeScript
/**
|
||
* @file sdig-contract-metadata.ts
|
||
* @description Contract metadata editor component
|
||
*/
|
||
|
||
import {
|
||
DeesElement,
|
||
property,
|
||
html,
|
||
customElement,
|
||
type TemplateResult,
|
||
css,
|
||
cssManager,
|
||
state,
|
||
} from '@design.estate/dees-element';
|
||
|
||
import * as plugins from '../../plugins.js';
|
||
|
||
declare global {
|
||
interface HTMLElementTagNameMap {
|
||
'sdig-contract-metadata': SdigContractMetadata;
|
||
}
|
||
}
|
||
|
||
// Type-safe options arrays
|
||
const CONTRACT_CATEGORIES: Array<{ value: plugins.sdInterfaces.TContractCategory; label: string }> = [
|
||
{ value: 'employment', label: 'Employment' },
|
||
{ value: 'service', label: 'Service Agreement' },
|
||
{ value: 'sales', label: 'Sales' },
|
||
{ value: 'lease', label: 'Lease / Rental' },
|
||
{ value: 'license', label: 'License' },
|
||
{ value: 'partnership', label: 'Partnership' },
|
||
{ value: 'confidentiality', label: 'Confidentiality / NDA' },
|
||
{ value: 'financial', label: 'Financial' },
|
||
{ value: 'real_estate', label: 'Real Estate' },
|
||
{ value: 'intellectual_property', label: 'Intellectual Property' },
|
||
{ value: 'government', label: 'Government' },
|
||
{ value: 'construction', label: 'Construction' },
|
||
{ value: 'healthcare', label: 'Healthcare' },
|
||
{ value: 'insurance', label: 'Insurance' },
|
||
{ value: 'other', label: 'Other' },
|
||
];
|
||
|
||
const CONFIDENTIALITY_LEVELS: Array<{ value: plugins.sdInterfaces.TConfidentialityLevel; label: string }> = [
|
||
{ value: 'public', label: 'Public' },
|
||
{ value: 'internal', label: 'Internal' },
|
||
{ value: 'confidential', label: 'Confidential' },
|
||
{ value: 'restricted', label: 'Restricted' },
|
||
];
|
||
|
||
const DISPUTE_RESOLUTIONS: Array<{ value: plugins.sdInterfaces.TDisputeResolution; label: string }> = [
|
||
{ value: 'litigation', label: 'Litigation' },
|
||
{ value: 'arbitration', label: 'Arbitration' },
|
||
{ value: 'mediation', label: 'Mediation' },
|
||
{ value: 'negotiation', label: 'Negotiation' },
|
||
];
|
||
|
||
const COMMON_LANGUAGES = [
|
||
{ value: 'en', label: 'English' },
|
||
{ value: 'de', label: 'German' },
|
||
{ value: 'fr', label: 'French' },
|
||
{ value: 'es', label: 'Spanish' },
|
||
{ value: 'it', label: 'Italian' },
|
||
{ value: 'pt', label: 'Portuguese' },
|
||
{ value: 'nl', label: 'Dutch' },
|
||
{ value: 'pl', label: 'Polish' },
|
||
{ value: 'sv', label: 'Swedish' },
|
||
{ value: 'da', label: 'Danish' },
|
||
{ value: 'fi', label: 'Finnish' },
|
||
{ value: 'no', label: 'Norwegian' },
|
||
{ value: 'zh', label: 'Chinese' },
|
||
{ value: 'ja', label: 'Japanese' },
|
||
{ value: 'ko', label: 'Korean' },
|
||
{ value: 'ar', label: 'Arabic' },
|
||
{ value: 'ru', label: 'Russian' },
|
||
];
|
||
|
||
@customElement('sdig-contract-metadata')
|
||
export class SdigContractMetadata extends DeesElement {
|
||
// ============================================================================
|
||
// STATIC
|
||
// ============================================================================
|
||
|
||
public static demo = () => html`
|
||
<sdig-contract-metadata
|
||
.contract=${plugins.sdDemodata.demoContract}
|
||
></sdig-contract-metadata>
|
||
`;
|
||
|
||
public static styles = [
|
||
cssManager.defaultStyles,
|
||
css`
|
||
:host {
|
||
display: block;
|
||
}
|
||
|
||
.metadata-container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 24px;
|
||
}
|
||
|
||
/* Section cards */
|
||
.section-card {
|
||
background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
||
border: 1px solid ${cssManager.bdTheme('#e5e5e5', '#27272a')};
|
||
border-radius: 12px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.section-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 16px 20px;
|
||
background: ${cssManager.bdTheme('#f9fafb', '#111111')};
|
||
border-bottom: 1px solid ${cssManager.bdTheme('#e5e5e5', '#27272a')};
|
||
}
|
||
|
||
.section-title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
color: ${cssManager.bdTheme('#111111', '#fafafa')};
|
||
}
|
||
|
||
.section-title dees-icon {
|
||
font-size: 18px;
|
||
color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
|
||
}
|
||
|
||
.section-content {
|
||
padding: 20px;
|
||
}
|
||
|
||
/* Form grid */
|
||
.form-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||
gap: 20px;
|
||
}
|
||
|
||
.form-group {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 6px;
|
||
}
|
||
|
||
.form-group.full-width {
|
||
grid-column: 1 / -1;
|
||
}
|
||
|
||
.form-label {
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
color: ${cssManager.bdTheme('#374151', '#d1d5db')};
|
||
}
|
||
|
||
.form-label .required {
|
||
color: #ef4444;
|
||
margin-left: 2px;
|
||
}
|
||
|
||
.form-description {
|
||
font-size: 12px;
|
||
color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
|
||
margin-top: 4px;
|
||
}
|
||
|
||
/* Input styles */
|
||
.form-input,
|
||
.form-select,
|
||
.form-textarea {
|
||
width: 100%;
|
||
padding: 10px 12px;
|
||
font-size: 14px;
|
||
color: ${cssManager.bdTheme('#111111', '#fafafa')};
|
||
background: ${cssManager.bdTheme('#ffffff', '#18181b')};
|
||
border: 1px solid ${cssManager.bdTheme('#d1d5db', '#3f3f46')};
|
||
border-radius: 8px;
|
||
outline: none;
|
||
transition: all 0.15s ease;
|
||
}
|
||
|
||
.form-input:focus,
|
||
.form-select:focus,
|
||
.form-textarea:focus {
|
||
border-color: ${cssManager.bdTheme('#111111', '#fafafa')};
|
||
box-shadow: 0 0 0 3px ${cssManager.bdTheme('rgba(0,0,0,0.05)', 'rgba(255,255,255,0.05)')};
|
||
}
|
||
|
||
.form-input::placeholder,
|
||
.form-textarea::placeholder {
|
||
color: ${cssManager.bdTheme('#9ca3af', '#6b7280')};
|
||
}
|
||
|
||
.form-input:disabled,
|
||
.form-select:disabled,
|
||
.form-textarea:disabled {
|
||
opacity: 0.6;
|
||
cursor: not-allowed;
|
||
}
|
||
|
||
.form-select {
|
||
appearance: none;
|
||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
|
||
background-position: right 10px center;
|
||
background-repeat: no-repeat;
|
||
background-size: 16px;
|
||
padding-right: 36px;
|
||
}
|
||
|
||
.form-textarea {
|
||
min-height: 80px;
|
||
resize: vertical;
|
||
}
|
||
|
||
/* Radio group */
|
||
.radio-group {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 12px;
|
||
}
|
||
|
||
.radio-option {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.radio-option input[type="radio"] {
|
||
width: 18px;
|
||
height: 18px;
|
||
accent-color: ${cssManager.bdTheme('#111111', '#fafafa')};
|
||
}
|
||
|
||
.radio-option span {
|
||
font-size: 14px;
|
||
color: ${cssManager.bdTheme('#374151', '#d1d5db')};
|
||
}
|
||
|
||
/* Tags input */
|
||
.tags-input-container {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
padding: 8px 12px;
|
||
min-height: 44px;
|
||
background: ${cssManager.bdTheme('#ffffff', '#18181b')};
|
||
border: 1px solid ${cssManager.bdTheme('#d1d5db', '#3f3f46')};
|
||
border-radius: 8px;
|
||
cursor: text;
|
||
}
|
||
|
||
.tags-input-container:focus-within {
|
||
border-color: ${cssManager.bdTheme('#111111', '#fafafa')};
|
||
box-shadow: 0 0 0 3px ${cssManager.bdTheme('rgba(0,0,0,0.05)', 'rgba(255,255,255,0.05)')};
|
||
}
|
||
|
||
.tag-item {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
padding: 4px 10px;
|
||
background: ${cssManager.bdTheme('#f3f4f6', '#27272a')};
|
||
border-radius: 6px;
|
||
font-size: 13px;
|
||
color: ${cssManager.bdTheme('#374151', '#d1d5db')};
|
||
}
|
||
|
||
.tag-remove {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 16px;
|
||
height: 16px;
|
||
border-radius: 50%;
|
||
background: transparent;
|
||
border: none;
|
||
color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
line-height: 1;
|
||
}
|
||
|
||
.tag-remove:hover {
|
||
background: ${cssManager.bdTheme('#e5e7eb', '#3f3f46')};
|
||
color: ${cssManager.bdTheme('#111111', '#fafafa')};
|
||
}
|
||
|
||
.tags-input {
|
||
flex: 1;
|
||
min-width: 120px;
|
||
border: none;
|
||
background: transparent;
|
||
padding: 4px 0;
|
||
font-size: 14px;
|
||
color: ${cssManager.bdTheme('#111111', '#fafafa')};
|
||
outline: none;
|
||
}
|
||
|
||
.tags-input::placeholder {
|
||
color: ${cssManager.bdTheme('#9ca3af', '#6b7280')};
|
||
}
|
||
|
||
/* Divider */
|
||
.section-divider {
|
||
border-top: 1px solid ${cssManager.bdTheme('#e5e5e5', '#27272a')};
|
||
margin: 20px 0;
|
||
}
|
||
|
||
/* Collapsible sections */
|
||
.collapsible-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 12px 0;
|
||
cursor: pointer;
|
||
user-select: none;
|
||
}
|
||
|
||
.collapsible-header:hover .collapse-icon {
|
||
color: ${cssManager.bdTheme('#111111', '#fafafa')};
|
||
}
|
||
|
||
.collapse-icon {
|
||
font-size: 16px;
|
||
color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
|
||
transition: transform 0.2s ease;
|
||
}
|
||
|
||
.collapse-icon.expanded {
|
||
transform: rotate(180deg);
|
||
}
|
||
|
||
.collapsible-content {
|
||
overflow: hidden;
|
||
max-height: 0;
|
||
opacity: 0;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.collapsible-content.expanded {
|
||
max-height: 1000px;
|
||
opacity: 1;
|
||
}
|
||
`,
|
||
];
|
||
|
||
// ============================================================================
|
||
// PROPERTIES
|
||
// ============================================================================
|
||
|
||
@property({ type: Object })
|
||
public accessor contract: plugins.sdInterfaces.IPortableContract | null = null;
|
||
|
||
@property({ type: Boolean })
|
||
public accessor readonly: boolean = false;
|
||
|
||
// ============================================================================
|
||
// STATE
|
||
// ============================================================================
|
||
|
||
@state()
|
||
private accessor showArbitrationFields: boolean = false;
|
||
|
||
@state()
|
||
private accessor newTag: string = '';
|
||
|
||
// ============================================================================
|
||
// LIFECYCLE
|
||
// ============================================================================
|
||
|
||
public updated(changedProperties: Map<string, unknown>) {
|
||
if (changedProperties.has('contract') && this.contract?.metadata?.governingLaw) {
|
||
this.showArbitrationFields = this.contract.metadata.governingLaw.disputeResolution === 'arbitration';
|
||
}
|
||
}
|
||
|
||
// ============================================================================
|
||
// EVENT HANDLERS
|
||
// ============================================================================
|
||
|
||
private handleFieldChange(path: string, value: unknown) {
|
||
this.dispatchEvent(
|
||
new CustomEvent('field-change', {
|
||
detail: { path, value },
|
||
bubbles: true,
|
||
composed: true,
|
||
})
|
||
);
|
||
}
|
||
|
||
private handleInputChange(path: string, e: Event) {
|
||
const input = e.target as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
|
||
this.handleFieldChange(path, input.value);
|
||
}
|
||
|
||
private handleRadioChange(path: string, value: string) {
|
||
this.handleFieldChange(path, value);
|
||
|
||
// Special handling for dispute resolution
|
||
if (path === 'metadata.governingLaw.disputeResolution') {
|
||
this.showArbitrationFields = value === 'arbitration';
|
||
}
|
||
}
|
||
|
||
private handleTagAdd(e: KeyboardEvent) {
|
||
if (e.key === 'Enter' && this.newTag.trim()) {
|
||
e.preventDefault();
|
||
const currentTags = this.contract?.metadata.tags || [];
|
||
if (!currentTags.includes(this.newTag.trim())) {
|
||
this.handleFieldChange('metadata.tags', [...currentTags, this.newTag.trim()]);
|
||
}
|
||
this.newTag = '';
|
||
}
|
||
}
|
||
|
||
private handleTagRemove(tag: string) {
|
||
const currentTags = this.contract?.metadata.tags || [];
|
||
this.handleFieldChange(
|
||
'metadata.tags',
|
||
currentTags.filter((t) => t !== tag)
|
||
);
|
||
}
|
||
|
||
// ============================================================================
|
||
// RENDER
|
||
// ============================================================================
|
||
|
||
public render(): TemplateResult {
|
||
if (!this.contract) {
|
||
return html`<div>No contract loaded</div>`;
|
||
}
|
||
|
||
if (!this.contract.metadata) {
|
||
return html`<div class="metadata-container"><div class="section-card">Contract metadata not available</div></div>`;
|
||
}
|
||
|
||
const metadata = this.contract.metadata;
|
||
|
||
return html`
|
||
<div class="metadata-container">
|
||
<!-- Basic Information -->
|
||
<div class="section-card">
|
||
<div class="section-header">
|
||
<div class="section-title">
|
||
<dees-icon .iconFA=${'lucide:info'}></dees-icon>
|
||
Basic Information
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Contract Number</label>
|
||
<input
|
||
type="text"
|
||
class="form-input"
|
||
.value=${metadata.contractNumber || ''}
|
||
placeholder="e.g., CNT-2024-001"
|
||
?disabled=${this.readonly}
|
||
@input=${(e: Event) => this.handleInputChange('metadata.contractNumber', e)}
|
||
/>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Category <span class="required">*</span></label>
|
||
<select
|
||
class="form-select"
|
||
.value=${metadata.category}
|
||
?disabled=${this.readonly}
|
||
@change=${(e: Event) => this.handleInputChange('metadata.category', e)}
|
||
>
|
||
${CONTRACT_CATEGORIES.map(
|
||
(cat) => html`
|
||
<option value=${cat.value} ?selected=${metadata.category === cat.value}>
|
||
${cat.label}
|
||
</option>
|
||
`
|
||
)}
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Contract Type <span class="required">*</span></label>
|
||
<input
|
||
type="text"
|
||
class="form-input"
|
||
.value=${metadata.contractType}
|
||
placeholder="e.g., employment_minijob"
|
||
?disabled=${this.readonly}
|
||
@input=${(e: Event) => this.handleInputChange('metadata.contractType', e)}
|
||
/>
|
||
<p class="form-description">Specific contract type identifier</p>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Confidentiality Level</label>
|
||
<div class="radio-group">
|
||
${CONFIDENTIALITY_LEVELS.map(
|
||
(level) => html`
|
||
<label class="radio-option">
|
||
<input
|
||
type="radio"
|
||
name="confidentiality"
|
||
.value=${level.value}
|
||
?checked=${metadata.confidentialityLevel === level.value}
|
||
?disabled=${this.readonly}
|
||
@change=${() => this.handleRadioChange('metadata.confidentialityLevel', level.value)}
|
||
/>
|
||
<span>${level.label}</span>
|
||
</label>
|
||
`
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group full-width">
|
||
<label class="form-label">Tags</label>
|
||
<div class="tags-input-container">
|
||
${metadata.tags.map(
|
||
(tag) => html`
|
||
<span class="tag-item">
|
||
${tag}
|
||
${!this.readonly
|
||
? html`
|
||
<button class="tag-remove" @click=${() => this.handleTagRemove(tag)}>×</button>
|
||
`
|
||
: ''}
|
||
</span>
|
||
`
|
||
)}
|
||
${!this.readonly
|
||
? html`
|
||
<input
|
||
type="text"
|
||
class="tags-input"
|
||
.value=${this.newTag}
|
||
placeholder="Add tag and press Enter"
|
||
@input=${(e: Event) => (this.newTag = (e.target as HTMLInputElement).value)}
|
||
@keydown=${this.handleTagAdd}
|
||
/>
|
||
`
|
||
: ''}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Language Settings -->
|
||
<div class="section-card">
|
||
<div class="section-header">
|
||
<div class="section-title">
|
||
<dees-icon .iconFA=${'lucide:globe'}></dees-icon>
|
||
Language Settings
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Primary Language <span class="required">*</span></label>
|
||
<select
|
||
class="form-select"
|
||
.value=${metadata.language}
|
||
?disabled=${this.readonly}
|
||
@change=${(e: Event) => this.handleInputChange('metadata.language', e)}
|
||
>
|
||
${COMMON_LANGUAGES.map(
|
||
(lang) => html`
|
||
<option value=${lang.value} ?selected=${metadata.language === lang.value}>
|
||
${lang.label}
|
||
</option>
|
||
`
|
||
)}
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Binding Language</label>
|
||
<select
|
||
class="form-select"
|
||
.value=${metadata.bindingLanguage || ''}
|
||
?disabled=${this.readonly}
|
||
@change=${(e: Event) => this.handleInputChange('metadata.bindingLanguage', e)}
|
||
>
|
||
<option value="">Same as primary</option>
|
||
${COMMON_LANGUAGES.map(
|
||
(lang) => html`
|
||
<option value=${lang.value} ?selected=${metadata.bindingLanguage === lang.value}>
|
||
${lang.label}
|
||
</option>
|
||
`
|
||
)}
|
||
</select>
|
||
<p class="form-description">Language that takes precedence in case of conflicts</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Governing Law -->
|
||
<div class="section-card">
|
||
<div class="section-header">
|
||
<div class="section-title">
|
||
<dees-icon .iconFA=${'lucide:scale'}></dees-icon>
|
||
Governing Law & Jurisdiction
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Country <span class="required">*</span></label>
|
||
<input
|
||
type="text"
|
||
class="form-input"
|
||
.value=${metadata.governingLaw.country}
|
||
placeholder="e.g., Germany"
|
||
?disabled=${this.readonly}
|
||
@input=${(e: Event) => this.handleInputChange('metadata.governingLaw.country', e)}
|
||
/>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">State / Province</label>
|
||
<input
|
||
type="text"
|
||
class="form-input"
|
||
.value=${metadata.governingLaw.state || ''}
|
||
placeholder="e.g., Bavaria"
|
||
?disabled=${this.readonly}
|
||
@input=${(e: Event) => this.handleInputChange('metadata.governingLaw.state', e)}
|
||
/>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Dispute Jurisdiction</label>
|
||
<input
|
||
type="text"
|
||
class="form-input"
|
||
.value=${metadata.governingLaw.disputeJurisdiction || ''}
|
||
placeholder="e.g., Munich Courts"
|
||
?disabled=${this.readonly}
|
||
@input=${(e: Event) => this.handleInputChange('metadata.governingLaw.disputeJurisdiction', e)}
|
||
/>
|
||
</div>
|
||
|
||
<div class="form-group full-width">
|
||
<label class="form-label">Dispute Resolution Method</label>
|
||
<div class="radio-group">
|
||
${DISPUTE_RESOLUTIONS.map(
|
||
(res) => html`
|
||
<label class="radio-option">
|
||
<input
|
||
type="radio"
|
||
name="disputeResolution"
|
||
.value=${res.value}
|
||
?checked=${metadata.governingLaw.disputeResolution === res.value}
|
||
?disabled=${this.readonly}
|
||
@change=${() => this.handleRadioChange('metadata.governingLaw.disputeResolution', res.value)}
|
||
/>
|
||
<span>${res.label}</span>
|
||
</label>
|
||
`
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
${this.showArbitrationFields
|
||
? html`
|
||
<div class="section-divider full-width"></div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Arbitration Institution</label>
|
||
<input
|
||
type="text"
|
||
class="form-input"
|
||
.value=${metadata.governingLaw.arbitrationInstitution || ''}
|
||
placeholder="e.g., ICC, LCIA, AAA"
|
||
?disabled=${this.readonly}
|
||
@input=${(e: Event) => this.handleInputChange('metadata.governingLaw.arbitrationInstitution', e)}
|
||
/>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Arbitration Rules</label>
|
||
<input
|
||
type="text"
|
||
class="form-input"
|
||
.value=${metadata.governingLaw.arbitrationRules || ''}
|
||
placeholder="e.g., ICC Rules of Arbitration"
|
||
?disabled=${this.readonly}
|
||
@input=${(e: Event) => this.handleInputChange('metadata.governingLaw.arbitrationRules', e)}
|
||
/>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Seat of Arbitration</label>
|
||
<input
|
||
type="text"
|
||
class="form-input"
|
||
.value=${metadata.governingLaw.arbitrationSeat || ''}
|
||
placeholder="e.g., Paris, London"
|
||
?disabled=${this.readonly}
|
||
@input=${(e: Event) => this.handleInputChange('metadata.governingLaw.arbitrationSeat', e)}
|
||
/>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Number of Arbitrators</label>
|
||
<select
|
||
class="form-select"
|
||
.value=${String(metadata.governingLaw.numberOfArbitrators || 1)}
|
||
?disabled=${this.readonly}
|
||
@change=${(e: Event) =>
|
||
this.handleFieldChange(
|
||
'metadata.governingLaw.numberOfArbitrators',
|
||
parseInt((e.target as HTMLSelectElement).value, 10)
|
||
)}
|
||
>
|
||
<option value="1">1 Arbitrator</option>
|
||
<option value="3">3 Arbitrators</option>
|
||
<option value="5">5 Arbitrators</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Proceedings Language</label>
|
||
<select
|
||
class="form-select"
|
||
.value=${metadata.governingLaw.proceedingsLanguage || ''}
|
||
?disabled=${this.readonly}
|
||
@change=${(e: Event) => this.handleInputChange('metadata.governingLaw.proceedingsLanguage', e)}
|
||
>
|
||
<option value="">Select language</option>
|
||
${COMMON_LANGUAGES.map(
|
||
(lang) => html`
|
||
<option
|
||
value=${lang.value}
|
||
?selected=${metadata.governingLaw.proceedingsLanguage === lang.value}
|
||
>
|
||
${lang.label}
|
||
</option>
|
||
`
|
||
)}
|
||
</select>
|
||
</div>
|
||
`
|
||
: ''}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- References -->
|
||
<div class="section-card">
|
||
<div class="section-header">
|
||
<div class="section-title">
|
||
<dees-icon .iconFA=${'lucide:link'}></dees-icon>
|
||
References & Integration
|
||
</div>
|
||
</div>
|
||
<div class="section-content">
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Internal Reference</label>
|
||
<input
|
||
type="text"
|
||
class="form-input"
|
||
.value=${metadata.internalReference || ''}
|
||
placeholder="Internal tracking reference"
|
||
?disabled=${this.readonly}
|
||
@input=${(e: Event) => this.handleInputChange('metadata.internalReference', e)}
|
||
/>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">External Reference</label>
|
||
<input
|
||
type="text"
|
||
class="form-input"
|
||
.value=${metadata.externalReference || ''}
|
||
placeholder="External system reference"
|
||
?disabled=${this.readonly}
|
||
@input=${(e: Event) => this.handleInputChange('metadata.externalReference', e)}
|
||
/>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Template ID</label>
|
||
<input
|
||
type="text"
|
||
class="form-input"
|
||
.value=${metadata.templateId || ''}
|
||
placeholder="Source template ID"
|
||
?disabled=${this.readonly}
|
||
@input=${(e: Event) => this.handleInputChange('metadata.templateId', e)}
|
||
/>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Parent Contract ID</label>
|
||
<input
|
||
type="text"
|
||
class="form-input"
|
||
.value=${metadata.parentContractId || ''}
|
||
placeholder="Parent/master contract"
|
||
?disabled=${this.readonly}
|
||
@input=${(e: Event) => this.handleInputChange('metadata.parentContractId', e)}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
}
|