Skip to content

Commit 21a8e27

Browse files
authored
Merge pull request #1862 from cardstack/add-phone-number-field
Create phone number field
2 parents 55a1df4 + 906b2b0 commit 21a8e27

File tree

7 files changed

+210
-141
lines changed

7 files changed

+210
-141
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"data": {
3+
"type": "card",
4+
"attributes": {
5+
"contactPhone": {
6+
"value": "01355889283",
7+
"type": {
8+
"index": 2,
9+
"label": "Work"
10+
}
11+
},
12+
"title": null,
13+
"description": null,
14+
"thumbnailURL": null
15+
},
16+
"meta": {
17+
"adoptsFrom": {
18+
"module": "../phone-number",
19+
"name": "CardWithContactPhoneNumber"
20+
}
21+
}
22+
}
23+
}

Diff for: packages/experiments-realm/Contact/a01fc5c9-d70d-4b9c-aae4-384cf2b79b25.json

+16-8
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,24 @@
99
"primaryEmail": "david@gmail.com",
1010
"secondaryEmail": "david23232@gmail.com",
1111
"phoneMobile": {
12-
"type": "office",
13-
"country": 1,
14-
"area": 415,
15-
"number": 123456
12+
"phoneNumber": {
13+
"number": "1158524828",
14+
"countryCode": "60"
15+
},
16+
"type": {
17+
"index": 0,
18+
"label": "Mobile"
19+
}
1620
},
1721
"phoneOffice": {
18-
"type": null,
19-
"country": null,
20-
"area": null,
21-
"number": null
22+
"phoneNumber": {
23+
"number": null,
24+
"countryCode": null
25+
},
26+
"type": {
27+
"index": null,
28+
"label": null
29+
}
2230
},
2331
"socialLinks": [
2432
{

Diff for: packages/experiments-realm/ExperimentsFieldsPreview/de720f57-964b-4a09-8d52-80cd8bb4b739.json

+3-5
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,8 @@
2626
"dan@email.com"
2727
],
2828
"phone": {
29-
"type": null,
30-
"country": null,
31-
"area": null,
32-
"number": null
29+
"number": "1159292211",
30+
"countryCode": "60"
3331
},
3432
"percentage": 100.159393,
3533
"currency": {
@@ -105,4 +103,4 @@
105103
}
106104
}
107105
}
108-
}
106+
}

