Skip to content

Commit 2aeef13

Browse files
authored
Merge pull request #310 from iceljc/features/refine-chat-window
refine time and state search
2 parents c71eed8 + be6cbd8 commit 2aeef13

File tree

8 files changed

+155
-55
lines changed

8 files changed

+155
-55
lines changed

src/lib/common/RemoteSearchInput.svelte

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
export let disabled = false;
1818
/** @type {boolean} */
1919
export let loading = false;
20+
/** @type {number} */
21+
export let maxLength = 2000;
2022
/** @type {(query: string) => Promise<string[]>} */
2123
export let onSearch = query => Promise.resolve([]);
2224
@@ -67,7 +69,7 @@
6769
toggle={() => (isOpen = !isOpen)}
6870
>
6971
<DropdownToggle tag="div">
70-
<Input type="text" {value} on:input={handleInput} {disabled} {placeholder} />
72+
<Input type="text" {value} on:input={handleInput} maxlength={maxLength} {disabled} {placeholder} />
7173
</DropdownToggle>
7274
<DropdownMenu class="w-100 thin-scrollbar">
7375
{#if loading}

src/lib/helpers/http.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ axios.interceptors.response.use(
3737
(error) => {
3838
loaderStore.set(false);
3939
const user = getUserStore();
40-
console.log('error', error);
40+
4141
const isExpired = Date.now() / 1000 > user.expires;
4242
if (isExpired || (error.response && error.response.status === 401)) {
4343
redirectToLogin();

src/lib/scss/custom/pages/_conversation.scss

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,29 @@
3535
max-height: 300px;
3636
}
3737

38+
.state-search-btn-wrapper {
39+
.state-search-btn {
40+
display: flex;
41+
justify-content: center;
42+
gap: 3px;
43+
flex-wrap: wrap;
44+
45+
@media (max-width: 800px) {
46+
.search-btn-text {
47+
display: none;
48+
}
49+
}
50+
}
51+
}
52+
3853
.state-search-container {
3954
display: flex;
55+
flex-direction: column;
4056
gap: 10px;
41-
justify-content: flex-end;
57+
58+
.state-search-item {
59+
display: flex;
60+
gap: 10px;
61+
justify-content: flex-end;
62+
}
4263
}

src/routes/page/agent/[agentId]/agent-components/agent-overview.svelte

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { Button, Card, CardBody, CardHeader, Input, Table } from '@sveltestrap/sveltestrap';
44
import { _ } from 'svelte-i18n'
55
import InPlaceEdit from '$lib/common/InPlaceEdit.svelte'
6-
import { format } from '$lib/helpers/datetime';
6+
import { utcToLocal } from '$lib/helpers/datetime';
77
import { AgentType } from '$lib/helpers/enums';
88
import { AgentExtensions } from '$lib/helpers/utils/agent';
99
@@ -103,7 +103,7 @@
103103
<h5 class="mt-1 mb-1 div-center">
104104
<InPlaceEdit bind:value={agent.name} on:input={handleAgentChange} />
105105
</h5>
106-
<p class="text-muted mb-0">{`Updated at ${format(agent.updated_datetime, 'time')}`}</p>
106+
<p class="text-muted mb-0">{`Updated at ${utcToLocal(agent.updated_datetime)}`}</p>
107107
</div>
108108
</CardHeader>
109109
<CardBody>
@@ -270,7 +270,7 @@
270270
</tr>
271271
<tr>
272272
<th class="agent-prop-key">Created Date</th>
273-
<td>{format(agent.created_datetime, 'time')}</td>
273+
<td>{utcToLocal(agent.created_datetime)}</td>
274274
</tr>
275275
</tbody>
276276
</Table>

src/routes/page/agent/card-agent.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script>
22
import Link from "svelte-link";
33
import { Badge, Card, CardBody, Col } from '@sveltestrap/sveltestrap';
4-
import { format } from '$lib/helpers/datetime';
4+
import { utcToLocal } from '$lib/helpers/datetime';
55
import { _ } from 'svelte-i18n';
66
import { LEARNER_ID } from "$lib/helpers/constants";
77
import { AgentExtensions } from "$lib/helpers/utils/agent";
@@ -87,7 +87,7 @@
8787
</li>
8888
<li class="list-inline-item me-1 mt-1 mb-1" id="dueDate">
8989
<i class="bx bx-calendar me-1" />
90-
{format(agent.updated_datetime, 'short-date')}
90+
{utcToLocal(agent.updated_datetime, 'MMM D, YYYY')}
9191
</li>
9292
<li class="list-inline-item me-1 mt-1 mb-1">
9393
<Link href="page/agent/{agent.id}/build" class="btn btn-primary btn-sm" target="_blank" disabled>

src/routes/page/conversation/+page.svelte

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,17 @@
2020
import { getConversations, deleteConversation, getConversationStateSearchKeys } from '$lib/services/conversation-service.js';
2121
import { utcToLocal } from '$lib/helpers/datetime';
2222
import { ConversationChannel } from '$lib/helpers/enums';
23-
import RemoteSearchInput from '$lib/common/RemoteSearchInput.svelte';
23+
import StateSearch from './state-search.svelte';
2424
25-
let isLoading = false;
26-
let isComplete = false;
2725
const duration = 3000;
2826
const firstPage = 1;
2927
const pageSize = 15;
3028
29+
/** @type {boolean} */
30+
let isLoading = false;
31+
let isComplete = false;
32+
let showStateSearch = false;
33+
3134
/** @type {import('$commonTypes').PagedItems<import('$conversationTypes').ConversationModel>} */
3235
let conversations = { count: 0, items: [] };
3336
@@ -69,11 +72,10 @@
6972
tags: []
7073
};
7174
72-
/** @type {string} */
73-
let stateKey = "";
74-
75-
/** @type {string | null} */
76-
let stateValue = null;
75+
/** @type {{key: string, value: string | null}[]} */
76+
let states = [
77+
{ key: '', value: ''}
78+
];
7779
7880
onMount(async () => {
7981
isLoading = true;
@@ -214,17 +216,11 @@
214216
* @param {any} e
215217
*/
216218
function handleConfirmStateModal(e) {
217-
if (stateKey) {
218-
searchOption.states = [
219-
{
220-
key: { data: stateKey, isValid: true },
221-
value: { data: stateValue || '', isValid: true },
222-
active_rounds: {data: -1, isValid: true},
223-
}
224-
];
225-
} else {
226-
searchOption.states = [];
227-
}
219+
searchOption.states = states.filter(x => !!lodash.trim(x.key)).map(x => ({
220+
key: { data: x.key, isValid: true },
221+
value: { data: x.value || '', isValid: true },
222+
active_rounds: {data: -1, isValid: true},
223+
}));
228224
handleSearchStates();
229225
searchConversations(e);
230226
}
@@ -251,12 +247,12 @@
251247
}
252248
253249
function getSearchStates() {
254-
return searchOption.states?.map(x => {
255-
return {
256-
key: x.key?.data,
257-
value: x.value?.data
258-
};
259-
}) || [];
250+
searchOption.states = states?.filter(x => !!lodash.trim(x.key))?.map(x => ({
251+
key: { data: x.key, isValid: true },
252+
value: { data: x.value || '', isValid: true },
253+
active_rounds: {data: -1, isValid: true},
254+
})) || [];
255+
return searchOption.states.map(x => ({ key: x.key.data, value: x.value.data }));;
260256
}
261257
262258
function handleSearchStates() {
@@ -358,30 +354,30 @@
358354
<div class="mb-0 card-title flex-grow-0">
359355
<h5 class="mb-0">{$_('Conversation List')}</h5>
360356
</div>
361-
<div>
362-
<div class="state-search-container">
363-
<div>
364-
<RemoteSearchInput
365-
bind:value={stateKey}
366-
onSearch={e => handleStateSearch(e)}
367-
placeholder="Search States"
368-
/>
369-
</div>
370-
<div>
371-
<Input
372-
type="text"
373-
bind:value={stateValue}
374-
disabled={!stateKey}
375-
placeholder="Enter a value"
376-
/>
377-
</div>
378-
<div>
379-
<Button color="primary" on:click={handleConfirmStateModal}>Confirm</Button>
357+
<div class="state-search-btn-wrapper">
358+
<Button
359+
color={showStateSearch ? 'secondary' : 'primary'}
360+
on:click={() => showStateSearch = !showStateSearch}
361+
>
362+
<div class="state-search-btn">
363+
<div>
364+
{#if showStateSearch}
365+
<i class="bx bx-hide" />
366+
{:else}
367+
<i class="bx bx-search-alt" />
368+
{/if}
369+
</div>
370+
<div class="search-btn-text">{'State Search'}</div>
380371
</div>
381-
</div>
372+
</Button>
382373
</div>
383374
</div>
384375
</CardBody>
376+
{#if showStateSearch}
377+
<CardBody class="border-bottom" style="display: flex; justify-content: flex-end;">
378+
<StateSearch bind:states={states} onSearch={q => handleStateSearch(q)}/>
379+
</CardBody>
380+
{/if}
385381
<CardBody class="border-bottom">
386382
<Row class="g-3">
387383
<Col lg="3">

src/routes/page/conversation/[conversationId]/conv-overview.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script>
22
import { Button, Card, CardBody, CardTitle} from '@sveltestrap/sveltestrap';
3-
import { format } from '$lib/helpers/datetime';
3+
import { utcToLocal } from '$lib/helpers/datetime';
44
import { _ } from 'svelte-i18n'
55
66
/** @type {import('$conversationTypes').ConversationModel} */
@@ -12,7 +12,7 @@
1212
<div class="text-center">
1313
<!--<img src={adobephotoshop} alt="" height="50" class="mx-auto d-block" />-->
1414
<h5 class="mt-3 mb-1">{conversation.title}</h5>
15-
<p class="text-muted mb-0">{format(conversation.created_time, 'time')}</p>
15+
<p class="text-muted mb-0">{utcToLocal(conversation.created_time)}</p>
1616
</div>
1717

1818
<ul class="list-unstyled mt-4">
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<script>
2+
import { fly } from 'svelte/transition';
3+
import RemoteSearchInput from "$lib/common/RemoteSearchInput.svelte";
4+
import { Button, Input } from "@sveltestrap/sveltestrap";
5+
6+
const limit = 5;
7+
8+
/** @type {{key: string, value: string | null}[]} */
9+
export let states = [];
10+
11+
/** @type {number} */
12+
export let maxLength = 3000;
13+
14+
/** @type {(e: string) => Promise<string[]>} */
15+
export let onSearch = e => Promise.resolve([]);
16+
17+
18+
/** @param {number} idx */
19+
function removeState(idx) {
20+
states = states.filter((_, index) => index !== idx);
21+
}
22+
23+
function addState() {
24+
states = [
25+
...states,
26+
{ key: '', value: ''}
27+
];
28+
}
29+
</script>
30+
31+
32+
<div
33+
class="state-search-container"
34+
in:fly={{ y: -10, duration: 500 }}
35+
out:fly={{ y: -10, duration: 200 }}
36+
>
37+
{#each states as state, idx}
38+
<div class="state-search-item">
39+
<div>
40+
<RemoteSearchInput
41+
bind:value={state.key}
42+
maxLength={maxLength}
43+
onSearch={e => onSearch(e)}
44+
placeholder="Search States"
45+
/>
46+
</div>
47+
<div>
48+
<Input
49+
type="text"
50+
bind:value={state.value}
51+
maxlength={maxLength}
52+
disabled={!state.key}
53+
placeholder="Enter a value"
54+
/>
55+
</div>
56+
<div class="state-delete line-align-center" style="flex: 0 0 13px;">
57+
<div>
58+
<!-- svelte-ignore a11y-click-events-have-key-events -->
59+
<!-- svelte-ignore a11y-no-static-element-interactions -->
60+
<i
61+
class="bx bx-no-entry text-danger clickable"
62+
class:hide={idx === 0}
63+
on:click={() => removeState(idx)}
64+
/>
65+
</div>
66+
</div>
67+
</div>
68+
{/each}
69+
{#if states.length < limit}
70+
<div>
71+
<Button
72+
color="link"
73+
style="padding-left: 0px;"
74+
on:click={() => addState()}
75+
>
76+
Add +
77+
</Button>
78+
</div>
79+
{/if}
80+
</div>
81+

0 commit comments

Comments
 (0)