diff --git a/src/lib/helpers/types/knowledgeTypes.js b/src/lib/helpers/types/knowledgeTypes.js index 00347c9d..5fddff54 100644 --- a/src/lib/helpers/types/knowledgeTypes.js +++ b/src/lib/helpers/types/knowledgeTypes.js @@ -25,6 +25,7 @@ * @property {boolean} [with_vector] - Include vector or not. * @property {string[]} [fields] - Included payload fields. * @property {VectorFilterGroup[]} [filter_groups] - Search filter groups. + * @property {VectorSort?} [order_by] - Sort by. */ /** @@ -33,6 +34,12 @@ * @property {{ key: string, value: string }[]} [filters] - Search filters. */ +/** + * @typedef {Object} VectorSort + * @property {string?} [field] - The sort field. + * @property {string?} [order] - The sort order. + */ + /** * @typedef {Object} KnowledgeSearchViewModel * @property {string} id - The knowledge data id. diff --git a/src/lib/scss/custom/pages/_knowledgebase.scss b/src/lib/scss/custom/pages/_knowledgebase.scss index 7d1f554d..4452f9c2 100644 --- a/src/lib/scss/custom/pages/_knowledgebase.scss +++ b/src/lib/scss/custom/pages/_knowledgebase.scss @@ -420,6 +420,24 @@ } } } + + .operator-container { + margin-top: 20px; + + .operator-item { + display: flex; + + @media (max-width: 420px) { + flex-direction: column; + gap: 10px !important; + text-align: center; + } + + .operator-title { + width: 120px; + } + } + } } diff --git a/src/routes/page/knowledge-base/common/search/advanced-search.svelte b/src/routes/page/knowledge-base/common/search/advanced-search.svelte index 22304bd3..c2963bc5 100644 --- a/src/routes/page/knowledge-base/common/search/advanced-search.svelte +++ b/src/routes/page/knowledge-base/common/search/advanced-search.svelte @@ -13,6 +13,12 @@ /** @type {string} */ export let operator = 'or'; + /** @type {string} */ + export let sortOrder = "desc"; + + /** @type {string} */ + export let sortField = ''; + /** @type {number} */ export let maxLength = 1000; @@ -37,6 +43,21 @@ } ]; + const sortDirections = [ + { + id: 'sort-asc', + value: 'asc', + label: 'ASC', + tip: 'Ascending sort.' + }, + { + id: 'sort-desc', + value: 'desc', + label: 'DESC', + tip: 'Descending sort.' + } + ]; + /** @type {HTMLElement} */ let scrollContainer; @@ -120,13 +141,6 @@ }); } } - - /** - * @param {any} e - */ - function changeLogicalOperator(e) { - operator = e.target.value; - } @@ -242,31 +256,77 @@ {/if} -
-
- Search operator: - {#each logicalOperators as op, idx (idx)} -
- changeLogicalOperator(e)} - /> - -
- {/each} +
+
+
Search operator:
+
+ {#each logicalOperators as op, idx (idx)} +
+ + +
+ {/each} +
+
+
+ +
+
+
Sort by field:
+
+ +
+
+
+
+
+ {#each sortDirections as op, idx (idx)} +
+ + +
+ {/each} +
{/if} diff --git a/src/routes/page/knowledge-base/documents/+page.svelte b/src/routes/page/knowledge-base/documents/+page.svelte index b582e5da..5f9d01df 100644 --- a/src/routes/page/knowledge-base/documents/+page.svelte +++ b/src/routes/page/knowledge-base/documents/+page.svelte @@ -48,14 +48,6 @@ const step = 0.1; const enableVector = true; const collectionType = KnowledgeCollectionType.Document; - const includedPayloads = [ - KnowledgePayloadName.Text, - KnowledgePayloadName.FileId, - KnowledgePayloadName.FileName, - KnowledgePayloadName.DataSource, - KnowledgePayloadName.FileSource, - KnowledgePayloadName.FileUrl - ]; /** @type {string} */ let text = ""; @@ -91,6 +83,14 @@ /** @type {import('$knowledgeTypes').VectorFilterGroup[]} */ let innerSearchGroups = []; + let sortField = ''; + let sortOrder = 'desc'; + /** @type {import('$knowledgeTypes').VectorSort?} */ + let innerSort = { + field: '', + order: 'desc' + }; + /** @type {boolean} */ let showDemo = true; let isSearching = false; @@ -114,7 +114,8 @@ * isReset: boolean, * isLocalLoading: boolean, * skipLoader: boolean, - * filterGroups: any[] + * filterGroups: any[], + * sort: any * }} */ const defaultParams = { @@ -122,7 +123,8 @@ isReset: false, isLocalLoading: false, skipLoader: false, - filterGroups: [] + filterGroups: [], + sort: null }; $: disabled = isLoading || isLoadingMore || isSearching; @@ -149,7 +151,8 @@ ...defaultParams, isReset: true, skipLoader: true, - filterGroups: innerSearchGroups + filterGroups: innerSearchGroups, + sort: null }).finally(() => isLoading = false); }).finally(() => { isLoading = false; @@ -173,13 +176,15 @@ isFromSearch = false; innerSearchGroups = buildSearchFilterGroups(searchItems); + innerSort = buildSearchSort(sortField, sortOrder); if (textSearch) { getData({ ...defaultParams, isReset: true, skipLoader: true, - filterGroups: innerSearchGroups + filterGroups: innerSearchGroups, + sort: innerSort }).then(() => { isFromSearch = true; }).finally(() => { @@ -226,7 +231,8 @@ startId: null, isReset: true, skipLoader: skipLoader, - filterGroups: innerSearchGroups + filterGroups: innerSearchGroups, + sort: innerSort }); } @@ -249,6 +255,12 @@ textSearch = false; selectedOperator = 'or'; innerSearchGroups = []; + sortField = ''; + sortOrder = 'desc'; + innerSort = { + field: sortField, + order: sortOrder + }; } @@ -316,12 +328,14 @@ * @param {{ * startId: string | null, * isReset: boolean, - * filterGroups: any[] }} params + * filterGroups: any[], + * sort: any }} params */ function getKnowledgeListData(params = { startId: null, isReset: false, - filterGroups: [] + filterGroups: [], + sort: null }) { return new Promise((resolve, reject) => { const filter = { @@ -329,7 +343,8 @@ start_id: params.startId, with_vector: enableVector, fields: [], - filter_groups: params.filterGroups + filter_groups: params.filterGroups, + order_by: !!params.sort?.field ? params.sort : null }; getVectorKnowledgePageList( @@ -358,14 +373,16 @@ * isReset: boolean, * isLocalLoading: boolean, * skipLoader: boolean, - * filterGroups: any[] }} params + * filterGroups: any[], + * sort: any }} params */ function getData(params = { startId: null, isReset: false, isLocalLoading: false, skipLoader: false, - filterGroups: [] + filterGroups: [], + sort: null }) { return new Promise((resolve, reject) => { if (!params.skipLoader) { @@ -404,7 +421,8 @@ ...defaultParams, startId: nextId || null, isLocalLoading: true, - filterGroups: innerSearchGroups + filterGroups: innerSearchGroups, + sort: innerSort }; getData(params); } @@ -713,11 +731,25 @@ if (isAdvSearchOn && items?.length > 0) { const validItems = items.filter(x => x.checked && !!util.trim(x.key) && !!util.trim(x.value)) .map(x => ({ key: util.trim(x.key), value: util.trim(x.value) })); - groups = [ ...groups, { filter_operator: selectedOperator, filters: validItems } ]; + + if (validItems.length > 0) { + groups = [ ...groups, { filter_operator: selectedOperator, filters: validItems } ]; + } } return groups; } + + /** + * @param {string} field + * @param {string} order + */ + function buildSearchSort(field, order) { + return isAdvSearchOn ? { + field: field, + order: order + } : null; + } @@ -889,6 +921,8 @@ bind:showAdvSearch={isAdvSearchOn} bind:items={searchItems} bind:operator={selectedOperator} + bind:sortField={sortField} + bind:sortOrder={sortOrder} disabled={disabled} /> diff --git a/src/routes/page/knowledge-base/question-answer/+page.svelte b/src/routes/page/knowledge-base/question-answer/+page.svelte index 8b8aec28..876ecc9b 100644 --- a/src/routes/page/knowledge-base/question-answer/+page.svelte +++ b/src/routes/page/knowledge-base/question-answer/+page.svelte @@ -43,11 +43,6 @@ const step = 0.1; const enableVector = true; const collectionType = KnowledgeCollectionType.QuestionAnswer; - const includedPayloads = [ - KnowledgePayloadName.Text, - KnowledgePayloadName.Answer, - KnowledgePayloadName.DataSource - ]; /** @type {string} */ let text = ""; @@ -83,6 +78,14 @@ /** @type {import('$knowledgeTypes').VectorFilterGroup[]} */ let innerSearchGroups = []; + let sortField = ''; + let sortOrder = 'desc'; + /** @type {import('$knowledgeTypes').VectorSort?} */ + let innerSort = { + field: '', + order: 'desc' + }; + /** @type {boolean} */ let showDemo = true; let isSearching = false; @@ -103,7 +106,8 @@ * isReset: boolean, * isLocalLoading: boolean, * skipLoader: boolean, - * filterGroups: any[] + * filterGroups: any[], + * sort: any * }} */ const defaultParams = { @@ -111,7 +115,8 @@ isReset: false, isLocalLoading: false, skipLoader: false, - filterGroups: [] + filterGroups: [], + sort: null }; $: disabled = isLoading || isLoadingMore || isSearching; @@ -137,7 +142,8 @@ ...defaultParams, isReset: true, skipLoader: true, - filterGroups: innerSearchGroups + filterGroups: innerSearchGroups, + sort: null }).finally(() => isLoading = false); }).finally(() => { isLoading = false; @@ -161,13 +167,15 @@ isFromSearch = false; innerSearchGroups = buildSearchFilterGroups(searchItems); + innerSort = buildSearchSort(sortField, sortOrder); if (textSearch) { getData({ ...defaultParams, isReset: true, skipLoader: true, - filterGroups: innerSearchGroups + filterGroups: innerSearchGroups, + sort: innerSort }).then(() => { isFromSearch = true; }).finally(() => { @@ -214,7 +222,8 @@ startId: null, isReset: true, skipLoader: skipLoader, - filterGroups: innerSearchGroups + filterGroups: innerSearchGroups, + sort: innerSort }); } @@ -237,6 +246,12 @@ textSearch = false; selectedOperator = 'or'; innerSearchGroups = []; + sortField = ''; + sortOrder = 'desc'; + innerSort = { + field: sortField, + order: sortOrder + }; } @@ -304,12 +319,14 @@ * @param {{ * startId: string | null, * isReset: boolean, - * filterGroups: any[] }} params + * filterGroups: any[], + * sort: any }} params */ function getKnowledgeListData(params = { startId: null, isReset: false, - filterGroups: [] + filterGroups: [], + sort: null }) { return new Promise((resolve, reject) => { const filter = { @@ -317,7 +334,8 @@ start_id: params.startId, with_vector: enableVector, fields: [], - filter_groups: params.filterGroups + filter_groups: params.filterGroups, + order_by: !!params.sort?.field ? params.sort : null }; getVectorKnowledgePageList( @@ -346,14 +364,16 @@ * isReset: boolean, * isLocalLoading: boolean, * skipLoader: boolean, - * filterGroups: any[] }} params + * filterGroups: any[], + * sort: any }} params */ function getData(params = { startId: null, isReset: false, isLocalLoading: false, skipLoader: false, - filterGroups: [] + filterGroups: [], + sort: null }) { return new Promise((resolve, reject) => { if (!params.skipLoader) { @@ -392,7 +412,8 @@ ...defaultParams, startId: nextId || null, isLocalLoading: true, - filterGroups: innerSearchGroups + filterGroups: innerSearchGroups, + sort: innerSort }; getData(params); } @@ -662,11 +683,25 @@ if (isAdvSearchOn && items?.length > 0) { const validItems = items.filter(x => x.checked && !!util.trim(x.key) && !!util.trim(x.value)) .map(x => ({ key: util.trim(x.key), value: util.trim(x.value) })); - groups = [ ...groups, { filter_operator: selectedOperator, filters: validItems } ]; + + if (validItems.length > 0) { + groups = [ ...groups, { filter_operator: selectedOperator, filters: validItems } ]; + } } return groups; } + + /** + * @param {string} field + * @param {string} order + */ + function buildSearchSort(field, order) { + return isAdvSearchOn ? { + field: field, + order: order + } : null; + } @@ -840,6 +875,8 @@ bind:showAdvSearch={isAdvSearchOn} bind:items={searchItems} bind:operator={selectedOperator} + bind:sortField={sortField} + bind:sortOrder={sortOrder} disabled={disabled} />