Diff for: packages/experiments-realm/crm/contact.gts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import StringField from 'https://cardstack.com/base/string';
2-
import { PhoneField } from '../phone';
2+
import { ContactPhoneNumber } from '../phone-number';
33
import { EmailField } from '../email';
44
import { ContactLinkField } from '../fields/contact-link';
55
import {
@@ -701,8 +701,8 @@ export class Contact extends CardDef {
701701
@field department = contains(StringField);
702702
@field primaryEmail = contains(EmailField);
703703
@field secondaryEmail = contains(EmailField);
704-
@field phoneMobile = contains(PhoneField);
705-
@field phoneOffice = contains(PhoneField);
704+
@field phoneMobile = contains(ContactPhoneNumber);
705+
@field phoneOffice = contains(ContactPhoneNumber);
706706
@field socialLinks = containsMany(SocialLinkField);
707707
@field statusTag = contains(StatusTagField); //this is an empty field that gets computed in subclasses
708708

Diff for: packages/experiments-realm/experiments_fields_preview.gts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { FeaturedImageField } from './fields/featured-image';
22
import { ContactLinkField } from './fields/contact-link';
33
import { EmailField } from './email';
4-
import { PhoneField } from './phone';
4+
import { PhoneField } from './phone-number';
55
import { UrlField } from './url';
66
import { WebsiteField } from './website';
77
import { Address as AddressField } from './address';

Diff for: packages/experiments-realm/phone-number.gts

+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
import {
2+
contains,
3+
field,
4+
Component,
5+
FieldDef,
6+
StringField,
7+
} from 'https://cardstack.com/base/card-api';
8+
import { LooseGooseyField, LooseyGooseyData } from './loosey-goosey';
9+
import { PhoneInput, Pill } from '@cardstack/boxel-ui/components';
10+
import { RadioInput } from '@cardstack/boxel-ui/components';
11+
import { EntityDisplay } from './components/entity-display';
12+
import { tracked } from '@glimmer/tracking';
13+
import { fn } from '@ember/helper';
14+
import { action } from '@ember/object';
15+
import PhoneIcon from '@cardstack/boxel-icons/phone';
16+
17+
class PhoneNumberTypeEdit extends Component<typeof PhoneNumberType> {
18+
@tracked label: string | undefined = this.args.model.label;
19+
20+
get types() {
21+
return PhoneNumberType.values;
22+
}
23+
24+
get selected() {
25+
return this.types?.find((type) => {
26+
return type.label === this.label;
27+
});
28+
}
29+
30+
@action onSelect(type: LooseyGooseyData): void {
31+
this.label = type.label;
32+
this.args.model.label = this.selected?.label;
33+
this.args.model.index = this.selected?.index;
34+
}
35+
<template>
36+
<RadioInput
37+
@groupDescription='Office, Work, Home '
38+
@items={{this.types}}
39+
@checkedId={{this.selected.label}}
40+
@orientation='horizontal'
41+
@spacing='default'
42+
@keyName='label'
43+
as |item|
44+
>
45+
<item.component @onChange={{fn this.onSelect item.data}}>
46+
{{item.data.label}}
47+
</item.component>
48+
</RadioInput>
49+
</template>
50+
}
51+
52+
export class PhoneNumberType extends LooseGooseyField {
53+
static displayName = 'Phone Number Type';
54+
static values = [
55+
{ index: 0, label: 'Mobile' },
56+
{ index: 1, label: 'Home' },
57+
{ index: 2, label: 'Work' },
58+
];
59+
static edit = PhoneNumberTypeEdit;
60+
}
61+
62+
export class PhoneField extends FieldDef {
63+
static displayName = 'Phone Number';
64+
@field number = contains(StringField);
65+
@field countryCode = contains(StringField);
66+
67+
setNumber = (number: string) => {
68+
this.number = number;
69+
};
70+
71+
setCountryCode = (code: string) => {
72+
this.countryCode = code;
73+
};
74+
75+
static edit = class Edit extends Component<typeof PhoneField> {
76+
<template>
77+
<PhoneInput
78+
@countryCode={{@model.countryCode}}
79+
@value={{@model.number}}
80+
@onInput={{@model.setNumber}}
81+
@onCountryCodeChange={{@model.setCountryCode}}
82+
/>
83+
</template>
84+
};
85+
86+
static atom = class Atom extends Component<typeof PhoneField> {
87+
<template>
88+
<EntityDisplay @underline={{false}}>
89+
<:title>
90+
{{#if @model.countryCode}}
91+
+{{@model.countryCode}}{{@model.number}}
92+
{{else}}
93+
{{@model.number}}
94+
{{/if}}
95+
</:title>
96+
<:thumbnail>
97+
<PhoneIcon class='icon' />
98+
</:thumbnail>
99+
</EntityDisplay>
100+
<style scoped>
101+
.icon {
102+
color: var(--boxel-400);
103+
}
104+
</style>
105+
</template>
106+
};
107+
108+
static embedded = class Embedded extends Component<typeof PhoneField> {
109+
<template>
110+
{{#if @model.countryCode}}
111+
<span>+{{@model.countryCode}}{{@model.number}}</span>
112+
{{else}}
113+
<span>{{@model.number}}</span>
114+
{{/if}}
115+
</template>
116+
};
117+
}
118+
119+
export class ContactPhoneNumber extends FieldDef {
120+
@field phoneNumber = contains(PhoneField);
121+
@field type = contains(PhoneNumberType);
122+
123+
static atom = class Atom extends Component<typeof ContactPhoneNumber> {
124+
<template>
125+
<EntityDisplay @underline={{false}}>
126+
<:title>
127+
{{#if @model.phoneNumber.countryCode}}
128+
+{{@model.phoneNumber.countryCode}}{{@model.phoneNumber.number}}
129+
{{else}}
130+
{{@model.phoneNumber.number}}
131+
{{/if}}
132+
</:title>
133+
<:thumbnail>
134+
<PhoneIcon class='icon' />
135+
</:thumbnail>
136+
<:tag>
137+
{{#if @model.type.label}}
138+
<Pill class='pill-gray'>
139+
{{@model.type.label}}
140+
</Pill>
141+
{{/if}}
142+
</:tag>
143+
</EntityDisplay>
144+
<style scoped>
145+
.icon {
146+
color: var(--boxel-400);
147+
}
148+
.pill-gray {
149+
--default-pill-padding: 0 var(--boxel-sp-xxxs);
150+
background-color: var(--boxel-200);
151+
border-color: transparent;
152+
}
153+
</style>
154+
</template>
155+
};
156+
157+
static embedded = class Embedded extends Component<
158+
typeof ContactPhoneNumber
159+
> {
160+
<template>
161+
<@fields.phoneNumber @format='embedded' />
162+
</template>
163+
};
164+
}

Diff for: packages/experiments-realm/phone.gts

-124
This file was deleted.

0 commit comments

Comments
 (0)