Initial commit
This commit is contained in:
@@ -0,0 +1,483 @@
|
||||
/**
|
||||
* Class model for Individual Interface
|
||||
*/
|
||||
|
||||
import { reactive } from 'vue'
|
||||
import { generateUrid, generateKey } from "../utils/key-generator";
|
||||
import type {
|
||||
IndividualAnniversary,
|
||||
IndividualCrypto,
|
||||
IndividualEmail,
|
||||
IndividualInterface,
|
||||
IndividualLanguage,
|
||||
IndividualMedia,
|
||||
IndividualName,
|
||||
IndividualNote,
|
||||
IndividualOrganization,
|
||||
IndividualPhone,
|
||||
IndividualPhysicalLocation,
|
||||
IndividualTitle,
|
||||
IndividualVirtualLocation
|
||||
} from "@/types/individual";
|
||||
|
||||
export class IndividualObject implements IndividualInterface {
|
||||
|
||||
_data: IndividualInterface;
|
||||
|
||||
constructor() {
|
||||
this._data = reactive({
|
||||
type: 'individual',
|
||||
version: 1,
|
||||
urid: generateUrid(),
|
||||
created: null,
|
||||
modified: null,
|
||||
label: '',
|
||||
names: {
|
||||
family: null,
|
||||
given: null,
|
||||
additional: null,
|
||||
prefix: null,
|
||||
suffix: null,
|
||||
phoneticFamily: null,
|
||||
phoneticGiven: null,
|
||||
phoneticAdditional: null,
|
||||
aliases: []
|
||||
},
|
||||
titles: {},
|
||||
anniversaries: [],
|
||||
physicalLocations: {},
|
||||
phones: {},
|
||||
emails: {},
|
||||
virtualLocations: {},
|
||||
media: {},
|
||||
organizations: {},
|
||||
tags: [],
|
||||
notes: {},
|
||||
language: null,
|
||||
languages: [],
|
||||
crypto: {},
|
||||
});
|
||||
}
|
||||
|
||||
fromJson(data: IndividualInterface) : IndividualObject {
|
||||
// Normalize arrays to Records for properties that should be Record types
|
||||
const normalized = {
|
||||
...data,
|
||||
titles: Array.isArray(data.titles) ? {} : (data.titles || {}),
|
||||
physicalLocations: Array.isArray(data.physicalLocations) ? {} : (data.physicalLocations || {}),
|
||||
phones: Array.isArray(data.phones) ? {} : (data.phones || {}),
|
||||
emails: Array.isArray(data.emails) ? {} : (data.emails || {}),
|
||||
virtualLocations: Array.isArray(data.virtualLocations) ? {} : (data.virtualLocations || {}),
|
||||
media: Array.isArray(data.media) ? {} : (data.media || {}),
|
||||
notes: Array.isArray(data.notes) ? {} : (data.notes || {}),
|
||||
crypto: Array.isArray(data.crypto) ? {} : (data.crypto || {}),
|
||||
};
|
||||
this._data = reactive(normalized);
|
||||
return this;
|
||||
}
|
||||
|
||||
toJson(): IndividualInterface {
|
||||
return this._data;
|
||||
}
|
||||
|
||||
clone(): IndividualObject {
|
||||
const cloned = new IndividualObject()
|
||||
cloned._data = JSON.parse(JSON.stringify(this._data))
|
||||
return cloned
|
||||
}
|
||||
|
||||
/** Immutable Properties */
|
||||
get type(): string {
|
||||
return this._data.type;
|
||||
}
|
||||
|
||||
get version(): number {
|
||||
return this._data.version;
|
||||
}
|
||||
|
||||
get urid(): string | null {
|
||||
return this._data.urid;
|
||||
}
|
||||
|
||||
/** Mutable Properties */
|
||||
|
||||
get created(): Date | null {
|
||||
return this._data.created;
|
||||
}
|
||||
|
||||
set created(value: Date | null) {
|
||||
this._data.created = value;
|
||||
}
|
||||
|
||||
get modified(): Date | null {
|
||||
return this._data.modified;
|
||||
}
|
||||
|
||||
set modified(value: Date | null) {
|
||||
this._data.modified = value;
|
||||
}
|
||||
|
||||
get label(): string | null {
|
||||
return this._data.label;
|
||||
}
|
||||
|
||||
set label(value: string | null) {
|
||||
this._data.label = value;
|
||||
}
|
||||
|
||||
get names(): IndividualName {
|
||||
return this._data.names;
|
||||
}
|
||||
|
||||
set names(value: IndividualName) {
|
||||
this._data.names = value;
|
||||
}
|
||||
|
||||
get titles(): Record<string, IndividualTitle> {
|
||||
return this._data.titles;
|
||||
}
|
||||
|
||||
set titles(value: Record<string, IndividualTitle>) {
|
||||
this._data.titles = value;
|
||||
}
|
||||
|
||||
get anniversaries(): IndividualAnniversary[] {
|
||||
return this._data.anniversaries;
|
||||
}
|
||||
|
||||
set anniversaries(value: IndividualAnniversary[]) {
|
||||
this._data.anniversaries = value;
|
||||
}
|
||||
|
||||
get physicalLocations(): Record<string, IndividualPhysicalLocation> {
|
||||
return this._data.physicalLocations;
|
||||
}
|
||||
|
||||
set physicalLocations(value: Record<string, IndividualPhysicalLocation>) {
|
||||
this._data.physicalLocations = value;
|
||||
}
|
||||
|
||||
get phones(): Record<string, IndividualPhone> {
|
||||
return this._data.phones;
|
||||
}
|
||||
|
||||
set phones(value: Record<string, IndividualPhone>) {
|
||||
this._data.phones = value;
|
||||
}
|
||||
|
||||
get emails(): Record<string, IndividualEmail> {
|
||||
return this._data.emails;
|
||||
}
|
||||
|
||||
set emails(value: Record<string, IndividualEmail>) {
|
||||
this._data.emails = value;
|
||||
}
|
||||
|
||||
get virtualLocations(): Record<string, IndividualVirtualLocation> {
|
||||
return this._data.virtualLocations;
|
||||
}
|
||||
|
||||
set virtualLocations(value: Record<string, IndividualVirtualLocation>) {
|
||||
this._data.virtualLocations = value;
|
||||
}
|
||||
|
||||
get media(): Record<string, IndividualMedia> {
|
||||
return this._data.media;
|
||||
}
|
||||
|
||||
set media(value: Record<string, IndividualMedia>) {
|
||||
this._data.media = value;
|
||||
}
|
||||
|
||||
get organizations(): Record<string, IndividualOrganization> {
|
||||
return this._data.organizations;
|
||||
}
|
||||
|
||||
set organizations(value: Record<string, IndividualOrganization>) {
|
||||
this._data.organizations = value;
|
||||
}
|
||||
|
||||
get tags(): string[] {
|
||||
return this._data.tags;
|
||||
}
|
||||
|
||||
set tags(value: string[]) {
|
||||
this._data.tags = value;
|
||||
}
|
||||
|
||||
get notes(): Record<string, IndividualNote> {
|
||||
return this._data.notes;
|
||||
}
|
||||
|
||||
set notes(value: Record<string, IndividualNote>) {
|
||||
this._data.notes = value;
|
||||
}
|
||||
|
||||
get language(): string | null {
|
||||
return this._data.language;
|
||||
}
|
||||
|
||||
set language(value: string | null) {
|
||||
this._data.language = value;
|
||||
}
|
||||
|
||||
get languages(): IndividualLanguage[] {
|
||||
return this._data.languages;
|
||||
}
|
||||
|
||||
set languages(value: IndividualLanguage[]) {
|
||||
this._data.languages = value;
|
||||
}
|
||||
|
||||
get crypto(): Record<string, IndividualCrypto> {
|
||||
return this._data.crypto;
|
||||
}
|
||||
|
||||
set crypto(value: Record<string, IndividualCrypto>) {
|
||||
this._data.crypto = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutation helpers for complex properties
|
||||
*/
|
||||
|
||||
addTitle(initial?: Partial<IndividualTitle>): string {
|
||||
if (!this._data.titles) {
|
||||
this._data.titles = {};
|
||||
}
|
||||
const key = generateKey();
|
||||
this._data.titles[key] = {
|
||||
kind: null,
|
||||
label: null,
|
||||
relation: null,
|
||||
context: null,
|
||||
priority: null,
|
||||
...initial,
|
||||
};
|
||||
return key;
|
||||
}
|
||||
|
||||
removeTitle(key: string): void {
|
||||
if (this._data.titles) {
|
||||
delete this._data.titles[key];
|
||||
}
|
||||
}
|
||||
|
||||
addAnniversary(initial?: Partial<IndividualAnniversary>): number {
|
||||
const anniversaries = this._data.anniversaries || (this._data.anniversaries = []);
|
||||
const entry: IndividualAnniversary = {
|
||||
type: null,
|
||||
when: null,
|
||||
location: null,
|
||||
...initial,
|
||||
};
|
||||
anniversaries.push(entry);
|
||||
return anniversaries.length - 1;
|
||||
}
|
||||
|
||||
removeAnniversary(index: number): void {
|
||||
const anniversaries = this._data.anniversaries;
|
||||
if (index >= 0 && index < anniversaries.length) {
|
||||
anniversaries.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
addPhysicalLocation(initial?: Partial<IndividualPhysicalLocation>): string {
|
||||
const locations = this._data.physicalLocations || (this._data.physicalLocations = {});
|
||||
const key = generateKey();
|
||||
locations[key] = {
|
||||
box: null,
|
||||
unit: null,
|
||||
street: null,
|
||||
locality: null,
|
||||
region: null,
|
||||
code: null,
|
||||
country: null,
|
||||
label: null,
|
||||
coordinates: null,
|
||||
timeZone: null,
|
||||
context: null,
|
||||
priority: null,
|
||||
...initial,
|
||||
};
|
||||
return key;
|
||||
}
|
||||
|
||||
removePhysicalLocation(key: string): void {
|
||||
if (this._data.physicalLocations) {
|
||||
delete this._data.physicalLocations[key];
|
||||
}
|
||||
}
|
||||
|
||||
addPhone(initial?: Partial<IndividualPhone>): string {
|
||||
const phones = this._data.phones || (this._data.phones = {});
|
||||
const key = generateKey();
|
||||
phones[key] = {
|
||||
number: null,
|
||||
label: null,
|
||||
context: null,
|
||||
priority: null,
|
||||
...initial,
|
||||
};
|
||||
return key;
|
||||
}
|
||||
|
||||
removePhone(key: string): void {
|
||||
if (this._data.phones) {
|
||||
delete this._data.phones[key];
|
||||
}
|
||||
}
|
||||
|
||||
addEmail(initial?: Partial<IndividualEmail>): string {
|
||||
const emails = this._data.emails || (this._data.emails = {});
|
||||
const key = generateKey();
|
||||
emails[key] = {
|
||||
address: null,
|
||||
context: null,
|
||||
priority: null,
|
||||
...initial,
|
||||
};
|
||||
return key;
|
||||
}
|
||||
|
||||
removeEmail(key: string): void {
|
||||
if (this._data.emails) {
|
||||
delete this._data.emails[key];
|
||||
}
|
||||
}
|
||||
|
||||
addVirtualLocation(initial?: Partial<IndividualVirtualLocation>): string {
|
||||
const virtualLocations = this._data.virtualLocations || (this._data.virtualLocations = {});
|
||||
const key = generateKey();
|
||||
virtualLocations[key] = {
|
||||
location: null,
|
||||
label: null,
|
||||
context: null,
|
||||
priority: null,
|
||||
...initial,
|
||||
};
|
||||
return key;
|
||||
}
|
||||
|
||||
removeVirtualLocation(key: string): void {
|
||||
if (this._data.virtualLocations) {
|
||||
delete this._data.virtualLocations[key];
|
||||
}
|
||||
}
|
||||
|
||||
addMedia(initial?: Partial<IndividualMedia>): string {
|
||||
const media = this._data.media || (this._data.media = {});
|
||||
const key = generateKey();
|
||||
media[key] = {
|
||||
type: "photo",
|
||||
kind: "photo",
|
||||
uri: "",
|
||||
mediaType: null,
|
||||
contexts: null,
|
||||
pref: null,
|
||||
label: null,
|
||||
...initial,
|
||||
};
|
||||
return key;
|
||||
}
|
||||
|
||||
removeMedia(key: string): void {
|
||||
if (this._data.media) {
|
||||
delete this._data.media[key];
|
||||
}
|
||||
}
|
||||
|
||||
addOrganization(initial?: Partial<IndividualOrganization>): string {
|
||||
const organizations = this._data.organizations || (this._data.organizations = {});
|
||||
const key = generateKey();
|
||||
organizations[key] = {
|
||||
Label: null,
|
||||
Units: [],
|
||||
sortName: null,
|
||||
context: null,
|
||||
priority: null,
|
||||
...initial,
|
||||
};
|
||||
return key;
|
||||
}
|
||||
|
||||
removeOrganization(key: string): void {
|
||||
if (this._data.organizations) {
|
||||
delete this._data.organizations[key];
|
||||
}
|
||||
}
|
||||
|
||||
addNote(initial?: Partial<IndividualNote>): string {
|
||||
const notes = this._data.notes || (this._data.notes = {});
|
||||
const key = generateKey();
|
||||
notes[key] = {
|
||||
content: null,
|
||||
date: null,
|
||||
authorUri: null,
|
||||
authorName: null,
|
||||
context: null,
|
||||
priority: null,
|
||||
...initial,
|
||||
};
|
||||
return key;
|
||||
}
|
||||
|
||||
removeNote(key: string): void {
|
||||
if (this._data.notes) {
|
||||
delete this._data.notes[key];
|
||||
}
|
||||
}
|
||||
|
||||
addLanguage(initial?: Partial<IndividualLanguage>): number {
|
||||
const languages = this._data.languages || (this._data.languages = []);
|
||||
const entry: IndividualLanguage = {
|
||||
Data: null,
|
||||
Id: null,
|
||||
Priority: null,
|
||||
Context: null,
|
||||
...initial,
|
||||
};
|
||||
languages.push(entry);
|
||||
return languages.length - 1;
|
||||
}
|
||||
|
||||
removeLanguage(index: number): void {
|
||||
const languages = this._data.languages;
|
||||
if (index >= 0 && index < languages.length) {
|
||||
languages.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
addCrypto(initial?: Partial<IndividualCrypto>): string {
|
||||
const cryptoEntries = this._data.crypto || (this._data.crypto = {});
|
||||
const key = generateKey();
|
||||
cryptoEntries[key] = {
|
||||
data: null,
|
||||
type: null,
|
||||
context: null,
|
||||
priority: null,
|
||||
...initial,
|
||||
};
|
||||
return key;
|
||||
}
|
||||
|
||||
removeCrypto(key: string): void {
|
||||
if (this._data.crypto) {
|
||||
delete this._data.crypto[key];
|
||||
}
|
||||
}
|
||||
|
||||
addTag(value: string): void {
|
||||
const tags = this._data.tags || (this._data.tags = []);
|
||||
tags.push(value);
|
||||
}
|
||||
|
||||
removeTag(value: string): void {
|
||||
const tags = this._data.tags;
|
||||
const index = tags.indexOf(value);
|
||||
if (index >= 0) {
|
||||
tags.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user