Home sayfası için Seeder
This commit is contained in:
parent
5806ff5f9f
commit
57dbb0d308
5 changed files with 432 additions and 235 deletions
|
|
@ -195,20 +195,13 @@ public class PublicAppService : PlatformAppService
|
|||
|
||||
public async Task<HomeDto> GetHomeAsync()
|
||||
{
|
||||
var entity = await _homeRepository.FirstOrDefaultAsync();
|
||||
if (entity == null)
|
||||
{
|
||||
entity = await _homeRepository.InsertAsync(CreateDefaultHomeEntity(), autoSave: true);
|
||||
}
|
||||
|
||||
var entity = await _homeRepository.FirstOrDefaultAsync() ?? throw new EntityNotFoundException(typeof(Home));
|
||||
return ObjectMapper.Map<Home, HomeDto>(entity);
|
||||
}
|
||||
|
||||
public async Task SaveHomePageAsync(SaveHomePageInput input)
|
||||
{
|
||||
var entity = await _homeRepository.FirstOrDefaultAsync();
|
||||
var isNewEntity = entity == null;
|
||||
entity ??= CreateDefaultHomeEntity();
|
||||
var entity = await _homeRepository.FirstOrDefaultAsync() ?? throw new EntityNotFoundException(typeof(Home));
|
||||
|
||||
entity.HeroBackgroundImageKey = input.HeroBackgroundImageKey;
|
||||
entity.HeroPrimaryCtaKey = input.HeroPrimaryCtaKey;
|
||||
|
|
@ -252,14 +245,7 @@ public class PublicAppService : PlatformAppService
|
|||
StyleClass = solution.StyleClass,
|
||||
}).ToList());
|
||||
|
||||
if (isNewEntity)
|
||||
{
|
||||
await _homeRepository.InsertAsync(entity, autoSave: false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _homeRepository.UpdateAsync(entity, autoSave: false);
|
||||
}
|
||||
await _homeRepository.UpdateAsync(entity, autoSave: false);
|
||||
|
||||
await UpsertLanguageTextAsync(input.CultureName, input.HeroBackgroundImageKey, input.HeroBackgroundImageValue);
|
||||
await UpsertLanguageTextAsync(input.CultureName, input.HeroPrimaryCtaKey, input.HeroPrimaryCtaValue);
|
||||
|
|
@ -608,83 +594,6 @@ public class PublicAppService : PlatformAppService
|
|||
await _languageTextAppService.ClearRedisCacheAsync();
|
||||
}
|
||||
|
||||
private static Home CreateDefaultHomeEntity()
|
||||
{
|
||||
var slides = new List<HomeSlideDto>
|
||||
{
|
||||
new()
|
||||
{
|
||||
TitleKey = "Public.hero.slide1.title",
|
||||
SubtitleKey = "Public.hero.slide1.subtitle",
|
||||
Services = new List<HomeSlideServiceDto>
|
||||
{
|
||||
new() { Icon = "FaCalendarAlt", TitleKey = "Public.hero.slide1.service1.title", DescriptionKey = "Public.hero.slide1.service1.desc" },
|
||||
new() { Icon = "FaUsers", TitleKey = "Public.hero.slide1.service2.title", DescriptionKey = "Public.hero.slide1.service2.desc" },
|
||||
new() { Icon = "FaShieldAlt", TitleKey = "Public.hero.slide1.service3.title", DescriptionKey = "Public.hero.slide1.service3.desc" },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
TitleKey = "Public.hero.slide2.title",
|
||||
SubtitleKey = "Public.hero.slide2.subtitle",
|
||||
Services = new List<HomeSlideServiceDto>
|
||||
{
|
||||
new() { Icon = "FaChartBar", TitleKey = "Public.hero.slide2.service1.title", DescriptionKey = "Public.hero.slide2.service1.desc" },
|
||||
new() { Icon = "FaCreditCard", TitleKey = "Public.hero.slide2.service2.title", DescriptionKey = "Public.hero.slide2.service2.desc" },
|
||||
new() { Icon = "FaDatabase", TitleKey = "Public.hero.slide2.service3.title", DescriptionKey = "Public.hero.slide2.service3.desc" },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
TitleKey = "Public.hero.slide3.title",
|
||||
SubtitleKey = "Public.hero.slide3.subtitle",
|
||||
Services = new List<HomeSlideServiceDto>
|
||||
{
|
||||
new() { Icon = "FaDesktop", TitleKey = "Public.hero.slide3.service1.title", DescriptionKey = "Public.hero.slide3.service1.desc" },
|
||||
new() { Icon = "FaServer", TitleKey = "Public.hero.slide3.service2.title", DescriptionKey = "Public.hero.slide3.service2.desc" },
|
||||
new() { Icon = "FaMobileAlt", TitleKey = "Public.hero.slide3.service3.title", DescriptionKey = "Public.hero.slide3.service3.desc" },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
var features = new List<HomeFeatureDto>
|
||||
{
|
||||
new() { Icon = "FaUsers", TitleKey = "Public.features.reliable", DescriptionKey = "Public.features.reliable.desc" },
|
||||
new() { Icon = "FaCalendarAlt", TitleKey = "App.Videoroom.Planning", DescriptionKey = "Public.features.rapid.desc" },
|
||||
new() { Icon = "FaBookOpen", TitleKey = "Public.features.expert", DescriptionKey = "Public.features.expert.desc" },
|
||||
new() { Icon = "FaCreditCard", TitleKey = "Public.features.muhasebe", DescriptionKey = "Public.features.muhasebe.desc" },
|
||||
new() { Icon = "FaRegComment", TitleKey = "Public.features.iletisim", DescriptionKey = "Public.features.iletisim.desc" },
|
||||
new() { Icon = "FaPhone", TitleKey = "Public.features.mobil", DescriptionKey = "Public.features.mobil.desc" },
|
||||
new() { Icon = "FaChartBar", TitleKey = "Public.features.scalable", DescriptionKey = "Public.features.scalable.desc" },
|
||||
new() { Icon = "FaShieldAlt", TitleKey = "Public.features.guvenlik", DescriptionKey = "Public.features.guvenlik.desc" },
|
||||
};
|
||||
|
||||
var solutions = new List<HomeSolutionDto>
|
||||
{
|
||||
new() { Icon = "FaDesktop", ColorClass = "bg-blue-600", TitleKey = "Public.services.web.title", DescriptionKey = "Public.solutions.web.desc" },
|
||||
new() { Icon = "FaMobileAlt", ColorClass = "bg-purple-600", TitleKey = "Public.services.mobile.title", DescriptionKey = "Public.solutions.mobile.desc" },
|
||||
new() { Icon = "FaServer", ColorClass = "bg-green-600", TitleKey = "Public.solutions.custom.title", DescriptionKey = "Public.solutions.custom.desc" },
|
||||
new() { Icon = "FaDatabase", ColorClass = "bg-red-600", TitleKey = "Public.solutions.database.title", DescriptionKey = "Public.solutions.database.desc" },
|
||||
};
|
||||
|
||||
return new Home
|
||||
{
|
||||
HeroBackgroundImageKey = "Public.home.hero.backgroundImage",
|
||||
HeroPrimaryCtaKey = "Public.hero.cta.consultation",
|
||||
HeroSecondaryCtaKey = "Public.hero.cta.discover",
|
||||
FeaturesTitleKey = "Public.features.title",
|
||||
FeaturesSubtitleKey = "Public.features.subtitle",
|
||||
SolutionsTitleKey = "Public.solutions.title",
|
||||
SolutionsSubtitleKey = "Public.solutions.subtitle",
|
||||
CtaTitleKey = "Public.common.getStarted",
|
||||
CtaSubtitleKey = "Public.common.contact",
|
||||
CtaButtonLabelKey = "Public.common.learnMore",
|
||||
SlidesJson = JsonSerializer.Serialize(slides),
|
||||
FeaturesJson = JsonSerializer.Serialize(features),
|
||||
SolutionsJson = JsonSerializer.Serialize(solutions),
|
||||
};
|
||||
}
|
||||
|
||||
private async Task UpsertLanguageTextAsync(string cultureName, string key, string value)
|
||||
{
|
||||
if (key.IsNullOrWhiteSpace())
|
||||
|
|
|
|||
|
|
@ -429,6 +429,153 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"Homes": [
|
||||
{
|
||||
"heroBackgroundImageKey": "Public.home.hero.backgroundImage",
|
||||
"heroPrimaryCtaKey": "Public.hero.cta.consultation",
|
||||
"heroSecondaryCtaKey": "Public.hero.cta.discover",
|
||||
"featuresTitleKey": "Public.features.title",
|
||||
"featuresSubtitleKey": "Public.features.subtitle",
|
||||
"solutionsTitleKey": "Public.solutions.title",
|
||||
"solutionsSubtitleKey": "Public.solutions.subtitle",
|
||||
"ctaTitleKey": "Public.common.getStarted",
|
||||
"ctaSubtitleKey": "Public.common.contact",
|
||||
"ctaButtonLabelKey": "Public.common.learnMore",
|
||||
"slides": [
|
||||
{
|
||||
"titleKey": "Public.hero.slide1.title",
|
||||
"subtitleKey": "Public.hero.slide1.subtitle",
|
||||
"services": [
|
||||
{
|
||||
"icon": "FaCalendarAlt",
|
||||
"titleKey": "Public.hero.slide1.service1.title",
|
||||
"descriptionKey": "Public.hero.slide1.service1.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaUsers",
|
||||
"titleKey": "Public.hero.slide1.service2.title",
|
||||
"descriptionKey": "Public.hero.slide1.service2.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaShieldAlt",
|
||||
"titleKey": "Public.hero.slide1.service3.title",
|
||||
"descriptionKey": "Public.hero.slide1.service3.desc"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"titleKey": "Public.hero.slide2.title",
|
||||
"subtitleKey": "Public.hero.slide2.subtitle",
|
||||
"services": [
|
||||
{
|
||||
"icon": "FaChartBar",
|
||||
"titleKey": "Public.hero.slide2.service1.title",
|
||||
"descriptionKey": "Public.hero.slide2.service1.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaCreditCard",
|
||||
"titleKey": "Public.hero.slide2.service2.title",
|
||||
"descriptionKey": "Public.hero.slide2.service2.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaDatabase",
|
||||
"titleKey": "Public.hero.slide2.service3.title",
|
||||
"descriptionKey": "Public.hero.slide2.service3.desc"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"titleKey": "Public.hero.slide3.title",
|
||||
"subtitleKey": "Public.hero.slide3.subtitle",
|
||||
"services": [
|
||||
{
|
||||
"icon": "FaDesktop",
|
||||
"titleKey": "Public.hero.slide3.service1.title",
|
||||
"descriptionKey": "Public.hero.slide3.service1.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaServer",
|
||||
"titleKey": "Public.hero.slide3.service2.title",
|
||||
"descriptionKey": "Public.hero.slide3.service2.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaMobileAlt",
|
||||
"titleKey": "Public.hero.slide3.service3.title",
|
||||
"descriptionKey": "Public.hero.slide3.service3.desc"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"icon": "FaUsers",
|
||||
"titleKey": "Public.features.reliable",
|
||||
"descriptionKey": "Public.features.reliable.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaCalendarAlt",
|
||||
"titleKey": "App.Videoroom.Planning",
|
||||
"descriptionKey": "Public.features.rapid.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaBookOpen",
|
||||
"titleKey": "Public.features.expert",
|
||||
"descriptionKey": "Public.features.expert.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaCreditCard",
|
||||
"titleKey": "Public.features.muhasebe",
|
||||
"descriptionKey": "Public.features.muhasebe.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaRegComment",
|
||||
"titleKey": "Public.features.iletisim",
|
||||
"descriptionKey": "Public.features.iletisim.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaPhone",
|
||||
"titleKey": "Public.features.mobil",
|
||||
"descriptionKey": "Public.features.mobil.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaChartBar",
|
||||
"titleKey": "Public.features.scalable",
|
||||
"descriptionKey": "Public.features.scalable.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaShieldAlt",
|
||||
"titleKey": "Public.features.guvenlik",
|
||||
"descriptionKey": "Public.features.guvenlik.desc"
|
||||
}
|
||||
],
|
||||
"solutions": [
|
||||
{
|
||||
"icon": "FaDesktop",
|
||||
"colorClass": "bg-blue-600",
|
||||
"titleKey": "Public.services.web.title",
|
||||
"descriptionKey": "Public.solutions.web.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaMobileAlt",
|
||||
"colorClass": "bg-purple-600",
|
||||
"titleKey": "Public.services.mobile.title",
|
||||
"descriptionKey": "Public.solutions.mobile.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaServer",
|
||||
"colorClass": "bg-green-600",
|
||||
"titleKey": "Public.solutions.custom.title",
|
||||
"descriptionKey": "Public.solutions.custom.desc"
|
||||
},
|
||||
{
|
||||
"icon": "FaDatabase",
|
||||
"colorClass": "bg-red-600",
|
||||
"titleKey": "Public.solutions.database.title",
|
||||
"descriptionKey": "Public.solutions.database.desc"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Services": [
|
||||
{
|
||||
"icon": "FaCode",
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ public class TenantSeederDto
|
|||
public List<JobPositionSeedDto> JobPositions { get; set; }
|
||||
|
||||
//Public
|
||||
public List<HomeSeedDto> Homes { get; set; }
|
||||
public List<AboutSeedDto> Abouts { get; set; }
|
||||
public List<ServiceSeedDto> Services { get; set; }
|
||||
public List<PaymentMethodSeedDto> PaymentMethods { get; set; }
|
||||
|
|
@ -392,6 +393,56 @@ public class AboutSeedDto
|
|||
public List<SectionDto> Sections { get; set; }
|
||||
}
|
||||
|
||||
public class HomeSeedDto
|
||||
{
|
||||
public string HeroBackgroundImageKey { get; set; }
|
||||
public string HeroPrimaryCtaKey { get; set; }
|
||||
public string HeroSecondaryCtaKey { get; set; }
|
||||
public string FeaturesTitleKey { get; set; }
|
||||
public string FeaturesSubtitleKey { get; set; }
|
||||
public string SolutionsTitleKey { get; set; }
|
||||
public string SolutionsSubtitleKey { get; set; }
|
||||
public string CtaTitleKey { get; set; }
|
||||
public string CtaSubtitleKey { get; set; }
|
||||
public string CtaButtonLabelKey { get; set; }
|
||||
public List<HomeSlideSeedDto> Slides { get; set; }
|
||||
public List<HomeFeatureSeedDto> Features { get; set; }
|
||||
public List<HomeSolutionSeedDto> Solutions { get; set; }
|
||||
}
|
||||
|
||||
public class HomeSlideSeedDto
|
||||
{
|
||||
public string TitleKey { get; set; }
|
||||
public string SubtitleKey { get; set; }
|
||||
public string StyleClass { get; set; }
|
||||
public List<HomeSlideServiceSeedDto> Services { get; set; }
|
||||
}
|
||||
|
||||
public class HomeSlideServiceSeedDto
|
||||
{
|
||||
public string Icon { get; set; }
|
||||
public string TitleKey { get; set; }
|
||||
public string DescriptionKey { get; set; }
|
||||
public string StyleClass { get; set; }
|
||||
}
|
||||
|
||||
public class HomeFeatureSeedDto
|
||||
{
|
||||
public string Icon { get; set; }
|
||||
public string TitleKey { get; set; }
|
||||
public string DescriptionKey { get; set; }
|
||||
public string StyleClass { get; set; }
|
||||
}
|
||||
|
||||
public class HomeSolutionSeedDto
|
||||
{
|
||||
public string Icon { get; set; }
|
||||
public string ColorClass { get; set; }
|
||||
public string TitleKey { get; set; }
|
||||
public string DescriptionKey { get; set; }
|
||||
public string StyleClass { get; set; }
|
||||
}
|
||||
|
||||
public class WorkHourSeedDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
|
@ -440,6 +491,7 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
|||
private readonly IRepository<CustomComponent, Guid> _customComponentRepository;
|
||||
private readonly IRepository<ReportCategory, Guid> _reportCategoriesRepository;
|
||||
private readonly IRepository<ReportTemplate, Guid> _reportTemplatesRepository;
|
||||
private readonly IRepository<Home, Guid> _homeRepository;
|
||||
private readonly IRepository<About, Guid> _aboutRepository;
|
||||
private readonly IRepository<PaymentMethod, Guid> _paymentMethodRepository;
|
||||
private readonly IRepository<InstallmentOption, Guid> _installmentOptionRepository;
|
||||
|
|
@ -495,6 +547,7 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
|||
IRepository<CustomComponent, Guid> customComponentRepository,
|
||||
IRepository<ReportCategory, Guid> reportCategoriesRepository,
|
||||
IRepository<ReportTemplate, Guid> reportTemplatesRepository,
|
||||
IRepository<Home, Guid> homeRepository,
|
||||
IRepository<About, Guid> aboutRepository,
|
||||
IRepository<Service, Guid> servicesRepository,
|
||||
IRepository<Product, Guid> productRepository,
|
||||
|
|
@ -548,6 +601,7 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
|||
_customComponentRepository = customComponentRepository;
|
||||
_reportCategoriesRepository = reportCategoriesRepository;
|
||||
_reportTemplatesRepository = reportTemplatesRepository;
|
||||
_homeRepository = homeRepository;
|
||||
_servicesRepository = servicesRepository;
|
||||
_aboutRepository = aboutRepository;
|
||||
_contactRepository = contactRepository;
|
||||
|
|
@ -848,6 +902,30 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.Homes)
|
||||
{
|
||||
var exists = await _homeRepository.FirstOrDefaultAsync();
|
||||
if (exists == null)
|
||||
{
|
||||
await _homeRepository.InsertAsync(new Home
|
||||
{
|
||||
HeroBackgroundImageKey = item.HeroBackgroundImageKey,
|
||||
HeroPrimaryCtaKey = item.HeroPrimaryCtaKey,
|
||||
HeroSecondaryCtaKey = item.HeroSecondaryCtaKey,
|
||||
FeaturesTitleKey = item.FeaturesTitleKey,
|
||||
FeaturesSubtitleKey = item.FeaturesSubtitleKey,
|
||||
SolutionsTitleKey = item.SolutionsTitleKey,
|
||||
SolutionsSubtitleKey = item.SolutionsSubtitleKey,
|
||||
CtaTitleKey = item.CtaTitleKey,
|
||||
CtaSubtitleKey = item.CtaSubtitleKey,
|
||||
CtaButtonLabelKey = item.CtaButtonLabelKey,
|
||||
SlidesJson = JsonSerializer.Serialize(item.Slides),
|
||||
FeaturesJson = JsonSerializer.Serialize(item.Features),
|
||||
SolutionsJson = JsonSerializer.Serialize(item.Solutions)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.Contacts)
|
||||
{
|
||||
var exists = await _contactRepository.FirstOrDefaultAsync();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,28 @@
|
|||
{
|
||||
"commit": "0b5eb3d",
|
||||
"commit": "0d4703c",
|
||||
"releases": [
|
||||
{
|
||||
"version": "1.1.03",
|
||||
"buildDate": "2026-05-30",
|
||||
"commit": "96f7091d46c248ba3c42849fe5d870db0ab96982",
|
||||
"changeLog": [
|
||||
"- User Detail komponentinin içerisinde Avatar ekleme",
|
||||
"- EditForm un içerisinde EditorOptions dinamik oluşturulması",
|
||||
"- Editform un içerisinde EditorScript dinamik oluşturulması"
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.1.02",
|
||||
"buildDate": "2026-05-27",
|
||||
"commit": "84b9f6510787bd82f3797728fd675f755b4caa2d",
|
||||
"changeLog": [
|
||||
"- .NET 10 yükseltildi.",
|
||||
"- Abp Framework 10 yükseltildi.",
|
||||
"- Sql Query Manager problemleri giderildi.",
|
||||
"- AuditLog problemleri giderildi.",
|
||||
"- Tenan yapısını uygunluğu için düzenlemeler yapıldı."
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.1.01",
|
||||
"buildDate": "2026-05-24",
|
||||
|
|
|
|||
|
|
@ -52,6 +52,12 @@ type EditorScriptBuilderDialogProps = {
|
|||
const baseInputClass =
|
||||
'w-full h-9 px-2 rounded border border-gray-200 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-700 dark:text-gray-100 focus:outline-none focus:border-indigo-400'
|
||||
|
||||
const fieldLabelClass =
|
||||
'flex flex-col gap-1 text-xs font-medium text-gray-500 dark:text-gray-400'
|
||||
|
||||
const actionIconCellClass =
|
||||
'col-span-12 flex h-9 items-center justify-end md:col-span-1 md:justify-center'
|
||||
|
||||
const makeId = () => `${Date.now()}_${Math.random().toString(36).slice(2)}`
|
||||
|
||||
const createConditionalAction = (): ConditionalAction => ({
|
||||
|
|
@ -612,7 +618,7 @@ function EditorScriptBuilderDialog({
|
|||
value: string,
|
||||
onChange: (value: string) => void,
|
||||
) => (
|
||||
<label className="flex flex-col gap-1 text-xs font-medium text-gray-500 dark:text-gray-400">
|
||||
<label className={fieldLabelClass}>
|
||||
{label}
|
||||
{renderFieldSelect(value, onChange)}
|
||||
</label>
|
||||
|
|
@ -721,8 +727,8 @@ function EditorScriptBuilderDialog({
|
|||
<div className="mb-3 rounded bg-gray-50 px-2 py-1.5 text-xs text-gray-600 dark:bg-gray-900 dark:text-gray-300">
|
||||
{describeCopyMapping(mapping)}
|
||||
</div>
|
||||
<div className="grid grid-cols-12 gap-2">
|
||||
<label className="col-span-12 flex flex-col gap-1 text-xs font-medium text-gray-500 dark:text-gray-400 md:col-span-5">
|
||||
<div className="grid grid-cols-12 items-end gap-2">
|
||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-5`}>
|
||||
Seçili kayıttaki kolon/path
|
||||
<input
|
||||
className={baseInputClass}
|
||||
|
|
@ -752,17 +758,20 @@ function EditorScriptBuilderDialog({
|
|||
),
|
||||
)}
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
shape="circle"
|
||||
variant="plain"
|
||||
icon={<FaTrash />}
|
||||
onClick={() =>
|
||||
setCopyMappings((current) =>
|
||||
current.filter((item) => item.id !== mapping.id),
|
||||
)
|
||||
}
|
||||
/>
|
||||
<div className={`${actionIconCellClass} md:col-span-2`}>
|
||||
<Button
|
||||
type="button"
|
||||
shape="circle"
|
||||
variant="plain"
|
||||
icon={<FaTrash />}
|
||||
title="Bu kopyalama satırını sil"
|
||||
onClick={() =>
|
||||
setCopyMappings((current) =>
|
||||
current.filter((item) => item.id !== mapping.id),
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
|
@ -774,7 +783,7 @@ function EditorScriptBuilderDialog({
|
|||
<div>
|
||||
<div
|
||||
className="text-sm font-semibold"
|
||||
title="Önce koşulu kur: hangi field, hangi operatör, hangi değer. Sonra aksiyonu seç: field yaz, API çağırıp cevabı field'a yaz, URL aç, alert/confirm göster veya formül hesapla. Örnek: Değer IPTAL ise SatisOlmamaSebebiID visible true yap. Değer 1 ise /api/x/{value} çağır, gelen data.name bilgisini DisplayName alanına yaz."
|
||||
title="Önce koşulu kur: hangi field, hangi operatör, hangi değer. Sonra aksiyonu seç: field yaz, API çağırıp cevabı field'a yaz, URL aç, alert/confirm göster veya formül hesapla. Örnek: Değer Aktif ise SatisOlmamaSebebiID visible true yap. Değer 1 ise /api/x/{value} çağır, gelen data.name bilgisini DisplayName alanına yaz."
|
||||
>
|
||||
2. Koşullu Aksiyon Builder
|
||||
</div>
|
||||
|
|
@ -783,7 +792,7 @@ function EditorScriptBuilderDialog({
|
|||
type="button"
|
||||
size="sm"
|
||||
icon={<FaPlus />}
|
||||
title="Koşul + aksiyon kuralı ekler. Örnek: değer IPTAL ise alanı pasif yap, API çağır, URL aç."
|
||||
title="Koşul + aksiyon kuralı ekler. Örnek: değer Aktif ise alanı pasif yap, API çağır, URL aç."
|
||||
onClick={() =>
|
||||
setConditionalActions((current) => [...current, createConditionalAction()])
|
||||
}
|
||||
|
|
@ -800,32 +809,35 @@ function EditorScriptBuilderDialog({
|
|||
<div className="rounded bg-gray-50 px-2 py-1.5 text-xs text-gray-600 dark:bg-gray-900 dark:text-gray-300">
|
||||
{describeConditionalAction(action)}
|
||||
</div>
|
||||
<div className="grid grid-cols-12 gap-2">
|
||||
<div className="col-span-12 md:col-span-3">
|
||||
<div className="grid grid-cols-12 items-end gap-2">
|
||||
<div className="col-span-12 md:col-span-4">
|
||||
{renderLabeledFieldSelect('Eğer: kaynak field', action.source, (value) =>
|
||||
updateConditionalAction(action.id, { source: value }),
|
||||
)}
|
||||
</div>
|
||||
<select
|
||||
className={`${baseInputClass} col-span-12 self-end md:col-span-3`}
|
||||
value={action.operator}
|
||||
title="Koşul operatörü. Her zaman seçersen kaynak field ve karşılaştırma değeri gerekmez."
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, {
|
||||
operator: event.target.value as ConditionalAction['operator'],
|
||||
})
|
||||
}
|
||||
>
|
||||
<option value="always">always</option>
|
||||
<option value="empty">empty</option>
|
||||
<option value="notEmpty">notEmpty</option>
|
||||
<option value="equals">equals</option>
|
||||
<option value="notEquals">notEquals</option>
|
||||
<option value="contains">contains</option>
|
||||
<option value="greaterThan">greaterThan</option>
|
||||
<option value="lessThan">lessThan</option>
|
||||
</select>
|
||||
<label className="col-span-12 flex flex-col gap-1 text-xs font-medium text-gray-500 dark:text-gray-400 md:col-span-3">
|
||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-3`}>
|
||||
Operatör
|
||||
<select
|
||||
className={baseInputClass}
|
||||
value={action.operator}
|
||||
title="Koşul operatörü. Her zaman seçersen kaynak field ve karşılaştırma değeri gerekmez."
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, {
|
||||
operator: event.target.value as ConditionalAction['operator'],
|
||||
})
|
||||
}
|
||||
>
|
||||
<option value="always">always</option>
|
||||
<option value="empty">empty</option>
|
||||
<option value="notEmpty">notEmpty</option>
|
||||
<option value="equals">equals</option>
|
||||
<option value="notEquals">notEquals</option>
|
||||
<option value="contains">contains</option>
|
||||
<option value="greaterThan">greaterThan</option>
|
||||
<option value="lessThan">lessThan</option>
|
||||
</select>
|
||||
</label>
|
||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-4`}>
|
||||
Koşul değeri
|
||||
<input
|
||||
className={baseInputClass}
|
||||
|
|
@ -838,25 +850,28 @@ function EditorScriptBuilderDialog({
|
|||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, { value: event.target.value })
|
||||
}
|
||||
placeholder="Örn: IPTAL, 1000"
|
||||
title="Koşulda kullanılacak sabit değer. Örnek: IPTAL, 0, True"
|
||||
placeholder="Örn: Aktif, 1000"
|
||||
title="Koşulda kullanılacak sabit değer. Örnek: Aktif, 0, True"
|
||||
/>
|
||||
</label>
|
||||
<Button
|
||||
type="button"
|
||||
shape="circle"
|
||||
variant="plain"
|
||||
icon={<FaTrash />}
|
||||
onClick={() =>
|
||||
setConditionalActions((current) =>
|
||||
current.filter((item) => item.id !== action.id),
|
||||
)
|
||||
}
|
||||
/>
|
||||
<div className={actionIconCellClass}>
|
||||
<Button
|
||||
type="button"
|
||||
shape="circle"
|
||||
variant="plain"
|
||||
icon={<FaTrash />}
|
||||
title="Bu koşullu aksiyonu sil"
|
||||
onClick={() =>
|
||||
setConditionalActions((current) =>
|
||||
current.filter((item) => item.id !== action.id),
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-12 gap-2">
|
||||
<label className="col-span-12 flex flex-col gap-1 text-xs font-medium text-gray-500 dark:text-gray-400 md:col-span-4">
|
||||
<div className="grid grid-cols-12 items-end gap-2">
|
||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-4`}>
|
||||
O zaman: aksiyon
|
||||
<select
|
||||
className={baseInputClass}
|
||||
|
|
@ -890,104 +905,130 @@ function EditorScriptBuilderDialog({
|
|||
)}
|
||||
|
||||
{action.actionType === 'setField' && (
|
||||
<input
|
||||
className={`${baseInputClass} col-span-4`}
|
||||
value={action.textValue}
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, { textValue: event.target.value })
|
||||
}
|
||||
placeholder="text, {Field} or {selected.Name}"
|
||||
title="Sabit metin veya token yaz. Örnek: {Name}, {value}, {selected.DisplayName}"
|
||||
/>
|
||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-4`}>
|
||||
Değer
|
||||
<input
|
||||
className={baseInputClass}
|
||||
value={action.textValue}
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, { textValue: event.target.value })
|
||||
}
|
||||
placeholder="text, {Field} or {selected.Name}"
|
||||
title="Sabit metin veya token yaz. Örnek: {Name}, {value}, {selected.DisplayName}"
|
||||
/>
|
||||
</label>
|
||||
)}
|
||||
|
||||
{action.actionType === 'apiToField' && (
|
||||
<>
|
||||
<select
|
||||
className={`${baseInputClass} col-span-2`}
|
||||
value={action.apiMethod}
|
||||
title="API çağrısı GET veya POST olabilir. POST formData'yı body olarak gönderir."
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, {
|
||||
apiMethod: event.target.value as ConditionalAction['apiMethod'],
|
||||
})
|
||||
}
|
||||
>
|
||||
<option value="GET">GET</option>
|
||||
<option value="POST">POST</option>
|
||||
</select>
|
||||
<input
|
||||
className={`${baseInputClass} col-span-3`}
|
||||
value={action.apiUrl}
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, { apiUrl: event.target.value })
|
||||
}
|
||||
placeholder="/api/path/{Id}"
|
||||
title="Token kullanabilirsin: /api/orders/{OrderId}, /api/x/{selected.Id}, /api/y/{value}"
|
||||
/>
|
||||
<input
|
||||
className={`${baseInputClass} col-span-3`}
|
||||
value={action.responsePath}
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, {
|
||||
responsePath: event.target.value,
|
||||
})
|
||||
}
|
||||
placeholder="data.value"
|
||||
title="API JSON cevabından okunacak path. Boş bırakırsan tüm JSON hedef field'a yazılır."
|
||||
/>
|
||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-2`}>
|
||||
Method
|
||||
<select
|
||||
className={baseInputClass}
|
||||
value={action.apiMethod}
|
||||
title="API çağrısı GET veya POST olabilir. POST formData'yı body olarak gönderir."
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, {
|
||||
apiMethod: event.target.value as ConditionalAction['apiMethod'],
|
||||
})
|
||||
}
|
||||
>
|
||||
<option value="GET">GET</option>
|
||||
<option value="POST">POST</option>
|
||||
</select>
|
||||
</label>
|
||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-3`}>
|
||||
API URL
|
||||
<input
|
||||
className={baseInputClass}
|
||||
value={action.apiUrl}
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, { apiUrl: event.target.value })
|
||||
}
|
||||
placeholder="/api/path/{Id}"
|
||||
title="Token kullanabilirsin: /api/orders/{OrderId}, /api/x/{selected.Id}, /api/y/{value}"
|
||||
/>
|
||||
</label>
|
||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-3`}>
|
||||
Response path
|
||||
<input
|
||||
className={baseInputClass}
|
||||
value={action.responsePath}
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, {
|
||||
responsePath: event.target.value,
|
||||
})
|
||||
}
|
||||
placeholder="data.value"
|
||||
title="API JSON cevabından okunacak path. Boş bırakırsan tüm JSON hedef field'a yazılır."
|
||||
/>
|
||||
</label>
|
||||
</>
|
||||
)}
|
||||
|
||||
{action.actionType === 'openUrl' && (
|
||||
<>
|
||||
<input
|
||||
className={`${baseInputClass} col-span-6`}
|
||||
value={action.textValue}
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, { textValue: event.target.value })
|
||||
}
|
||||
placeholder="/report?id={Id}&type={selected.Type}"
|
||||
title="Açılacak URL. Token destekler: {Id}, {value}, {selected.Type}"
|
||||
/>
|
||||
<select
|
||||
className={`${baseInputClass} col-span-2`}
|
||||
value={action.urlTarget}
|
||||
title="URL yeni sekmede mi mevcut sekmede mi açılsın?"
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, {
|
||||
urlTarget: event.target.value as ConditionalAction['urlTarget'],
|
||||
})
|
||||
}
|
||||
>
|
||||
<option value="_blank">_blank</option>
|
||||
<option value="_self">_self</option>
|
||||
</select>
|
||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-6`}>
|
||||
URL
|
||||
<input
|
||||
className={baseInputClass}
|
||||
value={action.textValue}
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, {
|
||||
textValue: event.target.value,
|
||||
})
|
||||
}
|
||||
placeholder="/report?id={Id}&type={selected.Type}"
|
||||
title="Açılacak URL. Token destekler: {Id}, {value}, {selected.Type}"
|
||||
/>
|
||||
</label>
|
||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-2`}>
|
||||
Hedef
|
||||
<select
|
||||
className={baseInputClass}
|
||||
value={action.urlTarget}
|
||||
title="URL yeni sekmede mi mevcut sekmede mi açılsın?"
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, {
|
||||
urlTarget: event.target.value as ConditionalAction['urlTarget'],
|
||||
})
|
||||
}
|
||||
>
|
||||
<option value="_blank">_blank</option>
|
||||
<option value="_self">_self</option>
|
||||
</select>
|
||||
</label>
|
||||
</>
|
||||
)}
|
||||
|
||||
{(action.actionType === 'alert' || action.actionType === 'confirm') && (
|
||||
<input
|
||||
className={`${baseInputClass} col-span-8`}
|
||||
value={action.message}
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, { message: event.target.value })
|
||||
}
|
||||
placeholder="{Field} tokenları ile mesaj"
|
||||
title="Alert/confirm mesajı. Token destekler: {Name}, {value}, {selected.Name}"
|
||||
/>
|
||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-8`}>
|
||||
Mesaj
|
||||
<input
|
||||
className={baseInputClass}
|
||||
value={action.message}
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, { message: event.target.value })
|
||||
}
|
||||
placeholder="{Field} tokenları ile mesaj"
|
||||
title="Alert/confirm mesajı. Token destekler: {Name}, {value}, {selected.Name}"
|
||||
/>
|
||||
</label>
|
||||
)}
|
||||
|
||||
{action.actionType === 'calculate' && (
|
||||
<input
|
||||
className={`${baseInputClass} col-span-4`}
|
||||
value={action.formula}
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, { formula: event.target.value })
|
||||
}
|
||||
placeholder="Number(data.Quantity || 0) * Number(data.UnitPrice || 0)"
|
||||
title="JavaScript expression yaz. data=formData, selected=selectedItem, value=e.value olarak kullanılır."
|
||||
/>
|
||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-4`}>
|
||||
Formül
|
||||
<input
|
||||
className={baseInputClass}
|
||||
value={action.formula}
|
||||
onChange={(event) =>
|
||||
updateConditionalAction(action.id, { formula: event.target.value })
|
||||
}
|
||||
placeholder="Number(data.Quantity || 0) * Number(data.UnitPrice || 0)"
|
||||
title="JavaScript expression yaz. data=formData, selected=selectedItem, value=e.value olarak kullanılır."
|
||||
/>
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1020,7 +1061,7 @@ function EditorScriptBuilderDialog({
|
|||
className="mb-3 text-sm font-semibold"
|
||||
title="Quantity ve UnitPrice ile TotalAmount hesaplar. Seçili kayıttan hesapla lookup kaydından değerleri alır; satır toplamını yenile mevcut form değerlerinden hesaplar."
|
||||
>
|
||||
5. Tutar Hesaplamaları
|
||||
4. Tutar Hesaplamaları
|
||||
</div>
|
||||
<div className="grid grid-cols-1 gap-2 mb-3 md:grid-cols-2">
|
||||
<label className="flex items-start gap-2 text-sm">
|
||||
|
|
@ -1059,7 +1100,7 @@ function EditorScriptBuilderDialog({
|
|||
className="mb-3 text-sm font-semibold"
|
||||
title="Tek satırlık global servis çağrıları için kullan. Daha detaylı kodu sağdaki TypeScript script editor alanında düzenleyebilirsin."
|
||||
>
|
||||
6. Servis Çağrısı
|
||||
5. Servis Çağrısı
|
||||
</div>
|
||||
<input
|
||||
className={baseInputClass}
|
||||
|
|
@ -1084,7 +1125,7 @@ function EditorScriptBuilderDialog({
|
|||
TypeScript
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-1 min-h-[430px] overflow-hidden rounded border border-gray-200 dark:border-gray-700">
|
||||
<div className="flex-1 min-h-[350px] overflow-hidden rounded border border-gray-200 dark:border-gray-700">
|
||||
<Editor
|
||||
height="100%"
|
||||
language="typescript"
|
||||
|
|
|
|||
Loading…
Reference in a new issue