diff --git a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/ListFormWizardDto.cs b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/ListFormWizardDto.cs index 0aa3f12..cb78695 100644 --- a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/ListFormWizardDto.cs +++ b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/ListFormWizardDto.cs @@ -20,6 +20,14 @@ public class ListFormWizardDto public bool AllowDetail { get; set; } public bool ConfirmDelete { get; set; } + public string DefaultLayout { get; set; } + public bool Grid { get; set; } + public bool Pivot { get; set; } + public bool Tree { get; set; } + public bool Chart { get; set; } + public bool Gantt { get; set; } + public bool Scheduler { get; set; } + public string LanguageTextMenuEn { get; set; } public string LanguageTextMenuTr { get; set; } public string LanguageTextTitleEn { get; set; } diff --git a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/WizardColumnItemInputDto.cs b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/WizardColumnItemInputDto.cs index c2635d9..465d675 100644 --- a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/WizardColumnItemInputDto.cs +++ b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/Wizard/WizardColumnItemInputDto.cs @@ -1,10 +1,12 @@ using System.Data; +using Sozsoft.Platform.Enums; namespace Sozsoft.Platform.ListForms; public class WizardColumnItemInputDto { public string DataField { get; set; } + public string CaptionName { get; set; } public string EditorType { get; set; } public string EditorOptions { get; set; } public string EditorScript { get; set; } @@ -13,4 +15,8 @@ public class WizardColumnItemInputDto public DbType DbSourceType { get; set; } = DbType.String; public string TurkishCaption { get; set; } public string EnglishCaption { get; set; } + public UiLookupDataSourceTypeEnum LookupDataSourceType { get; set; } + public string ValueExpr { get; set; } + public string DisplayExpr { get; set; } + public string LookupQuery { get; set; } } diff --git a/api/src/Sozsoft.Platform.Application/ListForms/ListFormWizardAppService.cs b/api/src/Sozsoft.Platform.Application/ListForms/ListFormWizardAppService.cs index 119d705..7cab680 100644 --- a/api/src/Sozsoft.Platform.Application/ListForms/ListFormWizardAppService.cs +++ b/api/src/Sozsoft.Platform.Application/ListForms/ListFormWizardAppService.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Text.Json; using System.Threading.Tasks; @@ -16,6 +17,7 @@ using static Sozsoft.Platform.PlatformConsts; using System.Data; using Microsoft.Extensions.Configuration; using Sozsoft.Languages; +using Sozsoft.Platform.DynamicData; namespace Sozsoft.Platform.ListForms; @@ -30,7 +32,8 @@ public class ListFormWizardAppService( IRepository repoMenu, IPermissionGrantRepository permissionGrantRepository, IConfiguration configuration, - LanguageTextAppService languageTextAppService + LanguageTextAppService languageTextAppService, + IDynamicDataManager dynamicDataManager ) : PlatformAppService(), IListFormWizardAppService { private readonly IRepository repoListForm = repoListForm; @@ -44,6 +47,7 @@ public class ListFormWizardAppService( private readonly IPermissionGrantRepository permissionGrantRepository = permissionGrantRepository; private readonly IConfiguration _configuration = configuration; private readonly LanguageTextAppService _languageTextAppService = languageTextAppService; + private readonly IDynamicDataManager _dynamicDataManager = dynamicDataManager; private readonly string cultureNameDefault = PlatformConsts.DefaultLanguage; [UnitOfWork] @@ -194,6 +198,10 @@ public class ListFormWizardAppService( await repoListFormField.DeleteManyAsync(existingListFormFields, autoSave: true); } + var tableColumns = await GetTableColumnNamesAsync(input.DataSourceCode, input.SelectCommandType, input.SelectCommand); + var isDeleted = tableColumns.Contains("IsDeleted"); + var isCreated = tableColumns.Contains("CreatorId"); + var listForm = await repoListForm.InsertAsync(new ListForm { ListFormType = ListFormTypeEnum.List, @@ -201,7 +209,7 @@ public class ListFormWizardAppService( ExportJson = WizardConsts.DefaultExportJson, IsSubForm = false, ShowNote = true, - LayoutJson = WizardConsts.DefaultLayoutJson(), + LayoutJson = WizardConsts.DefaultLayoutJson(input.DefaultLayout, input.Grid, input.Pivot, input.Tree, input.Chart, input.Gantt, input.Scheduler), CultureName = LanguageCodes.En, ListFormCode = input.ListFormCode, Name = nameLangKey, @@ -215,7 +223,7 @@ public class ListFormWizardAppService( SelectCommand = input.SelectCommand, KeyFieldName = input.KeyFieldName, KeyFieldDbSourceType = input.KeyFieldDbSourceType, - DefaultFilter = WizardConsts.DefaultFilterJson, + DefaultFilter = isDeleted ? WizardConsts.DefaultFilterJson : null, SortMode = GridOptions.SortModeSingle, FilterRowJson = WizardConsts.DefaultFilterRowJson, HeaderFilterJson = WizardConsts.DefaultHeaderFilterJson, @@ -224,9 +232,9 @@ public class ListFormWizardAppService( SelectionJson = WizardConsts.DefaultSelectionSingleJson, ColumnOptionJson = WizardConsts.DefaultColumnOptionJson(), PermissionJson = WizardConsts.DefaultPermissionJson(code), - DeleteCommand = WizardConsts.DefaultDeleteCommand(input.SelectCommand), - DeleteFieldsDefaultValueJson = WizardConsts.DefaultDeleteFieldsDefaultValueJson(input.KeyFieldDbSourceType), - InsertFieldsDefaultValueJson = WizardConsts.DefaultInsertFieldsDefaultValueJson(input.KeyFieldDbSourceType), + DeleteCommand = isDeleted ? WizardConsts.DefaultDeleteCommand(input.SelectCommand) : null, + DeleteFieldsDefaultValueJson = isDeleted ? WizardConsts.DefaultDeleteFieldsDefaultValueJson(input.KeyFieldDbSourceType) : WizardConsts.DefaultFieldsJsonOnlyId(input.KeyFieldDbSourceType), + InsertFieldsDefaultValueJson = isCreated ? WizardConsts.DefaultInsertFieldsDefaultValueJson(input.KeyFieldDbSourceType) : WizardConsts.DefaultFieldsJsonOnlyId(input.KeyFieldDbSourceType), PagerOptionJson = WizardConsts.DefaultPagerOptionJson, EditingOptionJson = WizardConsts.DefaultEditingOptionJson(titleLangKey, 600, 500, input.AllowDeleting, input.AllowAdding, input.AllowUpdating, input.ConfirmDelete, false, input.AllowDetail), EditingFormJson = editingFormDtos.Count > 0 ? JsonSerializer.Serialize(editingFormDtos) : null, @@ -234,18 +242,16 @@ public class ListFormWizardAppService( // ListFormField - each item in each group becomes a visible field record var fieldOrder = 0; - var captionName = string.Empty; foreach (var group in input.Groups) { foreach (var item in group.Items) { fieldOrder++; - captionName = $"App.Listform.ListformField.{item.DataField}"; await repoListFormField.InsertAsync(new ListFormField { ListFormCode = input.ListFormCode, FieldName = item.DataField, - CaptionName = captionName, + CaptionName = item.CaptionName, Visible = item.DataField != input.KeyFieldName, IsActive = true, AllowSearch = true, @@ -256,9 +262,10 @@ public class ListFormWizardAppService( ColumnCustomizationJson = WizardConsts.DefaultColumnCustomizationJson, ColumnFilterJson = WizardConsts.DefaultColumnFilteringJson, PivotSettingsJson = WizardConsts.DefaultPivotSettingsJson, - }, autoSave: false); + LookupJson = item.LookupQuery.Length > 0 ? WizardConsts.DefaultLookupJson(item.LookupDataSourceType, item.DisplayExpr, item.ValueExpr, item.LookupQuery) : null, + }, autoSave: true); - await CreateLangKey(captionName, item.EnglishCaption, item.TurkishCaption); + await CreateLangKey(item.CaptionName, item.EnglishCaption, item.TurkishCaption); } } @@ -267,24 +274,60 @@ public class ListFormWizardAppService( } + private async Task> GetTableColumnNamesAsync(string dataSourceCode, SelectCommandTypeEnum commandType, string selectCommand) + { + if (commandType == SelectCommandTypeEnum.Query || commandType == SelectCommandTypeEnum.StoredProcedure) + return []; + + var parts = selectCommand.Split('.'); + var schemaName = parts.Length > 1 ? parts[0].Trim('"', '[', ']') : "dbo"; + var tableName = parts[parts.Length - 1].Trim('"', '[', ']'); + + try + { + var (repo, connectionString, dbType) = await _dynamicDataManager.GetAsync(false, dataSourceCode); + + var query = dbType == Sozsoft.Platform.Enums.DataSourceTypeEnum.Postgresql + ? $"SELECT column_name FROM information_schema.columns WHERE table_schema = '{schemaName}' AND table_name = '{tableName}'" + : $"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '{schemaName}' AND TABLE_NAME = '{tableName}'"; + + var rows = await repo.QueryAsync(query, connectionString); + + var columns = new HashSet(StringComparer.OrdinalIgnoreCase); + foreach (var row in rows) + { + var dict = row as IDictionary; + if (dict != null) + { + var key = dict.ContainsKey("COLUMN_NAME") ? "COLUMN_NAME" : "column_name"; + if (dict.TryGetValue(key, out var col) && col != null) + columns.Add(col.ToString()!); + } + } + return columns; + } + catch + { + return []; + } + } + private async Task CreateLangKey(string key, string textEn, string textTr) { var res = PlatformConsts.AppName; - var keyQueryable = await repoLangKey.GetQueryableAsync(); - var langKey = await AsyncExecuter.FirstOrDefaultAsync(keyQueryable.Where(a => a.ResourceName == res && a.Key == key)) - ?? await repoLangKey.InsertAsync(new LanguageKey { ResourceName = res, Key = key }, autoSave: false); + var langKey = await repoLangKey.FirstOrDefaultAsync(a => a.ResourceName == res && a.Key == key) + ?? await repoLangKey.InsertAsync(new LanguageKey { ResourceName = res, Key = key }, autoSave: true); - var textQueryable = await repoLangText.GetQueryableAsync(); - var existingTexts = await AsyncExecuter.ToListAsync( - textQueryable.Where(a => a.ResourceName == res && a.Key == langKey.Key) - ); + var existingTexts = await repoLangText.GetListAsync(a => a.ResourceName == res && a.Key == langKey.Key); - var langTextEn = existingTexts.FirstOrDefault(a => a.CultureName == cultureNameDefault) - ?? await repoLangText.InsertAsync(new LanguageText { ResourceName = res, Key = langKey.Key, CultureName = cultureNameDefault, Value = textEn }, autoSave: false); + var existingEn = existingTexts.FirstOrDefault(a => a.CultureName == cultureNameDefault); + if (existingEn != null) await repoLangText.DeleteAsync(existingEn, autoSave: true); + await repoLangText.InsertAsync(new LanguageText { ResourceName = res, Key = langKey.Key, CultureName = cultureNameDefault, Value = textEn }, autoSave: true); - var langTextTr = existingTexts.FirstOrDefault(a => a.CultureName == LanguageCodes.Tr) - ?? await repoLangText.InsertAsync(new LanguageText { ResourceName = res, Key = langKey.Key, CultureName = LanguageCodes.Tr, Value = textTr }, autoSave: false); + var existingTr = existingTexts.FirstOrDefault(a => a.CultureName == LanguageCodes.Tr); + if (existingTr != null) await repoLangText.DeleteAsync(existingTr, autoSave: true); + await repoLangText.InsertAsync(new LanguageText { ResourceName = res, Key = langKey.Key, CultureName = LanguageCodes.Tr, Value = textTr }, autoSave: true); return langKey; } diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json b/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json index 2674512..cc759e4 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json @@ -16280,6 +16280,42 @@ "en": "Columns load after selecting a Select Command", "tr": "Select Command seçince sütunlar yüklenir" }, + { + "resourceName": "Platform", + "key": "ListForms.Wizard.Step3.GenerateFromTable", + "en": "Generate From Table", + "tr": "Tablodan Üret" + }, + { + "resourceName": "Platform", + "key": "ListForms.Wizard.Step3.LookupDataSourceType", + "en": "Lookup Data Source Type", + "tr": "Veri Kaynağı Türü" + }, + { + "resourceName": "Platform", + "key": "ListForms.Wizard.Step3.LookupValueExpression", + "en": "Lookup Value Expression", + "tr": "Değer İfadesi" + }, + { + "resourceName": "Platform", + "key": "ListForms.Wizard.Step3.LookupDisplayExpression", + "en": "Lookup Display Expression", + "tr": "Görüntü İfadesi" + }, + { + "resourceName": "Platform", + "key": "ListForms.Wizard.Step3.LookupLookupQuery", + "en": "Lookup Query", + "tr": "Lookup Sorgusu" + }, + { + "resourceName": "Platform", + "key": "ListForms.Wizard.Step3.LanguageKey", + "en": "Language Key", + "tr": "Dil Anahtarı" + }, { "resourceName": "Platform", "key": "ListForms.Wizard.Step3.TurkishCaption", @@ -16292,6 +16328,12 @@ "en": "English Caption", "tr": "İngilizce Başlık" }, + { + "resourceName": "Platform", + "key": "ListForms.Wizard.Step3.EditorType", + "en": "Editor Type", + "tr": "Editör Türü" + }, { "resourceName": "Platform", "key": "ListForms.Wizard.Step3.EditorOptions", diff --git a/api/src/Sozsoft.Platform.Domain.Shared/WizardConsts.cs b/api/src/Sozsoft.Platform.Domain.Shared/WizardConsts.cs index 0a56cf2..384b78f 100644 --- a/api/src/Sozsoft.Platform.Domain.Shared/WizardConsts.cs +++ b/api/src/Sozsoft.Platform.Domain.Shared/WizardConsts.cs @@ -78,14 +78,14 @@ public static class WizardConsts Margin = 10 }); - public static string DefaultLayoutJson(string DefaultLayout = "grid") => JsonSerializer.Serialize(new + public static string DefaultLayoutJson(string DefaultLayout = "grid", bool Grid = true, bool Pivot = true, bool Chart = true, bool Tree = true, bool Gantt = true, bool Scheduler = true) => JsonSerializer.Serialize(new { - Grid = true, - Pivot = true, - Chart = true, - Tree = true, - Gantt = true, - Scheduler = true, + Grid = Grid, + Pivot = Pivot, + Chart = Chart, + Tree = Tree, + Gantt = Gantt, + Scheduler = Scheduler, DefaultLayout = DefaultLayout, }); @@ -148,11 +148,19 @@ public static class WizardConsts { AllowFiltering = true, }); - public static readonly string DefaultPivotSettingsJson = JsonSerializer.Serialize(new + public static readonly string DefaultPivotSettingsJson = JsonSerializer.Serialize(new { IsPivot = true }); + public static string DefaultLookupJson(UiLookupDataSourceTypeEnum dataSourceType, string displayExpr = "name", string valueExpr = "key", string lookupQuery = "") => JsonSerializer.Serialize(new + { + DataSourceType = dataSourceType, + DisplayExpr = displayExpr, + ValueExpr = valueExpr, + LookupQuery = lookupQuery, + }); + public static string DefaultDeleteCommand(string tableName) { return $"UPDATE \"{tableName}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id"; @@ -178,6 +186,14 @@ public static class WizardConsts }); } + public static string DefaultFieldsJsonOnlyId(DbType dbType = DbType.Guid) + { + return JsonSerializer.Serialize(new[] + { + new { FieldName = "Id", FieldDbType = dbType, Value = "@NEWID", CustomValueType = FieldCustomValueTypeEnum.CustomKey } + }); + } + public static readonly string DefaultPagerOptionJson = JsonSerializer.Serialize(new { Visible = true, diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/Seeds/SqlTables.sql b/api/src/Sozsoft.Platform.EntityFrameworkCore/Seeds/SqlTables.sql index 036f14a..a8b4b91 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/Seeds/SqlTables.sql +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/Seeds/SqlTables.sql @@ -64,7 +64,7 @@ BEGIN [DeletionTime] datetime2 NULL, [DeleterId] uniqueidentifier NULL, [TenantId] uniqueidentifier NULL, - [BranchId] uniqueidentifier NOT NULL, + [BranchId] uniqueidentifier NULL, [Name] nvarchar(64) NOT NULL, [ParentId] uniqueidentifier NULL, CONSTRAINT [PK_Adm_T_Department] PRIMARY KEY CLUSTERED diff --git a/ui/src/proxy/admin/list-form/models.ts b/ui/src/proxy/admin/list-form/models.ts index dd8af41..e2a155f 100644 --- a/ui/src/proxy/admin/list-form/models.ts +++ b/ui/src/proxy/admin/list-form/models.ts @@ -43,6 +43,15 @@ export interface ListFormWizardDto { allowDeleting: boolean confirmDelete: boolean allowDetail: boolean + + defaultLayout: ListViewLayoutType + grid: boolean + pivot: boolean + tree: boolean + chart: boolean + gantt: boolean + scheduler: boolean + languageTextMenuEn: string languageTextMenuTr: string languageTextTitleEn: string diff --git a/ui/src/views/admin/listForm/Wizard.tsx b/ui/src/views/admin/listForm/Wizard.tsx index e404fa8..f2c3563 100644 --- a/ui/src/views/admin/listForm/Wizard.tsx +++ b/ui/src/views/admin/listForm/Wizard.tsx @@ -43,6 +43,13 @@ const initialValues: ListFormWizardDto = { allowDeleting: true, confirmDelete: true, allowDetail: false, + defaultLayout: 'grid', + grid: true, + pivot: true, + tree: true, + chart: true, + gantt: true, + scheduler: true, languageTextMenuEn: '', languageTextMenuTr: '', languageTextTitleEn: '', @@ -148,8 +155,7 @@ const Wizard = () => { 'deleterid', ]) - const isAuditColumn = (columnName: string) => - AUDIT_COLUMNS.has(columnName.toLowerCase()) + const isAuditColumn = (columnName: string) => AUDIT_COLUMNS.has(columnName.toLowerCase()) const loadColumns = async (dsCode: string, schema: string, name: string) => { if (!dsCode || !name) { @@ -268,7 +274,6 @@ const Wizard = () => { .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2') .trim() - const handleWizardNameChange = (name: string) => { const spacedLabel = toSpacedLabel(name) const derived = deriveListFormCode(name) @@ -379,6 +384,11 @@ const Wizard = () => { dbSourceType: col ? sqlDataTypeToDbType(col.dataType) : 12, turkishCaption: item.turkishCaption, englishCaption: item.englishCaption, + captionName: item.captionName, + lookupDataSourceType: item.lookupDataSourceType, + displayExpr: item.displayExpr, + valueExpr: item.valueExpr, + lookupQuery: item.lookupQuery, } }), })), @@ -388,7 +398,9 @@ const Wizard = () => { await getConfig(true) // ✅ sonra navigate - navigate(ROUTES_ENUM.protected.admin.list.replace(':listFormCode', values.listFormCode), { replace: true }) + navigate(ROUTES_ENUM.protected.admin.list.replace(':listFormCode', values.listFormCode), { + replace: true, + }) // ✅ en son kullanıcıya mesaj toast.push( @@ -438,7 +450,10 @@ const Wizard = () => { await getConfig(true) // 🔴 3. Navigate - navigate(ROUTES_ENUM.protected.admin.list.replace(':listFormCode', values.listFormCode), { replace: true }) + navigate( + ROUTES_ENUM.protected.admin.list.replace(':listFormCode', values.listFormCode), + { replace: true }, + ) // 🔴 4. Toast (istersen navigate öncesi de olabilir) toast.push( @@ -518,6 +533,9 @@ const Wizard = () => { selectCommandColumns={selectCommandColumns} groups={editingGroups} onGroupsChange={setEditingGroups} + dbObjects={dbObjects} + isLoadingDbObjects={isLoadingDbObjects} + dsCode={currentDataSource} translate={translate} onBack={() => setCurrentStep(1)} onNext={() => setCurrentStep(3)} diff --git a/ui/src/views/admin/listForm/WizardStep2.tsx b/ui/src/views/admin/listForm/WizardStep2.tsx index 8baafd0..2438051 100644 --- a/ui/src/views/admin/listForm/WizardStep2.tsx +++ b/ui/src/views/admin/listForm/WizardStep2.tsx @@ -3,7 +3,12 @@ import { ListFormWizardDto } from '@/proxy/admin/list-form/models' import { SelectCommandTypeEnum } from '@/proxy/form/models' import type { DatabaseColumnDto, SqlObjectExplorerDto } from '@/proxy/sql-query-manager/models' import { SelectBoxOption } from '@/types/shared' -import { dbSourceTypeOptions, selectCommandTypeOptions, sqlDataTypeToDbType } from './edit/options' +import { + dbSourceTypeOptions, + listFormDefaultLayoutOptions, + selectCommandTypeOptions, + sqlDataTypeToDbType, +} from './edit/options' import { Field, FieldProps, FormikErrors, FormikTouched } from 'formik' import CreatableSelect from 'react-select/creatable' import { FaArrowLeft, FaArrowRight } from 'react-icons/fa' @@ -395,6 +400,121 @@ const WizardStep2 = ({ +
+
+ + + {({ field, form }: FieldProps) => ( + onCaptionNameChange(e.target.value)} + className="w-full text-xs px-1.5 py-1 rounded border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-700 dark:text-gray-200 focus:outline-none focus:border-indigo-400 resize-none font-mono" + /> +
+
+ + {translate('::ListForms.Wizard.Step3.TurkishCaption')} + + onTurkishCaptionChange(e.target.value)} + className="w-full text-xs px-1.5 py-1 rounded border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-700 dark:text-gray-200 focus:outline-none focus:border-indigo-400 resize-none font-mono" + /> +
+
+ + {translate('::ListForms.Wizard.Step3.EnglishCaption')} + + onEnglishCaptionChange(e.target.value)} + className="w-full text-xs px-1.5 py-1 rounded border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-700 dark:text-gray-200 focus:outline-none focus:border-indigo-400 resize-none font-mono" + /> +
+
+ {/* Editor type select */} - - - {/* Turkish Caption */}
- {translate('::ListForms.Wizard.Step3.TurkishCaption')} - onTurkishCaptionChange(e.target.value)} + + {translate('::ListForms.Wizard.Step3.EditorType')} + + +
+ +
+
+ + {translate('::ListForms.Wizard.Step3.LookupDataSourceType')} + + +
+ +
+ + {translate('::ListForms.Wizard.Step3.LookupValueExpression')} + + onValueExprChange(e.target.value)} + className="w-full text-xs px-1.5 py-1 rounded border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-700 dark:text-gray-200 focus:outline-none focus:border-indigo-400 resize-none font-mono" + /> +
+ +
+ + {translate('::ListForms.Wizard.Step3.LookupDisplayExpression')} + + onDisplayExprChange(e.target.value)} + className="w-full text-xs px-1.5 py-1 rounded border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-700 dark:text-gray-200 focus:outline-none focus:border-indigo-400 resize-none font-mono" + /> +
+
+ + {/* LookupQuery */} +
+
+ + {translate('::ListForms.Wizard.Step3.LookupLookupQuery')} + + +
+