From 76d80fe29c036e282d5e040da912609578d9d6b0 Mon Sep 17 00:00:00 2001 From: trean Date: Mon, 7 Sep 2026 18:33:01 +0200 Subject: [PATCH 1/2] update indexing fields dialog --- src/components/Points/PayloadIndexDialog.jsx | 117 +++++++++++++++++++ src/lib/payload-index-helpers.js | 13 +++ src/lib/tests/payload-index-helpers.test.js | 26 ++++- 3 files changed, 154 insertions(+), 2 deletions(-) diff --git a/src/components/Points/PayloadIndexDialog.jsx b/src/components/Points/PayloadIndexDialog.jsx index 04d8de787..e6037d69d 100644 --- a/src/components/Points/PayloadIndexDialog.jsx +++ b/src/components/Points/PayloadIndexDialog.jsx @@ -34,14 +34,78 @@ const FIELD_TYPES = ['keyword', 'integer', 'float', 'uuid', 'datetime', 'text', const TEXT_TOKENIZERS = ['prefix', 'whitespace', 'word', 'multilingual']; +// Snowball stemmer languages supported by Qdrant. +const STEMMER_LANGUAGES = [ + 'none', + 'arabic', + 'armenian', + 'danish', + 'dutch', + 'english', + 'finnish', + 'french', + 'german', + 'greek', + 'hungarian', + 'italian', + 'norwegian', + 'portuguese', + 'romanian', + 'russian', + 'spanish', + 'swedish', + 'tamil', + 'turkish', +]; + +// Stopword languages supported by Qdrant. +const STOPWORDS_LANGUAGES = [ + 'none', + 'arabic', + 'azerbaijani', + 'basque', + 'bengali', + 'catalan', + 'chinese', + 'danish', + 'dutch', + 'english', + 'finnish', + 'french', + 'german', + 'greek', + 'hebrew', + 'hinglish', + 'hungarian', + 'indonesian', + 'italian', + 'japanese', + 'kazakh', + 'nepali', + 'norwegian', + 'portuguese', + 'romanian', + 'russian', + 'slovene', + 'spanish', + 'swedish', + 'tajik', + 'turkish', +]; + const DEFAULT_STATE = { // integer range: true, lookup: true, + // keyword + prefix: false, // text tokenizer: 'whitespace', lowercase: true, phrase_matching: true, + ascii_folding: false, + stemmer_language: 'none', + stopwords: 'none', min_token_len: '', max_token_len: '', }; @@ -60,10 +124,16 @@ function paramsFromSchema(indexInfo) { state.range = params.range ?? true; state.lookup = params.lookup ?? true; } + if (indexInfo?.data_type === 'keyword') { + state.prefix = params.prefix ?? false; + } if (indexInfo?.data_type === 'text') { state.tokenizer = params.tokenizer || 'whitespace'; state.lowercase = params.lowercase ?? true; state.phrase_matching = params.phrase_matching ?? true; + state.ascii_folding = params.ascii_folding ?? false; + state.stemmer_language = params.stemmer?.language ?? 'none'; + state.stopwords = typeof params.stopwords === 'string' ? params.stopwords : 'none'; state.min_token_len = params.min_token_len ?? ''; state.max_token_len = params.max_token_len ?? ''; } @@ -237,6 +307,17 @@ const PayloadIndexDialog = ({ ))} + {selectedType === 'keyword' && ( + + set('prefix', e.target.checked)} size="small" /> + } + label={Prefix matching} + /> + + )} + {selectedType === 'integer' && ( Phrase matching} /> + set('ascii_folding', e.target.checked)} + size="small" + /> + } + label={ASCII folding} + /> + + + + Stemmer + + + + Stopwords + + = 0) params.max_token_len = value; } + + const stemmerLanguage = fieldFormData?.stemmer_language; + if (stemmerLanguage && stemmerLanguage !== 'none') { + params.stemmer = { type: 'snowball', language: stemmerLanguage }; + } + + const stopwords = fieldFormData?.stopwords; + if (stopwords && stopwords !== 'none') { + params.stopwords = stopwords; + } } else if (type === 'integer') { params.range = fieldFormData?.range ?? true; params.lookup = fieldFormData?.lookup ?? true; + } else if (type === 'keyword') { + params.prefix = fieldFormData?.prefix ?? false; } return { name: fieldName, type, params }; diff --git a/src/lib/tests/payload-index-helpers.test.js b/src/lib/tests/payload-index-helpers.test.js index 969e680a1..8fd906bab 100644 --- a/src/lib/tests/payload-index-helpers.test.js +++ b/src/lib/tests/payload-index-helpers.test.js @@ -8,9 +8,14 @@ import { import { createPayloadIndexParams } from '../../components/Collections/CreateCollection/create-collection'; describe('payloadFieldFormToIndexConfig', () => { - it('converts keyword type with no extra params', () => { + it('converts keyword type with prefix defaulting to false', () => { const result = payloadFieldFormToIndexConfig('color', { field_config_enum: 'keyword' }); - expect(result).toEqual({ name: 'color', type: 'keyword', params: {} }); + expect(result).toEqual({ name: 'color', type: 'keyword', params: { prefix: false } }); + }); + + it('converts keyword type with prefix matching enabled', () => { + const result = payloadFieldFormToIndexConfig('color', { field_config_enum: 'keyword', prefix: true }); + expect(result).toEqual({ name: 'color', type: 'keyword', params: { prefix: true } }); }); it('converts integer type with range and lookup', () => { @@ -33,6 +38,9 @@ describe('payloadFieldFormToIndexConfig', () => { lowercase: false, tokenizer: 'word', phrase_matching: false, + ascii_folding: true, + stemmer_language: 'english', + stopwords: 'english', min_token_len: 2, max_token_len: 10, }); @@ -43,6 +51,9 @@ describe('payloadFieldFormToIndexConfig', () => { lowercase: false, tokenizer: 'word', phrase_matching: false, + ascii_folding: true, + stemmer: { type: 'snowball', language: 'english' }, + stopwords: 'english', min_token_len: 2, max_token_len: 10, }, @@ -55,11 +66,22 @@ describe('payloadFieldFormToIndexConfig', () => { lowercase: true, tokenizer: 'whitespace', phrase_matching: true, + ascii_folding: false, }); expect(result.params.min_token_len).toBeUndefined(); expect(result.params.max_token_len).toBeUndefined(); }); + it('omits stemmer and stopwords when set to "none"', () => { + const result = payloadFieldFormToIndexConfig('body', { + field_config_enum: 'text', + stemmer_language: 'none', + stopwords: 'none', + }); + expect(result.params.stemmer).toBeUndefined(); + expect(result.params.stopwords).toBeUndefined(); + }); + it('ignores blank min/max token length values', () => { const result = payloadFieldFormToIndexConfig('body', { field_config_enum: 'text', From d419636d80785edf0b3dd4ec0f77e42a5b84f28d Mon Sep 17 00:00:00 2001 From: trean Date: Wed, 9 Sep 2026 18:56:24 +0200 Subject: [PATCH 2/2] moving new fields under advanced options --- package-lock.json | 135 ++++++++------- src/components/Points/PayloadIndexDialog.jsx | 168 ++++++++++++------- 2 files changed, 190 insertions(+), 113 deletions(-) diff --git a/package-lock.json b/package-lock.json index 882d17093..13116ae8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -121,6 +121,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", @@ -314,6 +315,7 @@ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", "license": "MIT", + "peer": true, "engines": { "node": ">=6.9.0" } @@ -420,6 +422,7 @@ "node_modules/@emotion/react": { "version": "11.14.0", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", @@ -457,6 +460,7 @@ "node_modules/@emotion/styled": { "version": "11.14.1", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", @@ -1322,6 +1326,7 @@ "node_modules/@mui/icons-material": { "version": "7.2.0", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.27.6" }, @@ -1346,6 +1351,7 @@ "node_modules/@mui/material": { "version": "7.2.0", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.27.6", "@mui/core-downloads-tracker": "^7.2.0", @@ -1450,6 +1456,7 @@ "node_modules/@mui/system": { "version": "7.2.0", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.27.6", "@mui/private-theming": "^7.2.0", @@ -2987,8 +2994,7 @@ }, "node_modules/@types/aria-query": { "version": "5.0.4", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -3169,6 +3175,7 @@ "node_modules/@types/react": { "version": "18.3.23", "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -3303,6 +3310,7 @@ "node_modules/@uppy/core": { "version": "4.4.7", "license": "MIT", + "peer": true, "dependencies": { "@transloadit/prettier-bytes": "^0.3.4", "@uppy/store-default": "^4.2.0", @@ -3317,6 +3325,7 @@ "node_modules/@uppy/dashboard": { "version": "4.3.4", "license": "MIT", + "peer": true, "dependencies": { "@transloadit/prettier-bytes": "^0.3.4", "@uppy/informer": "^4.2.1", @@ -3338,6 +3347,7 @@ "node_modules/@uppy/drag-drop": { "version": "4.1.3", "license": "MIT", + "peer": true, "dependencies": { "@uppy/utils": "^6.1.4", "preact": "^10.5.13" @@ -3360,6 +3370,7 @@ "node_modules/@uppy/progress-bar": { "version": "4.2.1", "license": "MIT", + "peer": true, "dependencies": { "@uppy/utils": "^6.1.1", "preact": "^10.5.13" @@ -3493,15 +3504,15 @@ } }, "node_modules/@vitest/expect": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.6.tgz", - "integrity": "sha512-1+7q9BtaKzEmO+fmNT3kYvoNn5Y71XWAx2Q5HRim4tTVRQVRv4uJFAQ5FbK0OPUeNP/WmVCpxYxoJdvuHVjzBQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", + "integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.6", - "@vitest/utils": "3.2.6", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" }, @@ -3510,13 +3521,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.6.tgz", - "integrity": "sha512-EZOrpDbkKotFAP7wPAQV1UIyoGOk4oX7ynWhBhLB7v+meMHbQhU16oPpIYGTTe4oFlhpryGpgpcZP/sin3hYuw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz", + "integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.6", + "@vitest/spy": "3.2.7", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, @@ -3537,9 +3548,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.6.tgz", - "integrity": "sha512-lb7XXXzmm2h2ASzFnRvQpDo6onT1NmMJA3tkGTWiBFtRJ9lxGY3d3mm/Apt36gej2bkkOVLL/yTOtufDaFa/jA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz", + "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==", "dev": true, "license": "MIT", "dependencies": { @@ -3550,13 +3561,13 @@ } }, "node_modules/@vitest/runner": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.6.tgz", - "integrity": "sha512-HYcoSj1w5tcgUnzoF0HcyaAQjpA1gj9ftUJ7iSJSuipc02jW9gKkigwZbjFldAfYHA1fa8UZVRftdMY5msWM9Q==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz", + "integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.2.6", + "@vitest/utils": "3.2.7", "pathe": "^2.0.3", "strip-literal": "^3.0.0" }, @@ -3565,13 +3576,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.6.tgz", - "integrity": "sha512-H+ZjNTWGpObenh0YnlBctAPnJSI20P81PL8BPzWpx54YXLLTm8hEsWawtcYLMrwvpK48hGxLLbCS+1KRXhsKhw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz", + "integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.6", + "@vitest/pretty-format": "3.2.7", "magic-string": "^0.30.17", "pathe": "^2.0.3" }, @@ -3580,9 +3591,9 @@ } }, "node_modules/@vitest/spy": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.6.tgz", - "integrity": "sha512-oq6BbH68WzcWmwtBrU9nqLeaXTR4XwJF7FSLkKEZo4i6eoXcrxjcwSuTvWBIRUTC6VC72nXYunzqgZA+IKdtxg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz", + "integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3593,13 +3604,13 @@ } }, "node_modules/@vitest/utils": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.6.tgz", - "integrity": "sha512-lI23nIs4bnT3T8NIoh+vFaz5s2/DdP0Jgt2jxwgWljvwn82cLJtyi/If+fjFyoLMGIOz0U/fKvWE0d4jsNQEfg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz", + "integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.6", + "@vitest/pretty-format": "3.2.7", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" }, @@ -3629,6 +3640,7 @@ "node_modules/acorn": { "version": "8.15.0", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3877,6 +3889,7 @@ "resolved": "https://registry.npmjs.org/axios/-/axios-1.19.0.tgz", "integrity": "sha512-ht/iuYZXEjFxLH/Hkezgd7m6JKlHHXEUSneaDz8uZe1Gj5QZtCnpyDsckvAiEnT89OEbCLmnte4R4sn7P0EKFw==", "license": "MIT", + "peer": true, "dependencies": { "follow-redirects": "^1.16.0", "form-data": "^4.0.6", @@ -3974,6 +3987,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.11.12", "caniuse-lite": "^1.0.30001809", @@ -4323,7 +4337,7 @@ }, "node_modules/create-collection-form": { "version": "0.0.0", - "resolved": "git+ssh://git@github.com/qdrant/create-collection-form.git#07bb75aa55d01ed06797586a165d1543325e89b8", + "resolved": "git+ssh://git@github.com/qdrant/create-collection-form.git#df676404330e11e7512711c0ad9bcef65da527e4", "dependencies": { "jtd": "^0.1.1" }, @@ -4333,7 +4347,8 @@ "@mui/icons-material": "^7.0.2", "@mui/material": "^7.0.2", "lucide-react": "^0.545.0", - "prop-types": "^15.8.1" + "prop-types": "^15.8.1", + "react": "^18.3.1 || ^19.0.0" } }, "node_modules/cross-spawn": { @@ -4366,7 +4381,8 @@ }, "node_modules/csstype": { "version": "3.1.3", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/d3-array": { "version": "3.2.4", @@ -4484,6 +4500,7 @@ "node_modules/d3-selection": { "version": "3.0.0", "license": "ISC", + "peer": true, "engines": { "node": ">=12" } @@ -5043,6 +5060,7 @@ "version": "8.57.1", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -6755,9 +6773,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", - "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "funding": [ { "type": "github", @@ -6769,6 +6787,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -6780,6 +6799,7 @@ "version": "22.1.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "abab": "^2.0.6", "cssstyle": "^3.0.0", @@ -7225,6 +7245,7 @@ "node_modules/lucide-react": { "version": "0.545.0", "license": "ISC", + "peer": true, "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } @@ -7232,7 +7253,6 @@ "node_modules/lz-string": { "version": "1.5.0", "license": "MIT", - "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -8126,7 +8146,8 @@ }, "node_modules/monaco-editor": { "version": "0.44.0", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/mri": { "version": "1.2.0", @@ -8783,7 +8804,6 @@ "node_modules/pretty-format": { "version": "27.5.1", "license": "MIT", - "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -8796,7 +8816,6 @@ "node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -8806,8 +8825,7 @@ }, "node_modules/pretty-format/node_modules/react-is": { "version": "17.0.2", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/prism-react-renderer": { "version": "2.4.1", @@ -8830,6 +8848,7 @@ "node_modules/prop-types": { "version": "15.8.1", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -8904,6 +8923,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -8973,6 +8993,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -9261,6 +9282,7 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -9977,9 +9999,9 @@ } }, "node_modules/tinyspy": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", - "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.6.tgz", + "integrity": "sha512-u8KszXvGfU68hVcZpRHKG28T0krMuv2G5nDhiHaMLen/gIuFEgIJhaJuO69qjnXg5paSrbPMFfx3brNuN8eVSg==", "dev": true, "license": "MIT", "engines": { @@ -10477,6 +10499,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -10642,20 +10665,20 @@ } }, "node_modules/vitest": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.6.tgz", - "integrity": "sha512-xejya+bT/j/+R/AGa1XOfRxLmNUlLtlwjRsFUILF+xHfzElmGcmFydy2gqqIrd62ptIEfwVMofd19uNWD9L7Nw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz", + "integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.6", - "@vitest/mocker": "3.2.6", - "@vitest/pretty-format": "^3.2.6", - "@vitest/runner": "3.2.6", - "@vitest/snapshot": "3.2.6", - "@vitest/spy": "3.2.6", - "@vitest/utils": "3.2.6", + "@vitest/expect": "3.2.7", + "@vitest/mocker": "3.2.7", + "@vitest/pretty-format": "^3.2.7", + "@vitest/runner": "3.2.7", + "@vitest/snapshot": "3.2.7", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", @@ -10685,8 +10708,8 @@ "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.6", - "@vitest/ui": "3.2.6", + "@vitest/browser": "3.2.7", + "@vitest/ui": "3.2.7", "happy-dom": "*", "jsdom": "*" }, diff --git a/src/components/Points/PayloadIndexDialog.jsx b/src/components/Points/PayloadIndexDialog.jsx index e6037d69d..33bf79906 100644 --- a/src/components/Points/PayloadIndexDialog.jsx +++ b/src/components/Points/PayloadIndexDialog.jsx @@ -18,7 +18,10 @@ import { TextField, InputLabel, FormControl, + Collapse, + Link, } from '@mui/material'; +import { ChevronDown, ChevronRight } from 'lucide-react'; import JsonView from '../Common/JsonViewBase'; import { useTheme } from '@mui/material/styles'; import { useJsonViewerTheme } from '../../theme/json-viewer-theme'; @@ -140,6 +143,24 @@ function paramsFromSchema(indexInfo) { return state; } +/** + * Whether a text params state uses any of the advanced options (kept collapsed + * by default). Used to auto-expand the advanced section when editing an index + * that already relies on them, so no active setting stays hidden. + * + * @param {Object} state - params state + * @return {boolean} true when an advanced option is set + */ +function hasAdvancedTextParams(state) { + return ( + !!state.ascii_folding || + (state.stemmer_language && state.stemmer_language !== 'none') || + (state.stopwords && state.stopwords !== 'none') || + state.min_token_len !== '' || + state.max_token_len !== '' + ); +} + const PayloadIndexDialog = ({ open, onClose, @@ -158,6 +179,7 @@ const PayloadIndexDialog = ({ const [params, setParams] = useState(DEFAULT_STATE); const [loading, setLoading] = useState(false); const [confirmDelete, setConfirmDelete] = useState(false); + const [showAdvanced, setShowAdvanced] = useState(false); const indexInfo = selectedField ? payloadSchema?.[selectedField] : null; const isEditing = !!indexInfo; @@ -173,8 +195,11 @@ const PayloadIndexDialog = ({ if (!open) return; const info = selectedField ? payloadSchema?.[selectedField] : null; if (info) { + const presetParams = paramsFromSchema(info); setSelectedType(info.data_type); - setParams(paramsFromSchema(info)); + setParams(presetParams); + // Reveal advanced options up front when the existing index already uses them. + setShowAdvanced(info.data_type === 'text' && hasAdvancedTextParams(presetParams)); } else { const sample = selectedField && selectedField === fieldName @@ -182,6 +207,7 @@ const PayloadIndexDialog = ({ : availableFields?.find((field) => field.name === selectedField)?.value; setSelectedType(suggestFieldType(sample)); setParams(DEFAULT_STATE); + setShowAdvanced(false); } }, [open, selectedField]); @@ -196,6 +222,7 @@ const PayloadIndexDialog = ({ setSelectedField(null); setSelectedType(null); setParams(DEFAULT_STATE); + setShowAdvanced(false); onClose(); }; @@ -347,7 +374,7 @@ const PayloadIndexDialog = ({ ))} - + Phrase matching} /> - set('ascii_folding', e.target.checked)} + + + setShowAdvanced((prev) => !prev)} + sx={{ + display: 'inline-flex', + alignItems: 'center', + gap: 0.5, + alignSelf: 'flex-start', + color: 'text.secondary', + }} + > + {showAdvanced ? : } + Advanced options + + + + + set('ascii_folding', e.target.checked)} + size="small" + /> + } + label={ASCII folding} + /> + + + Stemmer + + + + Stopwords + + + + + set('min_token_len', e.target.value)} + inputProps={{ min: 1 }} /> - } - label={ASCII folding} - /> - - - - Stemmer - - - - Stopwords - - - - - set('min_token_len', e.target.value)} - inputProps={{ min: 1 }} - /> - set('max_token_len', e.target.value)} - inputProps={{ min: 1 }} - /> - + set('max_token_len', e.target.value)} + inputProps={{ min: 1 }} + /> + + + )}