@axium/contacts 0.1.2 → 0.2.1
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/lib/InitForm.svelte +9 -6
- package/lib/discovery.svelte +21 -0
- package/lib/index.ts +1 -1
- package/locales/en.json +0 -4
- package/package.json +2 -2
- package/lib/Discovery.svelte +0 -101
package/lib/InitForm.svelte
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { text } from '@axium/client';
|
|
3
3
|
import { dynamicRows } from '@axium/client/attachments';
|
|
4
|
-
import { Icon, LocationSelect, ZodInput } from '@axium/client/components';
|
|
4
|
+
import { Icon, LocationSelect, ZodInput, Discovery, discovery } from '@axium/client/components';
|
|
5
5
|
import { ContactURL, Custom, Email, Init, Phone, Relationship, SigDate, type Contact } from '@axium/contacts';
|
|
6
6
|
import ContactPicture from './ContactPicture.svelte';
|
|
7
7
|
import DateSelect from './DateSelect.svelte';
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
8
|
+
import { contactDiscovery } from './discovery.svelte';
|
|
9
|
+
import { format, getContact } from '@axium/contacts/client';
|
|
10
10
|
|
|
11
11
|
let showDetailed = $state(false);
|
|
12
12
|
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
{#if init.id}
|
|
66
66
|
<div class="contact-init-header">
|
|
67
67
|
<ContactPicture contact={init as typeof init & { id: string }} --size="150px" />
|
|
68
|
-
<span class="contact-name-title">{
|
|
68
|
+
<span class="contact-name-title">{format.name(init)}</span>
|
|
69
69
|
</div>
|
|
70
70
|
{/if}
|
|
71
71
|
|
|
@@ -140,8 +140,11 @@
|
|
|
140
140
|
{#if i}<span />{/if}
|
|
141
141
|
<div class="section">
|
|
142
142
|
<Discovery
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
onSelect={result => (rel.to = result.contact.id)}
|
|
144
|
+
sources={[contactDiscovery]}
|
|
145
|
+
exclude={target =>
|
|
146
|
+
[init.id, ...init.relationships.map(r => r.to)].filter((v): v is string => !!v).includes(target.contact.id)}
|
|
147
|
+
initialValue={format.name(await getContact(rel.to))}
|
|
145
148
|
/>
|
|
146
149
|
<ZodInput
|
|
147
150
|
bind:rootValue={init}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { discovery } from '@axium/client/components';
|
|
3
|
+
import { fetchAPI } from '@axium/client/requests';
|
|
4
|
+
import type { NoExternal } from '@axium/contacts';
|
|
5
|
+
import { format } from '@axium/contacts/client';
|
|
6
|
+
|
|
7
|
+
export const contactDiscovery: discovery.Source<{ contact: NoExternal }> = {
|
|
8
|
+
name: 'contact',
|
|
9
|
+
async get(search) {
|
|
10
|
+
const contacts = await fetchAPI('POST', 'contact-discovery', search);
|
|
11
|
+
return contacts.map(contact => ({ contact }));
|
|
12
|
+
},
|
|
13
|
+
get render() {
|
|
14
|
+
return renderContact;
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
{#snippet renderContact(result: { contact: NoExternal })}
|
|
20
|
+
<span>{format.name(result.contact)}</span>
|
|
21
|
+
{/snippet}
|
package/lib/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { default as ContactCard } from './ContactCard.svelte';
|
|
2
2
|
export { default as ContactPicture } from './ContactPicture.svelte';
|
|
3
3
|
export { default as DateSelect } from './DateSelect.svelte';
|
|
4
|
-
export {
|
|
4
|
+
export { contactDiscovery } from './discovery.svelte';
|
|
5
5
|
export { default as Field } from './Field.svelte';
|
|
6
6
|
export { default as InitForm } from './InitForm.svelte';
|
|
7
7
|
export { default as List } from './List.svelte';
|
package/locales/en.json
CHANGED
|
@@ -39,10 +39,6 @@
|
|
|
39
39
|
"toast_updated": "Updated contact picture",
|
|
40
40
|
"toast_removed": "Removed contact picture"
|
|
41
41
|
},
|
|
42
|
-
"Discovery": {
|
|
43
|
-
"placeholder": "Search for a contact",
|
|
44
|
-
"no_results": "No contacts found"
|
|
45
|
-
},
|
|
46
42
|
"delete_confirm": "Are you sure you want to delete this contact?"
|
|
47
43
|
},
|
|
48
44
|
"contact": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axium/contacts",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"author": "James Prevett <axium@jamespre.dev>",
|
|
5
5
|
"description": "Contacts for Axium",
|
|
6
6
|
"funding": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"build": "tsc"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"@axium/client": ">=0.
|
|
41
|
+
"@axium/client": ">=0.23.1",
|
|
42
42
|
"@axium/core": ">=0.26.0",
|
|
43
43
|
"@axium/server": ">=0.42.0",
|
|
44
44
|
"@sveltejs/kit": "^2.27.3",
|
package/lib/Discovery.svelte
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { text } from '@axium/client';
|
|
3
|
-
import { fetchAPI } from '@axium/client/requests';
|
|
4
|
-
import type { NoExternal } from '@axium/contacts';
|
|
5
|
-
import { format } from '@axium/contacts/client';
|
|
6
|
-
import { errorText } from 'ioium';
|
|
7
|
-
|
|
8
|
-
const { onSelect, exclude = [] }: { onSelect(id: string): unknown; exclude?: string[] } = $props();
|
|
9
|
-
|
|
10
|
-
let results = $state<NoExternal[]>([]),
|
|
11
|
-
value = $state<string>(),
|
|
12
|
-
gotError = $state<boolean>(false);
|
|
13
|
-
|
|
14
|
-
async function oninput() {
|
|
15
|
-
if (!value || !value.length) {
|
|
16
|
-
results = [];
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
results = await fetchAPI('POST', 'contact-discovery', value);
|
|
22
|
-
} catch (e) {
|
|
23
|
-
gotError = true;
|
|
24
|
-
console.warn('Can not use contact discovery:', errorText(e));
|
|
25
|
-
results = [];
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function select(target: NoExternal) {
|
|
30
|
-
return (e: Event) => {
|
|
31
|
-
e.stopPropagation();
|
|
32
|
-
onSelect(target.id);
|
|
33
|
-
results = [];
|
|
34
|
-
value = format.name(target);
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
</script>
|
|
38
|
-
|
|
39
|
-
<input bind:value type="text" placeholder={text('contacts.Discovery.placeholder')} {oninput} />
|
|
40
|
-
{#if !gotError && value}
|
|
41
|
-
<!-- Don't show results when we can't use the discovery API -->
|
|
42
|
-
<div class="results">
|
|
43
|
-
{#each results as result}
|
|
44
|
-
{#if !exclude.includes(result.id)}
|
|
45
|
-
<div class="result" onclick={select(result)}>
|
|
46
|
-
<span>{format.name(result)}</span>
|
|
47
|
-
</div>
|
|
48
|
-
{/if}
|
|
49
|
-
{:else}
|
|
50
|
-
<i>{text('contacts.Discovery.no_results')}</i>
|
|
51
|
-
{/each}
|
|
52
|
-
</div>
|
|
53
|
-
{/if}
|
|
54
|
-
|
|
55
|
-
<style>
|
|
56
|
-
:host {
|
|
57
|
-
anchor-scope: --discovery-input;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
input {
|
|
61
|
-
anchor-name: --discovery-input;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
input:focus + .results,
|
|
65
|
-
.results:active {
|
|
66
|
-
display: flex;
|
|
67
|
-
animation: var(--A-zoom);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.results {
|
|
71
|
-
position: fixed;
|
|
72
|
-
position-anchor: --discovery-input;
|
|
73
|
-
inset: anchor(bottom) anchor(right) auto anchor(left);
|
|
74
|
-
display: none;
|
|
75
|
-
flex-direction: column;
|
|
76
|
-
gap: 0.25em;
|
|
77
|
-
height: fit-content;
|
|
78
|
-
max-height: 25em;
|
|
79
|
-
background-color: var(--bg-accent);
|
|
80
|
-
border-radius: 0.25em 0.25em 0.75em 0.75em;
|
|
81
|
-
padding: 1em;
|
|
82
|
-
border: var(--border-accent);
|
|
83
|
-
align-items: stretch;
|
|
84
|
-
|
|
85
|
-
i {
|
|
86
|
-
text-align: center;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
.result {
|
|
91
|
-
padding: 0.25em 0.75em;
|
|
92
|
-
border-radius: 0.5em;
|
|
93
|
-
display: inline-flex;
|
|
94
|
-
align-items: center;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.result:hover {
|
|
98
|
-
cursor: pointer;
|
|
99
|
-
background-color: var(--bg-strong);
|
|
100
|
-
}
|
|
101
|
-
</style>
|