Widget Dialog
This commit is contained in:
parent
cafd4d9184
commit
e4ea0171fa
2 changed files with 209 additions and 64 deletions
|
|
@ -821,6 +821,54 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
|
||||||
}),
|
}),
|
||||||
FormFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] {
|
FormFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] {
|
||||||
new FieldsDefaultValue() { FieldName = "IsActive", FieldDbType = DbType.Boolean, Value = "true", CustomValueType = FieldCustomValueTypeEnum.Value }
|
new FieldsDefaultValue() { FieldName = "IsActive", FieldDbType = DbType.Boolean, Value = "true", CustomValueType = FieldCustomValueTypeEnum.Value }
|
||||||
|
}),
|
||||||
|
WidgetsJson = JsonSerializer.Serialize(new List<WidgetEditDto>
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
ColGap = 3,
|
||||||
|
ColSpan = 4,
|
||||||
|
SqlQuery = @"
|
||||||
|
SELECT
|
||||||
|
'Aktif' AS ""Title"",
|
||||||
|
COUNT(""Id"") AS ""Value"",
|
||||||
|
'blue' AS ""Color"",
|
||||||
|
'Aktif Kullanıcılar' AS ""SubTitle"",
|
||||||
|
'FaUserCheck' AS ""Icon""
|
||||||
|
FROM ""AbpUsers""
|
||||||
|
WHERE ""IsActive"" = 'true'
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
'Pasif' AS ""Title"",
|
||||||
|
COUNT(""Id"") AS ""Value"",
|
||||||
|
'green' AS ""Color"",
|
||||||
|
'Pasif Kullanıcılar' AS ""SubTitle"",
|
||||||
|
'FaUserSlash' AS ""Icon""
|
||||||
|
FROM ""AbpUsers""
|
||||||
|
WHERE ""IsActive"" = 'false'
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
'Doğrulama' AS ""Title"",
|
||||||
|
COUNT(""Id"") AS ""Value"",
|
||||||
|
'purple' AS ""Color"",
|
||||||
|
'Yönetici Doğrulaması bekleyenler' AS ""SubTitle"",
|
||||||
|
'FaUserClock' AS ""Icon""
|
||||||
|
FROM ""AbpUsers""
|
||||||
|
WHERE ""IsVerified"" = 'false';
|
||||||
|
",
|
||||||
|
Title = "Title",
|
||||||
|
Value = "Value",
|
||||||
|
ValueClassName = "bg-5 text-sm",
|
||||||
|
Color = "Color",
|
||||||
|
Icon = "Icon",
|
||||||
|
SubTitle = "SubTitle",
|
||||||
|
ClassName = "mb-3",
|
||||||
|
IsActive = true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import {
|
||||||
toast,
|
toast,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@/components/ui'
|
} from '@/components/ui'
|
||||||
|
import SqlEditor from '@/views/sqlQueryManager/components/SqlEditor'
|
||||||
import { ListFormJsonRowDto } from '@/proxy/admin/list-form/models'
|
import { ListFormJsonRowDto } from '@/proxy/admin/list-form/models'
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
import { SelectBoxOption } from '@/types/shared'
|
||||||
import { useStoreActions, useStoreState } from '@/store'
|
import { useStoreActions, useStoreState } from '@/store'
|
||||||
|
|
@ -89,16 +90,17 @@ function JsonRowOpDialogWidget({
|
||||||
data.widgetValues ?? {
|
data.widgetValues ?? {
|
||||||
colGap: 3,
|
colGap: 3,
|
||||||
colSpan: 3,
|
colSpan: 3,
|
||||||
sqlQuery: '',
|
sqlQuery:
|
||||||
|
"SELECT 'Total Records' as title, COUNT(*) as value, 'blue' as color, 'FaChartBar' as icon, 'Active records' as subTitle FROM YourTable WHERE IsActive = 1",
|
||||||
className: 'mb-3',
|
className: 'mb-3',
|
||||||
valueClassName: 'bg-5 text-sm',
|
valueClassName: 'bg-5 text-sm',
|
||||||
title: 'Title',
|
title: 'title',
|
||||||
value: 'Value',
|
value: 'value',
|
||||||
color: 'Color',
|
color: 'color',
|
||||||
icon: 'Icon',
|
icon: 'icon',
|
||||||
subTitle: 'SubTitle',
|
subTitle: 'subTitle',
|
||||||
onClick: '',
|
onClick: '',
|
||||||
isActive: false,
|
isActive: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
validationSchema={schema}
|
validationSchema={schema}
|
||||||
|
|
@ -135,11 +137,11 @@ function JsonRowOpDialogWidget({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, values, isSubmitting }) => (
|
{({ touched, errors, values, isSubmitting, setFieldValue }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<div className="h-full overflow-y-auto p-2">
|
<div className="h-full overflow-y-auto p-1">
|
||||||
<div className="grid grid-cols-3 gap-4">
|
<div className="grid grid-cols-5 gap-4">
|
||||||
<FormItem
|
<FormItem
|
||||||
label="Column Gap (Sütun Boşluğu)"
|
label="Column Gap (Sütun Boşluğu)"
|
||||||
invalid={errors.colGap && touched.colGap}
|
invalid={errors.colGap && touched.colGap}
|
||||||
|
|
@ -175,6 +177,52 @@ function JsonRowOpDialogWidget({
|
||||||
</Field>
|
</Field>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
|
<Tooltip
|
||||||
|
title={
|
||||||
|
<div className="text-xs">
|
||||||
|
<div className="font-semibold mb-1">Widget Container CSS Classes</div>
|
||||||
|
<div>Examples: mb-3, mt-2, p-4, rounded-lg, shadow-md</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FormItem
|
||||||
|
label="Class Name"
|
||||||
|
invalid={errors.className && touched.className}
|
||||||
|
errorMessage={errors.className}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
autoComplete="off"
|
||||||
|
name="className"
|
||||||
|
placeholder="Tailwind CSS classes: mb-3, mt-2, p-4..."
|
||||||
|
component={Input}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
<Tooltip
|
||||||
|
title={
|
||||||
|
<div className="text-xs">
|
||||||
|
<div className="font-semibold mb-1">Value Display CSS Classes</div>
|
||||||
|
<div>Examples: text-3xl, text-2xl, font-bold, text-sm, text-center</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FormItem
|
||||||
|
label="Value Class Name"
|
||||||
|
invalid={errors.valueClassName && touched.valueClassName}
|
||||||
|
errorMessage={errors.valueClassName}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
autoComplete="off"
|
||||||
|
name="valueClassName"
|
||||||
|
placeholder="Tailwind CSS classes: text-3xl, font-bold..."
|
||||||
|
component={Input}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
label="IsActive"
|
label="IsActive"
|
||||||
invalid={errors.isActive && touched.isActive}
|
invalid={errors.isActive && touched.isActive}
|
||||||
|
|
@ -189,25 +237,46 @@ function JsonRowOpDialogWidget({
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Tooltip
|
||||||
|
title={
|
||||||
|
<div className="text-xs max-h-96 overflow-y-auto">
|
||||||
|
<div className="font-semibold mb-2">SQL Query Examples:</div>
|
||||||
|
<div className="space-y-3">
|
||||||
|
<div>
|
||||||
|
<code className="text-xs bg-gray-800 p-1 rounded block mt-1">
|
||||||
|
SELECT 'Aktif' as title, COUNT(Id) as value,
|
||||||
|
<br />
|
||||||
|
'blue' as color, 'FaChartBar' as icon,
|
||||||
|
<br />
|
||||||
|
'Aktif kayıtlar' as subTitle
|
||||||
|
<br />
|
||||||
|
FROM YourTable WHERE IsActive = 1
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Sql Query
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
label="Sql Query"
|
|
||||||
invalid={errors.sqlQuery && touched.sqlQuery}
|
invalid={errors.sqlQuery && touched.sqlQuery}
|
||||||
errorMessage={errors.sqlQuery}
|
errorMessage={errors.sqlQuery}
|
||||||
>
|
>
|
||||||
<Field
|
<div
|
||||||
type="text"
|
className="border rounded-lg overflow-hidden"
|
||||||
autoComplete="off"
|
style={{ height: '200px' }}
|
||||||
name="sqlQuery"
|
>
|
||||||
placeholder="Sql Query"
|
<SqlEditor
|
||||||
component={Input}
|
value={values.sqlQuery || ''}
|
||||||
textArea={true}
|
onChange={(value) => setFieldValue('sqlQuery', value || '')}
|
||||||
|
height="200px"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<div className="bg-gray-100 p-1 rounded-md pb-2">
|
<div className="grid grid-cols-5 gap-2">
|
||||||
<span className="text-gray-500 font-bold">SQL Query Fields</span>
|
|
||||||
</div>
|
|
||||||
<div className="grid grid-cols-6 gap-2">
|
|
||||||
<FormItem
|
<FormItem
|
||||||
label="Title Field"
|
label="Title Field"
|
||||||
invalid={errors.title && touched.title}
|
invalid={errors.title && touched.title}
|
||||||
|
|
@ -217,7 +286,7 @@ function JsonRowOpDialogWidget({
|
||||||
type="text"
|
type="text"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
name="title"
|
name="title"
|
||||||
placeholder="Title Field"
|
placeholder="Column name from SQL query e.g., 'title'"
|
||||||
component={Input}
|
component={Input}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
@ -231,12 +300,30 @@ function JsonRowOpDialogWidget({
|
||||||
type="text"
|
type="text"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
name="value"
|
name="value"
|
||||||
placeholder="Value Field"
|
placeholder="Column name from SQL query e.g., 'value'"
|
||||||
component={Input}
|
component={Input}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Tooltip title={'blue, green, purple, gray, red, yellow, pink, indigo, teal'}>
|
<Tooltip
|
||||||
|
title={
|
||||||
|
<div className="text-xs">
|
||||||
|
<div className="font-semibold mb-1">Available Colors:</div>
|
||||||
|
<div className="grid grid-cols-2 gap-1">
|
||||||
|
<div>• blue</div>
|
||||||
|
<div>• green</div>
|
||||||
|
<div>• purple</div>
|
||||||
|
<div>• gray</div>
|
||||||
|
<div>• red</div>
|
||||||
|
<div>• yellow</div>
|
||||||
|
<div>• pink</div>
|
||||||
|
<div>• indigo</div>
|
||||||
|
<div>• teal</div>
|
||||||
|
<div>• orange</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
<FormItem
|
<FormItem
|
||||||
label="Color Field"
|
label="Color Field"
|
||||||
invalid={errors.color && touched.color}
|
invalid={errors.color && touched.color}
|
||||||
|
|
@ -246,7 +333,7 @@ function JsonRowOpDialogWidget({
|
||||||
type="text"
|
type="text"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
name="color"
|
name="color"
|
||||||
placeholder="Color"
|
placeholder="blue, green, purple, gray, red..."
|
||||||
component={Input}
|
component={Input}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
@ -254,7 +341,45 @@ function JsonRowOpDialogWidget({
|
||||||
|
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title={
|
title={
|
||||||
'FaHome, FaUser, FaSearch, FaCog, FaBell etc. (react-icons/fa icons)'
|
<div className="text-xs max-h-64 overflow-y-auto">
|
||||||
|
<div className="font-semibold mb-2">Popular Icon Examples:</div>
|
||||||
|
<div className="space-y-1">
|
||||||
|
<div>
|
||||||
|
📊 <strong>Charts:</strong> FaChartBar, FaChartLine, FaChartPie,
|
||||||
|
FaChartArea
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
💰 <strong>Finance:</strong> FaDollarSign, FaMoneyBill, FaWallet,
|
||||||
|
FaCreditCard
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
👥 <strong>Users:</strong> FaUser, FaUsers, FaUserCircle, FaUserTie
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
📦 <strong>Business:</strong> FaShoppingCart, FaBoxes, FaWarehouse,
|
||||||
|
FaTruck
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
📈 <strong>Analytics:</strong> FaArrowUp, FaArrowDown,
|
||||||
|
FaArrowTrendUp
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
⚙️ <strong>Settings:</strong> FaCog, FaTools, FaWrench
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
🔔 <strong>Alerts:</strong> FaBell, FaExclamation, FaInfoCircle
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
📁 <strong>Files:</strong> FaFile, FaFolder, FaFileAlt, FaDownload
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
🏠 <strong>Other:</strong> FaHome, FaBuilding, FaGlobe, FaHeart
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 pt-2 border-t">
|
||||||
|
All icons from <strong>react-icons/fa</strong> (Font Awesome)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<FormItem
|
<FormItem
|
||||||
|
|
@ -266,7 +391,7 @@ function JsonRowOpDialogWidget({
|
||||||
type="text"
|
type="text"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
name="icon"
|
name="icon"
|
||||||
placeholder="Icon"
|
placeholder="FaChartBar, FaUsers, FaShoppingCart..."
|
||||||
component={Input}
|
component={Input}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
@ -281,10 +406,11 @@ function JsonRowOpDialogWidget({
|
||||||
type="text"
|
type="text"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
name="subTitle"
|
name="subTitle"
|
||||||
placeholder="Sub Title"
|
placeholder="Column name from SQL query e.g., 'subTitle'"
|
||||||
component={Input}
|
component={Input}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
</div>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
label="On Click"
|
label="On Click"
|
||||||
|
|
@ -295,41 +421,12 @@ function JsonRowOpDialogWidget({
|
||||||
type="text"
|
type="text"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
name="onClick"
|
name="onClick"
|
||||||
placeholder="On Click"
|
placeholder="JavaScript function: () => alert('Clicked')"
|
||||||
component={Input}
|
component={Input}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="text-right mt-2">
|
||||||
<FormItem
|
|
||||||
label="Class Name"
|
|
||||||
invalid={errors.className && touched.className}
|
|
||||||
errorMessage={errors.className}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
type="text"
|
|
||||||
autoComplete="off"
|
|
||||||
name="className"
|
|
||||||
placeholder="Class Name"
|
|
||||||
component={Input}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
|
|
||||||
<FormItem
|
|
||||||
label="Value Class Name"
|
|
||||||
invalid={errors.valueClassName && touched.valueClassName}
|
|
||||||
errorMessage={errors.valueClassName}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
type="text"
|
|
||||||
autoComplete="off"
|
|
||||||
name="valueClassName"
|
|
||||||
placeholder="Value Class Name"
|
|
||||||
component={Input}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
</div>
|
|
||||||
<div className="text-right mt-4">
|
|
||||||
<Button className="ltr:mr-2 rtl:ml-2" variant="plain" onClick={handleClose}>
|
<Button className="ltr:mr-2 rtl:ml-2" variant="plain" onClick={handleClose}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue