Optimizasyon değişimleri
This commit is contained in:
parent
e96498645a
commit
3251c8bda4
184 changed files with 1470 additions and 3008 deletions
|
|
@ -44,7 +44,7 @@
|
||||||
"code": "App.SiteManagement.Theme.Style",
|
"code": "App.SiteManagement.Theme.Style",
|
||||||
"nameKey": "App.SiteManagement.Theme.Style",
|
"nameKey": "App.SiteManagement.Theme.Style",
|
||||||
"descriptionKey": "App.SiteManagement.Theme.Style.Description",
|
"descriptionKey": "App.SiteManagement.Theme.Style.Description",
|
||||||
"defaultValue": "dx.material.blue.light.compact",
|
"defaultValue": "dx.material.blue.dark.compact",
|
||||||
"isVisibleToClients": true,
|
"isVisibleToClients": true,
|
||||||
"providers": "U|G|D",
|
"providers": "U|G|D",
|
||||||
"isInherited": false,
|
"isInherited": false,
|
||||||
|
|
|
||||||
|
|
@ -10254,6 +10254,12 @@
|
||||||
"en": "Active",
|
"en": "Active",
|
||||||
"tr": "Aktif"
|
"tr": "Aktif"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Status.Inactive",
|
||||||
|
"en": "Inactive",
|
||||||
|
"tr": "Pasif"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.DeveloperKit.ComponentEditor.Save",
|
"key": "App.DeveloperKit.ComponentEditor.Save",
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,7 @@ interface ComponentCodeEditorProps {
|
||||||
onResetCodeChanges: () => void
|
onResetCodeChanges: () => void
|
||||||
language?: string
|
language?: string
|
||||||
theme?: 'vs-dark' | 'light'
|
theme?: 'vs-dark' | 'light'
|
||||||
parseError?: string | null
|
|
||||||
onCursorChange?: (componentId: string | null) => void
|
onCursorChange?: (componentId: string | null) => void
|
||||||
onDrop?: (componentDef: ComponentDefinition, position: { line: number; column: number }) => void
|
|
||||||
onComponentAdded?: (componentDef: ComponentDefinition) => void
|
onComponentAdded?: (componentDef: ComponentDefinition) => void
|
||||||
onComponentSave: () => void
|
onComponentSave: () => void
|
||||||
}
|
}
|
||||||
|
|
@ -24,6 +22,7 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
code,
|
code,
|
||||||
onChange,
|
onChange,
|
||||||
onApplyCodeChanges,
|
onApplyCodeChanges,
|
||||||
|
onResetCodeChanges,
|
||||||
language = 'typescript',
|
language = 'typescript',
|
||||||
theme = 'vs-dark',
|
theme = 'vs-dark',
|
||||||
onCursorChange,
|
onCursorChange,
|
||||||
|
|
@ -48,7 +47,6 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
|
|
||||||
const editorRef = useRef<any>(null)
|
const editorRef = useRef<any>(null)
|
||||||
const containerRef = useRef<HTMLDivElement>(null)
|
const containerRef = useRef<HTMLDivElement>(null)
|
||||||
const cursorChangeTimeout = useRef<number | null>(null)
|
|
||||||
// Refs to keep latest values accessible inside native DOM listeners
|
// Refs to keep latest values accessible inside native DOM listeners
|
||||||
const localCodeRef = useRef(localCode)
|
const localCodeRef = useRef(localCode)
|
||||||
const dropCallbacksRef = useRef({ onChange, onComponentAdded, onApplyCodeChanges })
|
const dropCallbacksRef = useRef({ onChange, onComponentAdded, onApplyCodeChanges })
|
||||||
|
|
@ -66,14 +64,6 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
dropCallbacksRef.current = { onChange, onComponentAdded, onApplyCodeChanges }
|
dropCallbacksRef.current = { onChange, onComponentAdded, onApplyCodeChanges }
|
||||||
}, [onChange, onComponentAdded, onApplyCodeChanges])
|
}, [onChange, onComponentAdded, onApplyCodeChanges])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
return () => {
|
|
||||||
if (cursorChangeTimeout.current) {
|
|
||||||
clearTimeout(cursorChangeTimeout.current)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const findComponentIdAtPosition = (
|
const findComponentIdAtPosition = (
|
||||||
code: string,
|
code: string,
|
||||||
position: { lineNumber: number; column: number },
|
position: { lineNumber: number; column: number },
|
||||||
|
|
@ -169,7 +159,10 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
if (ch === '(') parenDepth++
|
if (ch === '(') parenDepth++
|
||||||
else if (ch === ')') {
|
else if (ch === ')') {
|
||||||
parenDepth--
|
parenDepth--
|
||||||
if (parenDepth <= 0) { insideReturn = false; break }
|
if (parenDepth <= 0) {
|
||||||
|
insideReturn = false
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -178,7 +171,10 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
if (ch === '(') parenDepth++
|
if (ch === '(') parenDepth++
|
||||||
else if (ch === ')') {
|
else if (ch === ')') {
|
||||||
parenDepth--
|
parenDepth--
|
||||||
if (parenDepth <= 0) { insideReturn = false; break }
|
if (parenDepth <= 0) {
|
||||||
|
insideReturn = false
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -186,15 +182,11 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
return insideReturn
|
return insideReturn
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleEditorCursorChange = (_event: any) => {
|
const handleEditorCursorChange = () => {
|
||||||
if (!editorRef.current) return
|
if (!editorRef.current) return
|
||||||
const position = editorRef.current.getPosition()
|
const position = editorRef.current.getPosition()
|
||||||
if (!position) return
|
if (!position) return
|
||||||
|
|
||||||
// Throttle the cursor change to avoid too many calls
|
|
||||||
if (cursorChangeTimeout.current) {
|
|
||||||
clearTimeout(cursorChangeTimeout.current)
|
|
||||||
}
|
|
||||||
const id = findComponentIdAtPosition(localCode, position)
|
const id = findComponentIdAtPosition(localCode, position)
|
||||||
if (onCursorChange) onCursorChange(id)
|
if (onCursorChange) onCursorChange(id)
|
||||||
}
|
}
|
||||||
|
|
@ -242,12 +234,19 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
let componentDefData: string | undefined
|
let componentDefData: string | undefined
|
||||||
for (const fmt of ['application/json', 'text/plain']) {
|
for (const fmt of ['application/json', 'text/plain']) {
|
||||||
const d = nativeEvent.dataTransfer.getData(fmt)
|
const d = nativeEvent.dataTransfer.getData(fmt)
|
||||||
if (d) { componentDefData = d; break }
|
if (d) {
|
||||||
|
componentDefData = d
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!componentDefData) return
|
if (!componentDefData) return
|
||||||
|
|
||||||
let componentDef: any
|
let componentDef: any
|
||||||
try { componentDef = JSON.parse(componentDefData) } catch { return }
|
try {
|
||||||
|
componentDef = JSON.parse(componentDefData)
|
||||||
|
} catch {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!componentDef?.name) return
|
if (!componentDef?.name) return
|
||||||
|
|
||||||
// Resolve the drop position inside Monaco
|
// Resolve the drop position inside Monaco
|
||||||
|
|
@ -300,8 +299,11 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
const newCode = newLines.join('\n')
|
const newCode = newLines.join('\n')
|
||||||
|
|
||||||
setLocalCode(newCode)
|
setLocalCode(newCode)
|
||||||
const { onChange: onChg, onComponentAdded: onAdded, onApplyCodeChanges: onApply } =
|
const {
|
||||||
dropCallbacksRef.current
|
onChange: onChg,
|
||||||
|
onComponentAdded: onAdded,
|
||||||
|
onApplyCodeChanges: onApply,
|
||||||
|
} = dropCallbacksRef.current
|
||||||
onChg(newCode)
|
onChg(newCode)
|
||||||
if (onAdded) onAdded(componentDefWithId)
|
if (onAdded) onAdded(componentDefWithId)
|
||||||
setTimeout(() => onApply(newCode), 100)
|
setTimeout(() => onApply(newCode), 100)
|
||||||
|
|
@ -346,6 +348,7 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
const handleResetChanges = () => {
|
const handleResetChanges = () => {
|
||||||
setLocalCode(code)
|
setLocalCode(code)
|
||||||
setHasChanges(false)
|
setHasChanges(false)
|
||||||
|
onResetCodeChanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drag & Drop handlers for Code Editor
|
// Drag & Drop handlers for Code Editor
|
||||||
|
|
@ -561,53 +564,53 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
<div className="bg-gray-800 border-b border-gray-700 p-4 flex items-end justify-between shrink-0">
|
<div className="bg-gray-800 border-b border-gray-700 p-4 flex items-end justify-between shrink-0">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button
|
<Button
|
||||||
onClick={handleFormatCode}
|
|
||||||
loading={isFormatting}
|
loading={isFormatting}
|
||||||
icon={<FaCode className="w-4 h-4" />}
|
icon={<FaCode className="w-4 h-4" />}
|
||||||
variant="default"
|
variant="default"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
onClick={handleFormatCode}
|
||||||
>
|
>
|
||||||
Formatla
|
Formatla
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={() => setShowSettings(!showSettings)}
|
|
||||||
icon={<FaCog className="w-4 h-4" />}
|
icon={<FaCog className="w-4 h-4" />}
|
||||||
variant={showSettings ? 'solid' : 'default'}
|
variant={showSettings ? 'solid' : 'default'}
|
||||||
color="blue-600"
|
color="blue-600"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
onClick={() => setShowSettings(!showSettings)}
|
||||||
>
|
>
|
||||||
Ayarlar
|
Ayarlar
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={handleResetChanges}
|
|
||||||
icon={<FaTimes className="w-4 h-4" />}
|
icon={<FaTimes className="w-4 h-4" />}
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="red-600"
|
color="red-600"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
onClick={handleResetChanges}
|
||||||
>
|
>
|
||||||
Sıfırla
|
Sıfırla
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={handleApplyChanges}
|
|
||||||
icon={<FaCheck className="w-4 h-4" />}
|
icon={<FaCheck className="w-4 h-4" />}
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="green-600"
|
color="green-600"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
onClick={handleApplyChanges}
|
||||||
>
|
>
|
||||||
Uygula
|
Uygula
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-2 flex items-center justify-end">
|
<div className="col-span-2 flex items-center justify-end">
|
||||||
<Button
|
<Button
|
||||||
onClick={onComponentSave}
|
|
||||||
icon={<FaSave className="w-4 h-4" />}
|
icon={<FaSave className="w-4 h-4" />}
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="yellow-600"
|
color="yellow-600"
|
||||||
size="sm"
|
size="sm"
|
||||||
className="shadow-sm"
|
className="shadow-sm"
|
||||||
|
onClick={onComponentSave}
|
||||||
>
|
>
|
||||||
Kaydet
|
Kaydet
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -622,8 +625,8 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
<label className="block text-sm font-medium text-gray-300 mb-2">Tema</label>
|
<label className="block text-sm font-medium text-gray-300 mb-2">Tema</label>
|
||||||
<select
|
<select
|
||||||
value={editorTheme}
|
value={editorTheme}
|
||||||
onChange={(e) => setEditorTheme(e.target.value as 'vs-dark' | 'light')}
|
|
||||||
className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-md text-white text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-md text-white text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
onChange={(e) => setEditorTheme(e.target.value as 'vs-dark' | 'light')}
|
||||||
>
|
>
|
||||||
<option value="vs-dark">Koyu</option>
|
<option value="vs-dark">Koyu</option>
|
||||||
<option value="light">Açık</option>
|
<option value="light">Açık</option>
|
||||||
|
|
@ -637,8 +640,8 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
min="10"
|
min="10"
|
||||||
max="24"
|
max="24"
|
||||||
value={fontSize}
|
value={fontSize}
|
||||||
onChange={(e) => setFontSize(parseInt(e.target.value))}
|
|
||||||
className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-md text-white text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-md text-white text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
onChange={(e) => setFontSize(parseInt(e.target.value))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -648,8 +651,8 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
value={wordWrap}
|
value={wordWrap}
|
||||||
onChange={(e) => setWordWrap(e.target.value as 'on' | 'off')}
|
|
||||||
className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-md text-white text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-md text-white text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
onChange={(e) => setWordWrap(e.target.value as 'on' | 'off')}
|
||||||
>
|
>
|
||||||
<option value="on">Açık</option>
|
<option value="on">Açık</option>
|
||||||
<option value="off">Kapalı</option>
|
<option value="off">Kapalı</option>
|
||||||
|
|
@ -659,11 +662,11 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-300 mb-2">Mini Harita</label>
|
<label className="block text-sm font-medium text-gray-300 mb-2">Mini Harita</label>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => setMinimap(!minimap)}
|
|
||||||
block
|
block
|
||||||
variant={minimap ? 'solid' : 'default'}
|
variant={minimap ? 'solid' : 'default'}
|
||||||
color="blue-600"
|
color="blue-600"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
onClick={() => setMinimap(!minimap)}
|
||||||
>
|
>
|
||||||
{minimap ? 'Etkin' : 'Devre Dışı'}
|
{minimap ? 'Etkin' : 'Devre Dışı'}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -680,8 +683,6 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
language={language}
|
language={language}
|
||||||
theme={editorTheme}
|
theme={editorTheme}
|
||||||
value={localCode}
|
value={localCode}
|
||||||
onChange={handleCodeChange}
|
|
||||||
onMount={handleEditorDidMount}
|
|
||||||
options={{
|
options={{
|
||||||
fontSize: fontSize,
|
fontSize: fontSize,
|
||||||
wordWrap: wordWrap,
|
wordWrap: wordWrap,
|
||||||
|
|
@ -748,6 +749,8 @@ export const ComponentCodeEditor: React.FC<ComponentCodeEditorProps> = ({
|
||||||
formatOnPaste: true,
|
formatOnPaste: true,
|
||||||
formatOnType: true,
|
formatOnType: true,
|
||||||
}}
|
}}
|
||||||
|
onChange={handleCodeChange}
|
||||||
|
onMount={handleEditorDidMount}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import TailwindModal from "./TailwindModal";
|
import TailwindModal from "./TailwindModal";
|
||||||
import { ComponentInfo, HookInfo, PropertyInfo } from "../../proxy/developerKit/componentInfo";
|
import { ComponentInfo, HookInfo, PropertyInfo } from "../../proxy/developerKit/componentInfo";
|
||||||
import { getComponentDefinition } from "./data/componentDefinitions";
|
import { getComponentDefinition } from "./data/componentDefinitions";
|
||||||
|
|
@ -113,15 +113,6 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
||||||
setHasHookChanges(true);
|
setHasHookChanges(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle local event changes
|
|
||||||
const handleLocalEventChange = (eventName: string, value: string) => {
|
|
||||||
setPendingEvents((prev) => ({
|
|
||||||
...prev,
|
|
||||||
[eventName]: value,
|
|
||||||
}));
|
|
||||||
setHasChanges(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Apply only property/event changes
|
// Apply only property/event changes
|
||||||
const handleApplyPropChanges = () => {
|
const handleApplyPropChanges = () => {
|
||||||
if (!selectedComponent) return;
|
if (!selectedComponent) return;
|
||||||
|
|
@ -222,7 +213,7 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
||||||
if (property.type === "array") {
|
if (property.type === "array") {
|
||||||
try {
|
try {
|
||||||
arrayInputValue = JSON.stringify(value, null, 2);
|
arrayInputValue = JSON.stringify(value, null, 2);
|
||||||
} catch (e) {
|
} catch {
|
||||||
arrayInputValue = "";
|
arrayInputValue = "";
|
||||||
arrayError = "Array verisi gösterilemiyor.";
|
arrayError = "Array verisi gösterilemiyor.";
|
||||||
}
|
}
|
||||||
|
|
@ -365,7 +356,7 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
||||||
const parsed = JSON.parse(e.target.value);
|
const parsed = JSON.parse(e.target.value);
|
||||||
handleLocalPropertyChange(property.name, parsed);
|
handleLocalPropertyChange(property.name, parsed);
|
||||||
arrayError = "";
|
arrayError = "";
|
||||||
} catch (err) {
|
} catch {
|
||||||
arrayError = "Geçersiz JSON formatı";
|
arrayError = "Geçersiz JSON formatı";
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { searchTailwindClasses, TAILWIND_CLASSES } from './data/tailwindClasses';
|
import { searchTailwindClasses, TAILWIND_CLASSES } from './data/tailwindClasses';
|
||||||
import { Button } from '../ui';
|
import { Button } from '../ui';
|
||||||
import { FaTimes } from 'react-icons/fa';
|
import { FaTimes } from 'react-icons/fa';
|
||||||
|
|
@ -40,12 +40,6 @@ const TailwindModal: React.FC<TailwindModalProps> = ({
|
||||||
// Don't close modal - let user select multiple classes
|
// Don't close modal - let user select multiple classes
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAddToCurrentValue = (className: string) => {
|
|
||||||
const newValue = currentValue ? `${currentValue} ${className}` : className;
|
|
||||||
onSelectClass(newValue);
|
|
||||||
// Don't close modal - let user continue selecting
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
declare interface Window {
|
declare interface Window {
|
||||||
ReactDOM?: {
|
ReactDOM?: {
|
||||||
render: (element: React.ReactNode, container: Element) => void;
|
render: (element: React.ReactNode, container: Element) => void;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import React from "react";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
|
||||||
interface InfoSectionProps {
|
interface InfoSectionProps {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { iconList } from "./iconList";
|
import { iconList } from "./iconList";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import Widget, { type colorType } from "./Widget";
|
import Widget, { type colorType } from "./Widget";
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import { WidgetEditDto, WidgetGroupDto } from "../../types/common";
|
import { WidgetEditDto, WidgetGroupDto } from "../../types/common";
|
||||||
|
|
||||||
export default function WidgetGroup({
|
export default function WidgetGroup({
|
||||||
|
|
@ -8,8 +7,6 @@ export default function WidgetGroup({
|
||||||
}: {
|
}: {
|
||||||
widgetGroups: WidgetGroupDto[];
|
widgetGroups: WidgetGroupDto[];
|
||||||
}) {
|
}) {
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{widgetGroups.map((group, gIdx) => (
|
{widgetGroups.map((group, gIdx) => (
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { cloneElement } from 'react'
|
import React, { cloneElement } from 'react'
|
||||||
import Avatar from '@/components/ui/Avatar'
|
import Avatar from '@/components/ui/Avatar'
|
||||||
import Logo from '@/components/template/Logo'
|
import Logo from '@/components/template/Logo'
|
||||||
import { APP_NAME } from '@/constants/app.constant'
|
import { APP_NAME } from '@/constants/app.constant'
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,10 @@
|
||||||
import React from 'react'
|
import type { PropsWithChildren } from 'react'
|
||||||
import { FaTachometerAlt, FaDatabase, FaBolt, FaServer, FaPuzzlePiece } from 'react-icons/fa'
|
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
|
||||||
import { useLocation, useNavigate } from 'react-router-dom'
|
|
||||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
|
||||||
import { Container } from '../shared'
|
import { Container } from '../shared'
|
||||||
|
|
||||||
interface DeveloperLayoutProps {
|
const DeveloperLayout = ({ children }: PropsWithChildren) => {
|
||||||
children: React.ReactNode
|
|
||||||
}
|
|
||||||
|
|
||||||
const DeveloperLayout: React.FC<DeveloperLayoutProps> = ({ children }) => {
|
|
||||||
const { translate } = useLocalization()
|
|
||||||
const location = useLocation()
|
|
||||||
const navigate = useNavigate()
|
|
||||||
|
|
||||||
const navigation = [
|
|
||||||
{
|
|
||||||
id: 'entities',
|
|
||||||
label: translate('::App.DeveloperKit.Entity'),
|
|
||||||
icon: FaDatabase,
|
|
||||||
path: ROUTES_ENUM.protected.saas.developerKit.entities,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'endpoints',
|
|
||||||
label: translate('::App.DeveloperKit.CrudEndpoints'),
|
|
||||||
icon: FaServer,
|
|
||||||
path: ROUTES_ENUM.protected.saas.developerKit.endpoints,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'components',
|
|
||||||
label: translate('::App.DeveloperKit.Components'),
|
|
||||||
icon: FaPuzzlePiece,
|
|
||||||
path: ROUTES_ENUM.protected.saas.developerKit.components,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<div className="flex flex-col lg:flex-row gap-8">
|
<div className="flex flex-col lg:flex-row gap-8">
|
||||||
{/* Main Content */}
|
|
||||||
<div className="flex-1">{children}</div>
|
<div className="flex-1">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ export const BillingControls: React.FC<BillingControlsProps> = ({
|
||||||
setGlobalBillingCycle,
|
setGlobalBillingCycle,
|
||||||
setGlobalPeriod,
|
setGlobalPeriod,
|
||||||
onCartClick,
|
onCartClick,
|
||||||
onNavigate,
|
|
||||||
cartItemsCount,
|
cartItemsCount,
|
||||||
cartState,
|
cartState,
|
||||||
}) => {
|
}) => {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ interface OrderSuccessProps {
|
||||||
onBackToShop: () => void
|
onBackToShop: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const OrderSuccess: React.FC<OrderSuccessProps> = ({ orderId, onBackToShop }) => {
|
export const OrderSuccess: React.FC<OrderSuccessProps> = ({ orderId }) => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
import { FaPlus, FaMinus } from 'react-icons/fa'
|
import { FaPlus, FaMinus } from 'react-icons/fa'
|
||||||
import { BillingCycle, Product, ProductDto } from '@/proxy/order/models'
|
import { BillingCycle, ProductDto } from '@/proxy/order/models'
|
||||||
import { CartState } from '@/utils/cartUtils'
|
import { CartState } from '@/utils/cartUtils'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { Button } from '@/components/ui'
|
import { Button } from '@/components/ui'
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@ import { Link } from 'react-router-dom'
|
||||||
import type { CommonProps } from '@/proxy/common'
|
import type { CommonProps } from '@/proxy/common'
|
||||||
import type { ComponentPropsWithoutRef } from 'react'
|
import type { ComponentPropsWithoutRef } from 'react'
|
||||||
|
|
||||||
interface ActionLink extends CommonProps, ComponentPropsWithoutRef<'a'> {
|
interface ActionLinkProps extends CommonProps, ComponentPropsWithoutRef<'a'> {
|
||||||
themeColor?: boolean
|
themeColor?: boolean
|
||||||
to?: string
|
to?: string
|
||||||
href?: string
|
href?: string
|
||||||
reloadDocument?: boolean
|
reloadDocument?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const ActionLink = (props: ActionLink) => {
|
const ActionLink = (props: ActionLinkProps) => {
|
||||||
const {
|
const {
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { MigrateLogEntry } from '@/proxy/setup/models'
|
import { MigrateLogEntry } from '@/proxy/setup/models'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { createRoot } from 'react-dom/client'
|
import { createRoot } from 'react-dom/client'
|
||||||
import { Button } from '@/components/ui'
|
import { Button } from '@/components/ui'
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { forwardRef } from 'react'
|
import React, { forwardRef } from 'react'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import useThemeClass from '@/utils/hooks/useThemeClass'
|
import useThemeClass from '@/utils/hooks/useThemeClass'
|
||||||
import { FaCheckCircle } from 'react-icons/fa'
|
import { FaCheckCircle } from 'react-icons/fa'
|
||||||
|
|
|
||||||
|
|
@ -179,34 +179,58 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Example components for testing
|
// Example components for testing
|
||||||
const HelloWorldComponent: React.ComponentType<unknown> = () => {
|
const HelloWorldComponent: React.ComponentType<unknown> = () => {
|
||||||
return React.createElement('div', {
|
return React.createElement(
|
||||||
className: 'p-6 bg-blue-50 rounded-lg'
|
'div',
|
||||||
}, [
|
{
|
||||||
React.createElement('h1', {
|
className: 'p-6 bg-blue-50 rounded-lg',
|
||||||
className: 'text-2xl font-bold text-blue-900 mb-4'
|
},
|
||||||
}, 'Hello World!'),
|
[
|
||||||
React.createElement('p', {
|
React.createElement(
|
||||||
className: 'text-blue-700'
|
'h1',
|
||||||
}, 'Bu manuel kayıtlı bir komponent!')
|
{
|
||||||
])
|
className: 'text-2xl font-bold text-blue-900 mb-4',
|
||||||
|
},
|
||||||
|
'Hello World!',
|
||||||
|
),
|
||||||
|
React.createElement(
|
||||||
|
'p',
|
||||||
|
{
|
||||||
|
className: 'text-blue-700',
|
||||||
|
},
|
||||||
|
'Bu manuel kayıtlı bir komponent!',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const TestListComponent: React.ComponentType<unknown> = () => {
|
const TestListComponent: React.ComponentType<unknown> = () => {
|
||||||
return React.createElement('div', {
|
return React.createElement(
|
||||||
className: 'p-6 bg-green-50 rounded-lg'
|
'div',
|
||||||
}, [
|
{
|
||||||
React.createElement('h1', {
|
className: 'p-6 bg-green-50 rounded-lg',
|
||||||
className: 'text-2xl font-bold text-green-900 mb-4'
|
},
|
||||||
}, 'Test List'),
|
[
|
||||||
React.createElement('p', {
|
React.createElement(
|
||||||
className: 'text-green-700'
|
'h1',
|
||||||
}, 'Bu da test için kayıtlı komponent!')
|
{
|
||||||
])
|
className: 'text-2xl font-bold text-green-900 mb-4',
|
||||||
|
},
|
||||||
|
'Test List',
|
||||||
|
),
|
||||||
|
React.createElement(
|
||||||
|
'p',
|
||||||
|
{
|
||||||
|
className: 'text-green-700',
|
||||||
|
},
|
||||||
|
'Bu da test için kayıtlı komponent!',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
registerComponent('HelloWorld', HelloWorldComponent)
|
registerComponent('HelloWorld', HelloWorldComponent)
|
||||||
registerComponent('TestList', TestListComponent)
|
registerComponent('TestList', TestListComponent)
|
||||||
}, []) // Empty dependency array - only run once
|
}, []) // Empty dependency array - only run once
|
||||||
|
|
||||||
// Component compilation functions (moved from ComponentRegistryProvider)
|
// Component compilation functions (moved from ComponentRegistryProvider)
|
||||||
const extractComponentInfo = useCallback((code: string, defaultName = '') => {
|
const extractComponentInfo = useCallback((code: string, defaultName = '') => {
|
||||||
|
|
@ -269,8 +293,8 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
||||||
const componentDefinitions = componentInfos
|
const componentDefinitions = componentInfos
|
||||||
.map((info) => {
|
.map((info) => {
|
||||||
const componentVariables = componentInfos
|
const componentVariables = componentInfos
|
||||||
.filter(other => other.name !== info.name)
|
.filter((other) => other.name !== info.name)
|
||||||
.map(other => `const ${other.name} = ${other.name}_Component;`)
|
.map((other) => `const ${other.name} = ${other.name}_Component;`)
|
||||||
.join('\n ')
|
.join('\n ')
|
||||||
|
|
||||||
return `
|
return `
|
||||||
|
|
@ -314,12 +338,90 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
||||||
}
|
}
|
||||||
|
|
||||||
const componentsFactory = new Function(
|
const componentsFactory = new Function(
|
||||||
'React', 'Alert', 'Avatar', 'Badge', 'Button', 'Calendar', 'Card', 'Checkbox', 'ConfigProvider', 'DatePicker', 'Dialog', 'Drawer', 'Dropdown', 'FormItem', 'FormContainer', 'Input', 'InputGroup', 'Menu', 'MenuItem', 'Notification', 'Pagination', 'Progress', 'Radio', 'RangeCalendar', 'ScrollBar', 'Segment', 'Select', 'Skeleton', 'Spinner', 'Steps', 'Switcher', 'Table', 'Tabs', 'Tag', 'TimeInput', 'Timeline', 'toast', 'Tooltip', 'Upload', 'axios',
|
'React',
|
||||||
|
'Alert',
|
||||||
|
'Avatar',
|
||||||
|
'Badge',
|
||||||
|
'Button',
|
||||||
|
'Calendar',
|
||||||
|
'Card',
|
||||||
|
'Checkbox',
|
||||||
|
'ConfigProvider',
|
||||||
|
'DatePicker',
|
||||||
|
'Dialog',
|
||||||
|
'Drawer',
|
||||||
|
'Dropdown',
|
||||||
|
'FormItem',
|
||||||
|
'FormContainer',
|
||||||
|
'Input',
|
||||||
|
'InputGroup',
|
||||||
|
'Menu',
|
||||||
|
'MenuItem',
|
||||||
|
'Notification',
|
||||||
|
'Pagination',
|
||||||
|
'Progress',
|
||||||
|
'Radio',
|
||||||
|
'RangeCalendar',
|
||||||
|
'ScrollBar',
|
||||||
|
'Segment',
|
||||||
|
'Select',
|
||||||
|
'Skeleton',
|
||||||
|
'Spinner',
|
||||||
|
'Steps',
|
||||||
|
'Switcher',
|
||||||
|
'Table',
|
||||||
|
'Tabs',
|
||||||
|
'Tag',
|
||||||
|
'TimeInput',
|
||||||
|
'Timeline',
|
||||||
|
'toast',
|
||||||
|
'Tooltip',
|
||||||
|
'Upload',
|
||||||
|
'axios',
|
||||||
`return ${compiledBundle}`,
|
`return ${compiledBundle}`,
|
||||||
)
|
)
|
||||||
|
|
||||||
const compiledComponentsRegistry = componentsFactory(
|
const compiledComponentsRegistry = componentsFactory(
|
||||||
React, Alert, Avatar, Badge, Button, Calendar, Card, Checkbox, ConfigProvider, DatePicker, Dialog, Drawer, Dropdown, FormItem, FormContainer, Input, InputGroup, Menu, MenuItem, Notification, Pagination, Progress, Radio, RangeCalendar, ScrollBar, Segment, Select, Skeleton, Spinner, Steps, Switcher, Table, Tabs, Tag, TimeInput, Timeline, toast, Tooltip, Upload, axios,
|
React,
|
||||||
|
Alert,
|
||||||
|
Avatar,
|
||||||
|
Badge,
|
||||||
|
Button,
|
||||||
|
Calendar,
|
||||||
|
Card,
|
||||||
|
Checkbox,
|
||||||
|
ConfigProvider,
|
||||||
|
DatePicker,
|
||||||
|
Dialog,
|
||||||
|
Drawer,
|
||||||
|
Dropdown,
|
||||||
|
FormItem,
|
||||||
|
FormContainer,
|
||||||
|
Input,
|
||||||
|
InputGroup,
|
||||||
|
Menu,
|
||||||
|
MenuItem,
|
||||||
|
Notification,
|
||||||
|
Pagination,
|
||||||
|
Progress,
|
||||||
|
Radio,
|
||||||
|
RangeCalendar,
|
||||||
|
ScrollBar,
|
||||||
|
Segment,
|
||||||
|
Select,
|
||||||
|
Skeleton,
|
||||||
|
Spinner,
|
||||||
|
Steps,
|
||||||
|
Switcher,
|
||||||
|
Table,
|
||||||
|
Tabs,
|
||||||
|
Tag,
|
||||||
|
TimeInput,
|
||||||
|
Timeline,
|
||||||
|
toast,
|
||||||
|
Tooltip,
|
||||||
|
Upload,
|
||||||
|
axios,
|
||||||
)
|
)
|
||||||
|
|
||||||
setCompiledComponents(compiledComponentsRegistry)
|
setCompiledComponents(compiledComponentsRegistry)
|
||||||
|
|
@ -352,14 +454,11 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
||||||
[components, compiledComponents],
|
[components, compiledComponents],
|
||||||
)
|
)
|
||||||
|
|
||||||
const compileAndRender = useCallback(
|
const compileAndRender = useCallback((code: string) => {
|
||||||
(code: string, props: ComponentProps = {}) => {
|
if (!code?.trim()) return null
|
||||||
if (!code?.trim()) return null
|
// Simplified version - can be extended later
|
||||||
// Simplified version - can be extended later
|
return <div>Code compilation not implemented yet</div>
|
||||||
return <div>Code compilation not implemented yet</div>
|
}, [])
|
||||||
},
|
|
||||||
[],
|
|
||||||
)
|
|
||||||
|
|
||||||
const isComponentRegistered = useCallback(
|
const isComponentRegistered = useCallback(
|
||||||
(name: string) => {
|
(name: string) => {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { createContext, useContext } from 'react'
|
import { createContext, useContext } from 'react'
|
||||||
|
|
||||||
interface DemoContextValue {
|
interface DemoContextValue {
|
||||||
openDemo: () => void
|
openDemo: () => void
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// ScrollContext.tsx
|
// ScrollContext.tsx
|
||||||
import React, { createContext, useContext } from 'react'
|
import { createContext, useContext } from 'react'
|
||||||
|
|
||||||
export const ScrollContext = createContext<boolean>(false)
|
export const ScrollContext = createContext<boolean>(false)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
import React, { lazy } from 'react'
|
||||||
import { RouteDto } from '@/proxy/routes/models'
|
import { RouteDto } from '@/proxy/routes/models'
|
||||||
import { lazy } from 'react'
|
|
||||||
|
|
||||||
// Tüm view bileşenlerini import et (vite özel)
|
// Tüm view bileşenlerini import et (vite özel)
|
||||||
// shared klasörü hariç, çünkü bu bileşenler genellikle başka yerlerde statik import ediliyor
|
// shared klasörü hariç, çünkü bu bileşenler genellikle başka yerlerde statik import ediliyor
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ export const deleteListFormJsonRow = (id: string, field: string, index: number)
|
||||||
url: `/api/admin/list-form-json-row/${id}?field=${field}&index=${index}`,
|
url: `/api/admin/list-form-json-row/${id}?field=${field}&index=${index}`,
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getListFormSelectQueryByCode = (listFormCode?: string, op: number = -1) =>
|
export const getListFormSelectQueryByCode = (listFormCode?: string) =>
|
||||||
apiService.fetchData<string>({
|
apiService.fetchData<string>({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: `/api/admin/list-form-query-preview/form-select-query`,
|
url: `/api/admin/list-form-query-preview/form-select-query`,
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class NoteService {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async downloadFile(savedFileName: string, fileName: string, fileType: string) {
|
async downloadFile(savedFileName: string, fileName: string) {
|
||||||
const response = await apiService.fetchData<NoteFileDto>({
|
const response = await apiService.fetchData<NoteFileDto>({
|
||||||
url: `/api/app/note/download?savedFileName=${savedFileName}`,
|
url: `/api/app/note/download?savedFileName=${savedFileName}`,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { InstallmentOptionDto, OrderDto, PaymentMethodDto, ProductDto } from '@/proxy/order/models'
|
import { InstallmentOptionDto, OrderDto, PaymentMethodDto, ProductDto } from '@/proxy/order/models'
|
||||||
import apiService, { Config } from '@/services/api.service'
|
import apiService from '@/services/api.service'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
export class OrderService {
|
export class OrderService {
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ platformApiService.interceptors.response.use(
|
||||||
signOut()
|
signOut()
|
||||||
error.silent = true
|
error.silent = true
|
||||||
}
|
}
|
||||||
} catch (error2) {
|
} catch {
|
||||||
await revokeTokens({
|
await revokeTokens({
|
||||||
token: auth.session.token,
|
token: auth.session.token,
|
||||||
refreshToken: auth.session.refreshToken,
|
refreshToken: auth.session.refreshToken,
|
||||||
|
|
|
||||||
|
|
@ -1,663 +0,0 @@
|
||||||
import { DepartmentDto, EmployeeDto } from '@/proxy/intranet/models'
|
|
||||||
|
|
||||||
export interface Address {
|
|
||||||
// Adres
|
|
||||||
country: string
|
|
||||||
state: string
|
|
||||||
city: string
|
|
||||||
street: string
|
|
||||||
postalCode: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrCostCenter {
|
|
||||||
// İnsan Kaynakları Masraf Merkezi
|
|
||||||
id: string
|
|
||||||
code: string
|
|
||||||
name: string
|
|
||||||
description?: string
|
|
||||||
parentCostCenterId?: string
|
|
||||||
parentCostCenter?: HrCostCenter
|
|
||||||
subCostCenters: HrCostCenter[]
|
|
||||||
responsibleEmployeeId?: string
|
|
||||||
responsibleEmployee?: EmployeeDto
|
|
||||||
departmentId?: string
|
|
||||||
department?: DepartmentDto
|
|
||||||
costCenterType: CostCenterType
|
|
||||||
budgetedAmount: number
|
|
||||||
actualAmount: number
|
|
||||||
currency: string
|
|
||||||
fiscalYear: string
|
|
||||||
isActive: boolean
|
|
||||||
creationTime: Date
|
|
||||||
lastModificationTime: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrPerformanceEvaluation {
|
|
||||||
// İnsan Kaynakları Performans Değerlendirmesi
|
|
||||||
id: string
|
|
||||||
employeeId: string
|
|
||||||
employee?: EmployeeDto
|
|
||||||
evaluatorId: string
|
|
||||||
evaluator?: EmployeeDto
|
|
||||||
evaluationPeriod: string
|
|
||||||
evaluationType: EvaluationTypeEnum
|
|
||||||
overallRating: number
|
|
||||||
goals: HrPerformanceGoal[]
|
|
||||||
competencies: HrCompetencyRating[]
|
|
||||||
strengths: string[]
|
|
||||||
areasForImprovement: string[]
|
|
||||||
developmentPlan: string[]
|
|
||||||
comments?: string
|
|
||||||
status: EvaluationStatusEnum
|
|
||||||
dueDate: Date
|
|
||||||
completedDate?: Date
|
|
||||||
creationTime: Date
|
|
||||||
lastModificationTime: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrPerformanceGoal {
|
|
||||||
// İnsan Kaynakları Performans Hedefi
|
|
||||||
id: string
|
|
||||||
evaluationId: string
|
|
||||||
goalDescription: string
|
|
||||||
targetValue?: string
|
|
||||||
actualValue?: string
|
|
||||||
weight: number
|
|
||||||
rating: number
|
|
||||||
comments?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrCompetencyRating {
|
|
||||||
// İnsan Kaynakları Yeterlilik Değerlendirmesi
|
|
||||||
id: string
|
|
||||||
evaluationId: string
|
|
||||||
competencyName: string
|
|
||||||
expectedLevel: number
|
|
||||||
actualLevel: number
|
|
||||||
rating: number
|
|
||||||
comments?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrTraining {
|
|
||||||
// İnsan Kaynakları Eğitimi
|
|
||||||
id: string
|
|
||||||
trainingCode: string
|
|
||||||
title: string
|
|
||||||
description?: string
|
|
||||||
trainingType: TrainingTypeEnum
|
|
||||||
provider: string
|
|
||||||
startDate: Date
|
|
||||||
endDate: Date
|
|
||||||
duration: number
|
|
||||||
location?: string
|
|
||||||
isOnline: boolean
|
|
||||||
maxParticipants?: number
|
|
||||||
cost: number
|
|
||||||
currency: string
|
|
||||||
status: TrainingStatusEnum
|
|
||||||
participants: HrTrainingParticipant[]
|
|
||||||
materials: string[]
|
|
||||||
creationTime: Date
|
|
||||||
lastModificationTime: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrTrainingParticipant {
|
|
||||||
// İnsan Kaynakları Eğitim Katılımcısı
|
|
||||||
id: string
|
|
||||||
trainingId: string
|
|
||||||
employeeId: string
|
|
||||||
employee?: EmployeeDto
|
|
||||||
enrollmentDate: Date
|
|
||||||
completionDate?: Date
|
|
||||||
status: ParticipationStatusEnum
|
|
||||||
score?: number
|
|
||||||
feedback?: string
|
|
||||||
certificateIssued: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrWorkSchedule {
|
|
||||||
// İnsan Kaynakları Çalışma Programı
|
|
||||||
id: string
|
|
||||||
scheduleCode: string
|
|
||||||
name: string
|
|
||||||
description?: string
|
|
||||||
workingDays: HrWorkingDay[]
|
|
||||||
totalHoursPerWeek: number
|
|
||||||
isFlexible: boolean
|
|
||||||
isActive: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrWorkingDay {
|
|
||||||
// İnsan Kaynakları Çalışma Günü
|
|
||||||
dayOfWeek: number // 0-6 (Sunday-Saturday)
|
|
||||||
isWorkingDay: boolean
|
|
||||||
startTime?: string
|
|
||||||
endTime?: string
|
|
||||||
breakDuration?: number // minutes
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrDisciplinaryAction {
|
|
||||||
// İnsan Kaynakları Disiplin Cezası
|
|
||||||
id: string
|
|
||||||
employeeId: string
|
|
||||||
employee?: EmployeeDto
|
|
||||||
actionType: DisciplinaryActionTypeEnum
|
|
||||||
reason: string
|
|
||||||
description: string
|
|
||||||
actionDate: Date
|
|
||||||
issuedBy: string
|
|
||||||
severity: DisciplinarySeverityEnum
|
|
||||||
status: DisciplinaryStatusEnum
|
|
||||||
expiryDate?: Date
|
|
||||||
attachments: string[]
|
|
||||||
creationTime: Date
|
|
||||||
lastModificationTime: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrEmergencyContact {
|
|
||||||
// İnsan Kaynakları Acil Durum İletişim
|
|
||||||
name: string
|
|
||||||
relationship: string
|
|
||||||
phoneNumber: string
|
|
||||||
email?: string
|
|
||||||
address?: Address
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrEmploymentType {
|
|
||||||
// İnsan Kaynakları İstihdam Türü
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
count?: number
|
|
||||||
creationTime: Date
|
|
||||||
lastModificationTime: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrPayroll {
|
|
||||||
// İnsan Kaynakları Maaş Bordrosu
|
|
||||||
id: string
|
|
||||||
employeeId: string
|
|
||||||
employee?: EmployeeDto
|
|
||||||
period: string
|
|
||||||
baseSalary: number
|
|
||||||
allowances: HrPayrollAllowance[] // İnsan Kaynakları Maaş Ek Ödemeleri
|
|
||||||
deductions: HrPayrollDeduction[] // İnsan Kaynakları Maaş Kesintileri
|
|
||||||
overtime: number
|
|
||||||
bonus: number
|
|
||||||
grossSalary: number
|
|
||||||
netSalary: number
|
|
||||||
tax: number
|
|
||||||
socialSecurity: number
|
|
||||||
status: PayrollStatusEnum
|
|
||||||
paymentDate?: Date
|
|
||||||
creationTime: Date
|
|
||||||
lastModificationTime: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrPayrollAllowance {
|
|
||||||
// İnsan Kaynakları Maaş Ek Ödemesi
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
amount: number
|
|
||||||
taxable: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrPayrollDeduction {
|
|
||||||
// İnsan Kaynakları Maaş Kesintisi
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
amount: number
|
|
||||||
mandatory: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrBadge {
|
|
||||||
// İnsan Kaynakları Rozeti
|
|
||||||
id: string
|
|
||||||
code: string
|
|
||||||
name: string
|
|
||||||
description: string
|
|
||||||
icon: string
|
|
||||||
color: string
|
|
||||||
backgroundColor: string
|
|
||||||
category: BadgeCategoryEnum
|
|
||||||
criteria: string
|
|
||||||
points: number
|
|
||||||
rarity: BadgeRarityEnum
|
|
||||||
isActive: boolean
|
|
||||||
creationTime: Date
|
|
||||||
lastModificationTime: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrOrganizationChart {
|
|
||||||
// İnsan Kaynakları Organizasyon Şeması
|
|
||||||
id: string
|
|
||||||
employeeId: string
|
|
||||||
employee?: EmployeeDto
|
|
||||||
parentId?: string
|
|
||||||
parent?: HrOrganizationChart
|
|
||||||
children?: HrOrganizationChart[]
|
|
||||||
level: number
|
|
||||||
position: string
|
|
||||||
isActive: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrEmployeeBadge {
|
|
||||||
// İnsan Kaynakları Çalışan Rozeti
|
|
||||||
id: string
|
|
||||||
employeeId: string
|
|
||||||
employee?: EmployeeDto
|
|
||||||
badgeId: string
|
|
||||||
badge?: HrBadge
|
|
||||||
earnedDate: Date
|
|
||||||
expiryDate?: Date
|
|
||||||
reason?: string
|
|
||||||
notes?: string
|
|
||||||
isActive: boolean
|
|
||||||
creationTime: Date
|
|
||||||
lastModificationTime: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrEvaluation360Template {
|
|
||||||
// İnsan Kaynakları 360 Derece Değerlendirme Şablonu
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
description: string
|
|
||||||
isActive: boolean
|
|
||||||
questionGroups: HrQuestionGroup[]
|
|
||||||
applicablePositions: string[] // JobPosition ID'leri
|
|
||||||
applicableDepartments: string[] // Department ID'leri
|
|
||||||
assessorTypes: AssessorTypeEnum[] // Değerlendiriciler
|
|
||||||
creationTime: Date
|
|
||||||
lastModificationTime: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrQuestionGroup {
|
|
||||||
// İnsan Kaynakları Soru Grubu
|
|
||||||
id: string
|
|
||||||
templateId: string
|
|
||||||
groupName: string
|
|
||||||
description?: string
|
|
||||||
weight: number // Bu grubun toplam puandaki ağırlığı (%)
|
|
||||||
order: number
|
|
||||||
questions: HrEvaluationQuestion[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrEvaluationQuestion {
|
|
||||||
// İnsan Kaynakları Değerlendirme Sorusu
|
|
||||||
id: string
|
|
||||||
groupId: string
|
|
||||||
questionText: string
|
|
||||||
questionType: QuestionTypeEnum
|
|
||||||
isRequired: boolean
|
|
||||||
weight: number // Bu sorunun grup içindeki ağırlığı (%)
|
|
||||||
order: number
|
|
||||||
options?: HrQuestionOption[] // Çoktan seçmeli sorular için
|
|
||||||
minRating?: number
|
|
||||||
maxRating?: number
|
|
||||||
ratingLabels?: string[] // Rating için etiketler (örn: ["Zayıf", "Orta", "İyi", "Mükemmel"])
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrQuestionOption {
|
|
||||||
// İnsan Kaynakları Soru Seçeneği
|
|
||||||
id: string
|
|
||||||
questionId: string
|
|
||||||
optionText: string
|
|
||||||
value: number
|
|
||||||
order: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrEvaluation360 {
|
|
||||||
// İnsan Kaynakları 360 Derece Değerlendirme Kampanyası
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
description: string
|
|
||||||
templateId: string
|
|
||||||
template?: HrEvaluation360Template
|
|
||||||
evaluationPeriod: string
|
|
||||||
startDate: Date
|
|
||||||
endDate: Date
|
|
||||||
status: CampaignStatusEnum
|
|
||||||
departmentId?: string // Hedef departman
|
|
||||||
targetEmployees: string[] // Değerlendirilecek Employee ID'leri
|
|
||||||
settings: HrEvaluation360Settings
|
|
||||||
creationTime: Date
|
|
||||||
lastModificationTime: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrEvaluation360Settings {
|
|
||||||
// İnsan Kaynakları 360 Derece Değerlendirme Ayarları
|
|
||||||
allowSelfEvaluation: boolean
|
|
||||||
requireManagerEvaluation: boolean
|
|
||||||
minPeerEvaluations: number
|
|
||||||
minSubordinateEvaluations: number
|
|
||||||
allowAnonymousFeedback: boolean
|
|
||||||
sendReminderEmails: boolean
|
|
||||||
reminderIntervalDays: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrEvaluation360Participant {
|
|
||||||
// İnsan Kaynakları 360 Derece Değerlendirme Katılımcısı
|
|
||||||
id: string
|
|
||||||
campaignId: string
|
|
||||||
evaluatedEmployeeId: string // Değerlendirilen kişi
|
|
||||||
evaluatedEmployee?: EmployeeDto
|
|
||||||
evaluatorId: string // Değerlendiren kişi
|
|
||||||
evaluator?: EmployeeDto
|
|
||||||
evaluatorType: AssessorTypeEnum
|
|
||||||
status: ParticipantStatusEnum
|
|
||||||
invitedDate: Date
|
|
||||||
startedDate?: Date
|
|
||||||
completedDate?: Date
|
|
||||||
responses: HrEvaluation360Response[]
|
|
||||||
overallScore?: number
|
|
||||||
notes?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrEvaluation360Response {
|
|
||||||
// İnsan Kaynakları 360 Derece Değerlendirme Cevabı
|
|
||||||
id: string
|
|
||||||
participantId: string
|
|
||||||
questionId: string
|
|
||||||
question?: HrEvaluationQuestion
|
|
||||||
responseValue: string | number // Cevap değeri
|
|
||||||
responseText?: string // Metin cevaplar için
|
|
||||||
score: number // Hesaplanan puan
|
|
||||||
submittedDate: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrEvaluation360Result {
|
|
||||||
// İnsan Kaynakları 360 Derece Değerlendirme Sonucu
|
|
||||||
id: string
|
|
||||||
campaignId: string
|
|
||||||
employeeId: string
|
|
||||||
employee?: EmployeeDto
|
|
||||||
participants: HrEvaluation360Participant[] // Bu sonuca katkıda bulunan değerlendiriciler
|
|
||||||
overallScore: number
|
|
||||||
maxPossibleScore: number
|
|
||||||
scorePercentage: number
|
|
||||||
groupScores: HrGroupScore[]
|
|
||||||
assessorTypeScores: HrAssessorTypeScore[]
|
|
||||||
strengths: string[]
|
|
||||||
developmentAreas: string[]
|
|
||||||
actionPlan: string[]
|
|
||||||
managerComments?: string
|
|
||||||
hrComments?: string
|
|
||||||
status: ResultStatusEnum
|
|
||||||
generatedDate: Date
|
|
||||||
approvedBy?: string
|
|
||||||
approvedDate?: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrGroupScore {
|
|
||||||
// İnsan Kaynakları Grup Puanı
|
|
||||||
groupId: string
|
|
||||||
groupName: string
|
|
||||||
score: number
|
|
||||||
maxScore: number
|
|
||||||
percentage: number
|
|
||||||
responseCount: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HrAssessorTypeScore {
|
|
||||||
// İnsan Kaynakları Değerlendirici Türü Puanı
|
|
||||||
assessorType: AssessorTypeEnum
|
|
||||||
assessorCount: number
|
|
||||||
averageScore: number
|
|
||||||
maxScore: number
|
|
||||||
percentage: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum PayrollStatusEnum {
|
|
||||||
// Maaş Durumu
|
|
||||||
Draft = 'DRAFT', // Taslak
|
|
||||||
Calculated = 'CALCULATED', // Hesaplandı
|
|
||||||
Approved = 'APPROVED', // Onaylandı
|
|
||||||
Paid = 'PAID', // Ödendi
|
|
||||||
Cancelled = 'CANCELLED', // İptal edildi
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum GoalStatusEnum {
|
|
||||||
// Hedef Durumu
|
|
||||||
NotStarted = 'NOT_STARTED', // Başlanmadı
|
|
||||||
InProgress = 'IN_PROGRESS', // Devam Ediyor
|
|
||||||
Completed = 'COMPLETED', // Tamamlandı
|
|
||||||
Overdue = 'OVERDUE', // Geçmiş
|
|
||||||
Cancelled = 'CANCELLED', // İptal edildi
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum BadgeCategoryEnum {
|
|
||||||
// Rozet Kategorisi
|
|
||||||
Performance = 'PERFORMANCE', // Performans
|
|
||||||
Leadership = 'LEADERSHIP', // Liderlik
|
|
||||||
Innovation = 'INNOVATION', // Yenilik
|
|
||||||
Teamwork = 'TEAMWORK', // Takım Çalışması
|
|
||||||
Customer = 'CUSTOMER', // Müşteri
|
|
||||||
Safety = 'SAFETY', // Güvenlik
|
|
||||||
Attendance = 'ATTENDANCE', // Devamsızlık
|
|
||||||
Training = 'TRAINING', // Eğitim
|
|
||||||
Project = 'PROJECT', // Proje
|
|
||||||
Special = 'SPECIAL', // Özel
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum BadgeRarityEnum {
|
|
||||||
// Rozet Nadirliği
|
|
||||||
Common = 'COMMON', // Orta
|
|
||||||
Uncommon = 'UNCOMMON', // Yaygın olmayan
|
|
||||||
Rare = 'RARE', // Nadir
|
|
||||||
Epic = 'EPIC', // Epik
|
|
||||||
Legendary = 'LEGENDARY', // Efsanevi
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum ResultStatusEnum {
|
|
||||||
// Sonuç Durumu
|
|
||||||
Pending = 'PENDING', // Beklemede
|
|
||||||
InReview = 'IN_REVIEW', // İnceleniyor
|
|
||||||
Approved = 'APPROVED', // Onaylandı
|
|
||||||
Published = 'PUBLISHED', // Yayınlandı
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum GenderEnum {
|
|
||||||
// Cinsiyet
|
|
||||||
Male = 'MALE', // Erkek
|
|
||||||
Female = 'FEMALE', // Kadın
|
|
||||||
Other = 'OTHER', // Diğer
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum MaritalStatusEnum {
|
|
||||||
// Medeni Durum
|
|
||||||
Single = 'SINGLE', // Bekar
|
|
||||||
Married = 'MARRIED', // Evli
|
|
||||||
Divorced = 'DIVORCED', // Boşanmış
|
|
||||||
Widowed = 'WIDOWED', // Dul
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum CostCenterType {
|
|
||||||
// Masraf Merkezi Türü
|
|
||||||
Revenue = 'REVENUE', // Gelir
|
|
||||||
Standard = 'STANDARD', // Standart
|
|
||||||
Discretionary = 'DISCRETIONARY', // İsteğe bağlı
|
|
||||||
Investment = 'INVESTMENT', // Yatırım
|
|
||||||
Service = 'SERVICE', // Hizmet
|
|
||||||
Production = 'PRODUCTION', // Üretim
|
|
||||||
Support = 'SUPPORT', // Destek
|
|
||||||
Administrative = 'ADMINISTRATIVE', // İdari
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum EmploymentTypeEnum {
|
|
||||||
// İstihdam Türü
|
|
||||||
FullTime = 'FULL_TIME', // Tam Zamanlı
|
|
||||||
PartTime = 'PART_TIME', // Yarı Zamanlı
|
|
||||||
Contract = 'CONTRACT', // Sözleşmeli
|
|
||||||
Intern = 'INTERN', // Stajyer
|
|
||||||
Temporary = 'TEMPORARY', // Geçici
|
|
||||||
Consultant = 'CONSULTANT', // Danışman
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum EmployeeStatusEnum {
|
|
||||||
// Çalışan Durumu
|
|
||||||
Active = 'ACTIVE', // Aktif
|
|
||||||
Inactive = 'INACTIVE', // Pasif
|
|
||||||
OnLeave = 'ON_LEAVE', // İzinli
|
|
||||||
Suspended = 'SUSPENDED', // Askıya Alındı
|
|
||||||
Terminated = 'TERMINATED', // İşten Ayrıldı
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum JobLevelEnum {
|
|
||||||
// İş Seviyesi
|
|
||||||
Entry = 'ENTRY', // Giriş
|
|
||||||
Junior = 'JUNIOR', // Junior
|
|
||||||
Mid = 'MID', // Orta
|
|
||||||
Senior = 'SENIOR', // Kıdemli
|
|
||||||
Lead = 'LEAD', // Lider
|
|
||||||
Manager = 'MANAGER', // Yönetici
|
|
||||||
Director = 'DIRECTOR', // Direktör
|
|
||||||
Executive = 'EXECUTIVE', // İcra
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum LeaveTypeEnum {
|
|
||||||
// İzin Türü
|
|
||||||
Annual = 'Annual', // Yıllık
|
|
||||||
Sick = 'Sick', // Hastalık
|
|
||||||
Maternity = 'Maternity', // Doğum
|
|
||||||
Paternity = 'Paternity', // Babalık
|
|
||||||
Personal = 'Personal', // Kişisel
|
|
||||||
Emergency = 'Emergency', // Acil
|
|
||||||
Study = 'Study', // Eğitim
|
|
||||||
Unpaid = 'Unpaid', // Ücretsiz
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum LeaveStatusEnum {
|
|
||||||
// İzin Durumu
|
|
||||||
Pending = 'Pending', // Beklemede
|
|
||||||
Approved = 'Approved', // Onaylandı
|
|
||||||
Rejected = 'Rejected', // Reddedildi
|
|
||||||
Cancelled = 'Cancelled', // İptal edildi
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum EvaluationStatusEnum {
|
|
||||||
// Değerlendirme Durumu
|
|
||||||
NotStarted = 'NOT_STARTED', // Başlanmadı
|
|
||||||
InProgress = 'IN_PROGRESS', // Devam Ediyor
|
|
||||||
PendingReview = 'PENDING_REVIEW', // İnceleme Bekliyor
|
|
||||||
Completed = 'COMPLETED', // Tamamlandı
|
|
||||||
Overdue = 'OVERDUE', // Geçmiş
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum TrainingTypeEnum {
|
|
||||||
// Eğitim Türü
|
|
||||||
Technical = 'TECHNICAL', // Teknik
|
|
||||||
Soft_Skills = 'SOFT_SKILLS', // Yumuşak Beceriler
|
|
||||||
Leadership = 'LEADERSHIP', // Liderlik
|
|
||||||
Compliance = 'COMPLIANCE', // Uyum
|
|
||||||
Safety = 'SAFETY', // Güvenlik
|
|
||||||
Product = 'PRODUCT', // Ürün
|
|
||||||
Process = 'PROCESS', // Süreç
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum TrainingStatusEnum {
|
|
||||||
// Eğitim Durumu
|
|
||||||
Planned = 'PLANNED', // Planlandı
|
|
||||||
Open = 'OPEN', // Açık
|
|
||||||
InProgress = 'IN_PROGRESS', // Devam Ediyor
|
|
||||||
Completed = 'COMPLETED', // Tamamlandı
|
|
||||||
Cancelled = 'CANCELLED', // İptal Edildi
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum ParticipationStatusEnum {
|
|
||||||
// Katılım Durumu
|
|
||||||
Enrolled = 'ENROLLED', // Kayıtlı
|
|
||||||
InProgress = 'IN_PROGRESS', // Devam Ediyor
|
|
||||||
Completed = 'COMPLETED', // Tamamlandı
|
|
||||||
Failed = 'FAILED', // Başarısız
|
|
||||||
Withdrawn = 'WITHDRAWN', // Çekildi
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum DisciplinaryActionTypeEnum {
|
|
||||||
// Disiplin Cezası Türü
|
|
||||||
Verbal_Warning = 'VERBAL_WARNING', // Sözlü Uyarı
|
|
||||||
Written_Warning = 'WRITTEN_WARNING', // Yazılı Uyarı
|
|
||||||
Final_Warning = 'FINAL_WARNING', // Son Uyarı
|
|
||||||
Suspension = 'SUSPENSION', // Askıya Alma
|
|
||||||
Termination = 'TERMINATION', // İşten Çıkarma
|
|
||||||
Demotion = 'DEMOTION', // Aşağı Alma
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum DisciplinarySeverityEnum {
|
|
||||||
// Disiplin Cezası Şiddeti
|
|
||||||
Minor = 'MINOR', // Hafif
|
|
||||||
Major = 'MAJOR', // Ağır
|
|
||||||
Severe = 'SEVERE', // Ciddi
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum DisciplinaryStatusEnum {
|
|
||||||
// Disiplin Cezası Durumu
|
|
||||||
Active = 'ACTIVE', // Aktif
|
|
||||||
Resolved = 'RESOLVED', // Çözüldü
|
|
||||||
Expired = 'EXPIRED', // Süresi Dolmuş
|
|
||||||
Appealed = 'APPEALED', // İtiraz Edilmiş
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum AssessorTypeEnum {
|
|
||||||
// Değerlendirici Türü
|
|
||||||
Self = 'SELF', // Kendi
|
|
||||||
Manager = 'MANAGER', // Yönetici
|
|
||||||
Peer = 'PEER', // Meslektaş
|
|
||||||
Subordinate = 'SUBORDINATE', // Ast
|
|
||||||
Customer = 'CUSTOMER', // Müşteri
|
|
||||||
OtherDepartment = 'OTHER_DEPARTMENT', // Diğer Departman
|
|
||||||
HRUpperManagement = 'HR_UPPER_MANAGEMENT', // İK/Üst Yönetim
|
|
||||||
External = 'EXTERNAL', // Dış paydaş değerlendirmesi (mevcut)
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum EvaluationTypeEnum {
|
|
||||||
// Değerlendirme Türü
|
|
||||||
Annual = 'ANNUAL', // Yıllık
|
|
||||||
Quarterly = 'QUARTERLY', // Çeyrek
|
|
||||||
Probation = 'PROBATION', // Deneme Süresi
|
|
||||||
Project = 'PROJECT', // Proje
|
|
||||||
Competency = 'COMPETENCY', // Yeterlilik
|
|
||||||
Leadership = 'LEADERSHIP', // Liderlik
|
|
||||||
Degree360 = 'DEGREE_360', // 360° Derece değerlendirme
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum CampaignStatusEnum {
|
|
||||||
// Kampanya Durumu
|
|
||||||
Draft = 'DRAFT', // Taslak
|
|
||||||
Active = 'ACTIVE', // Aktif
|
|
||||||
Completed = 'COMPLETED', // Tamamlandı
|
|
||||||
Cancelled = 'CANCELLED', // İptal Edildi
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum ParticipantStatusEnum {
|
|
||||||
// Katılımcı Durumu
|
|
||||||
Invited = 'INVITED', // Davet Edildi
|
|
||||||
Started = 'STARTED', // Başladı
|
|
||||||
Completed = 'COMPLETED', // Tamamlandı
|
|
||||||
Expired = 'EXPIRED', // Süresi Dolmuş
|
|
||||||
Declined = 'DECLINED', // Reddedildi
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum QuestionTypeEnum {
|
|
||||||
// Soru Türü
|
|
||||||
Rating = 'RATING', // 1-5 puan verme
|
|
||||||
MultipleChoice = 'MULTIPLE_CHOICE', // Çoktan seçmeli
|
|
||||||
Text = 'TEXT', // Metin cevap
|
|
||||||
YesNo = 'YES_NO', // Evet/Hayır
|
|
||||||
Scale = 'SCALE', // Ölçek (1-10 gibi)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getQuestionTypeText = (type: QuestionTypeEnum) => {
|
|
||||||
switch (type) {
|
|
||||||
case QuestionTypeEnum.Rating:
|
|
||||||
return 'Puanlama'
|
|
||||||
case QuestionTypeEnum.MultipleChoice:
|
|
||||||
return 'Çoktan Seçmeli'
|
|
||||||
case QuestionTypeEnum.Text:
|
|
||||||
return 'Metin'
|
|
||||||
case QuestionTypeEnum.YesNo:
|
|
||||||
return 'Evet/Hayır'
|
|
||||||
case QuestionTypeEnum.Scale:
|
|
||||||
return 'Ölçek'
|
|
||||||
default:
|
|
||||||
return 'Bilinmeyen'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -11,7 +11,7 @@ function deepParseJson(jsonString: Json): Json {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return deepParseJson(JSON.parse(jsonString))
|
return deepParseJson(JSON.parse(jsonString))
|
||||||
} catch (err) {
|
} catch {
|
||||||
return jsonString
|
return jsonString
|
||||||
}
|
}
|
||||||
} else if (Array.isArray(jsonString)) {
|
} else if (Array.isArray(jsonString)) {
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,8 @@ import { NotificationDto } from '@/proxy/notification/models'
|
||||||
import { getList } from '@/services/notification.service'
|
import { getList } from '@/services/notification.service'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { Dictionary } from 'lodash'
|
|
||||||
import forOwn from 'lodash/forOwn'
|
|
||||||
import groupBy from 'lodash/groupBy'
|
import groupBy from 'lodash/groupBy'
|
||||||
import has from 'lodash/has'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import merge from 'lodash/merge'
|
|
||||||
import { useEffect, useState } from 'react'
|
|
||||||
import Log from './components/Log'
|
import Log from './components/Log'
|
||||||
import LogFilter from './components/LogFilter'
|
import LogFilter from './components/LogFilter'
|
||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
|
|
@ -21,12 +17,13 @@ import { DIR_RTL } from '@/constants/theme.constant'
|
||||||
import { useStoreState } from '@/store'
|
import { useStoreState } from '@/store'
|
||||||
|
|
||||||
const itemsPerPage = 10
|
const itemsPerPage = 10
|
||||||
|
type NotificationGroups = Record<string, NotificationDto[]>
|
||||||
|
|
||||||
const ActivityLog = () => {
|
const ActivityLog = () => {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [notifications, setNotifications] = useState<Dictionary<NotificationDto[]>>({})
|
const [notifications, setNotifications] = useState<NotificationGroups>({})
|
||||||
const [page, setPage] = useState(0)
|
const [page, setPage] = useState(0)
|
||||||
const [hasMore, setHasMore] = useState(false)
|
const [hasMore, setHasMore] = useState(false)
|
||||||
const [isFilterDrawerOpen, setIsFilterDrawerOpen] = useState(false)
|
const [isFilterDrawerOpen, setIsFilterDrawerOpen] = useState(false)
|
||||||
|
|
@ -41,38 +38,43 @@ const ActivityLog = () => {
|
||||||
NotificationChannels.WhatsApp,
|
NotificationChannels.WhatsApp,
|
||||||
])
|
])
|
||||||
|
|
||||||
const fetchData = async (isLoadmore: boolean = false) => {
|
const fetchData = useCallback(async (isLoadmore: boolean = false) => {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
const response = await getList({
|
try {
|
||||||
maxResultCount: itemsPerPage,
|
const response = await getList({
|
||||||
skipCount: page * itemsPerPage,
|
maxResultCount: itemsPerPage,
|
||||||
sorting: 'CreationTime DESC',
|
skipCount: page * itemsPerPage,
|
||||||
channels: filter,
|
sorting: 'CreationTime DESC',
|
||||||
isListRequest: true,
|
channels: filter,
|
||||||
})
|
isListRequest: true,
|
||||||
const items = response.data?.items ?? []
|
|
||||||
|
|
||||||
const currentItemCount = page * itemsPerPage + items.length
|
|
||||||
setHasMore((response.data?.totalCount ?? 0) > currentItemCount)
|
|
||||||
const logs = groupBy(items, (a) => dayjs(a.creationTime).format('YYYY-MM-DD'))
|
|
||||||
|
|
||||||
if (isLoadmore) {
|
|
||||||
forOwn(notifications, function (value, key) {
|
|
||||||
if (has(logs, key)) {
|
|
||||||
notifications[key] = [...notifications[key], ...logs[key]]
|
|
||||||
delete logs[key]
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
setNotifications(merge(notifications, logs))
|
const items = response.data?.items ?? []
|
||||||
} else {
|
|
||||||
setNotifications(logs)
|
const currentItemCount = page * itemsPerPage + items.length
|
||||||
|
setHasMore((response.data?.totalCount ?? 0) > currentItemCount)
|
||||||
|
const logs = groupBy(items, (a) => dayjs(a.creationTime).format('YYYY-MM-DD'))
|
||||||
|
|
||||||
|
if (isLoadmore) {
|
||||||
|
setNotifications((prev) => {
|
||||||
|
const next: NotificationGroups = { ...prev }
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(logs)) {
|
||||||
|
next[key] = [...(next[key] ?? []), ...value]
|
||||||
|
}
|
||||||
|
|
||||||
|
return next
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setNotifications(logs)
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
}
|
}
|
||||||
setLoading(false)
|
}, [filter, page])
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchData(page > 0)
|
fetchData(page > 0)
|
||||||
}, [page, filter])
|
}, [fetchData, page])
|
||||||
|
|
||||||
const handleFilterChange = (value: string[]) => {
|
const handleFilterChange = (value: string[]) => {
|
||||||
setPage(0)
|
setPage(0)
|
||||||
|
|
@ -111,13 +113,13 @@ const ActivityLog = () => {
|
||||||
<Log
|
<Log
|
||||||
notifications={notifications}
|
notifications={notifications}
|
||||||
isLoading={loading}
|
isLoading={loading}
|
||||||
onLoadMore={() => setPage((prev) => prev + 1)}
|
|
||||||
loadable={hasMore}
|
loadable={hasMore}
|
||||||
|
onLoadMore={() => setPage((prev) => prev + 1)}
|
||||||
></Log>
|
></Log>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="hidden lg:block">
|
<div className="hidden lg:block">
|
||||||
<LogFilter filter={filter} onFilterChange={handleFilterChange} useAffix className="dark:bg-gray-800" />
|
<LogFilter useAffix filter={filter} className="dark:bg-gray-800" onFilterChange={handleFilterChange} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -132,9 +134,9 @@ const ActivityLog = () => {
|
||||||
>
|
>
|
||||||
<LogFilter
|
<LogFilter
|
||||||
filter={filter}
|
filter={filter}
|
||||||
onFilterChange={handleFilterChange}
|
|
||||||
useAffix={false}
|
useAffix={false}
|
||||||
className="border-none p-0 dark:bg-gray-800"
|
className="border-none p-0 dark:bg-gray-800"
|
||||||
|
onFilterChange={handleFilterChange}
|
||||||
/>
|
/>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</AdaptableCard>
|
</AdaptableCard>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import { AVATAR_URL } from '@/constants/app.constant'
|
||||||
import { NotificationDto } from '@/proxy/notification/models'
|
import { NotificationDto } from '@/proxy/notification/models'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { Dictionary } from 'lodash'
|
|
||||||
import isEmpty from 'lodash/isEmpty'
|
import isEmpty from 'lodash/isEmpty'
|
||||||
import keys from 'lodash/keys'
|
import keys from 'lodash/keys'
|
||||||
import Event from './Event'
|
import Event from './Event'
|
||||||
|
|
@ -18,7 +17,7 @@ const Log = ({
|
||||||
isLoading,
|
isLoading,
|
||||||
loadable,
|
loadable,
|
||||||
}: {
|
}: {
|
||||||
notifications: Dictionary<NotificationDto[]>
|
notifications: Record<string, NotificationDto[]>
|
||||||
onLoadMore: () => void
|
onLoadMore: () => void
|
||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
loadable: boolean
|
loadable: boolean
|
||||||
|
|
@ -38,7 +37,7 @@ const Log = ({
|
||||||
{isEmpty(notifications[group]) ? (
|
{isEmpty(notifications[group]) ? (
|
||||||
<Timeline.Item className="dark:text-gray-400">Bildirim yok</Timeline.Item>
|
<Timeline.Item className="dark:text-gray-400">Bildirim yok</Timeline.Item>
|
||||||
) : (
|
) : (
|
||||||
notifications[group].map((notification, i) => (
|
notifications[group].map((notification) => (
|
||||||
<Timeline.Item
|
<Timeline.Item
|
||||||
key={notification.id}
|
key={notification.id}
|
||||||
media={
|
media={
|
||||||
|
|
@ -57,7 +56,7 @@ const Log = ({
|
||||||
))}
|
))}
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
{loadable ? (
|
{loadable ? (
|
||||||
<Button size="sm" loading={isLoading} onClick={onLoadMore} variant='solid'>
|
<Button size="sm" loading={isLoading} variant='solid' onClick={onLoadMore}>
|
||||||
{translate('::Abp.Identity.ActivityLogs.LoadMore')}
|
{translate('::Abp.Identity.ActivityLogs.LoadMore')}
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useState, useEffect, useCallback, useRef } from 'react'
|
import { useState, useEffect, useCallback, useRef, type MouseEvent } from 'react'
|
||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
import { Button, Input, Select, toast, Notification, Spinner } from '@/components/ui'
|
import { Button, Input, Select, toast, Notification, Spinner } from '@/components/ui'
|
||||||
import { useStoreState } from '@/store'
|
import { useStoreState } from '@/store'
|
||||||
|
|
@ -251,7 +251,7 @@ const FileManager = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleItemDoubleClick = (item: FileItemType, event?: React.MouseEvent) => {
|
const handleItemDoubleClick = (item: FileItemType, event?: MouseEvent) => {
|
||||||
// Prevent text selection and other default behaviors
|
// Prevent text selection and other default behaviors
|
||||||
if (event) {
|
if (event) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
@ -409,7 +409,7 @@ const FileManager = () => {
|
||||||
if (hasFiles) {
|
if (hasFiles) {
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Security Warning" type="warning">
|
<Notification title="Security Warning" type="warning">
|
||||||
Folder '{item.name}' contains files and cannot be deleted for security reasons.
|
Folder {item.name} contains files and cannot be deleted for security reasons.
|
||||||
</Notification>,
|
</Notification>,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
@ -491,6 +491,8 @@ const FileManager = () => {
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener('keydown', handleKeyDown)
|
document.removeEventListener('keydown', handleKeyDown)
|
||||||
}
|
}
|
||||||
|
// Keyboard shortcuts should bind once per selection/list state snapshot.
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [selectedItems, filteredItems])
|
}, [selectedItems, filteredItems])
|
||||||
|
|
||||||
// Bulk operations
|
// Bulk operations
|
||||||
|
|
@ -710,7 +712,7 @@ const FileManager = () => {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch {
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification title="Error" type="danger">
|
<Notification title="Error" type="danger">
|
||||||
Invalid clipboard data
|
Invalid clipboard data
|
||||||
|
|
@ -738,18 +740,18 @@ const FileManager = () => {
|
||||||
<Button
|
<Button
|
||||||
variant="plain"
|
variant="plain"
|
||||||
icon={<FaArrowUp />}
|
icon={<FaArrowUp />}
|
||||||
onClick={goUpOneLevel}
|
|
||||||
size="sm"
|
size="sm"
|
||||||
disabled={breadcrumbItems.length <= 1}
|
disabled={breadcrumbItems.length <= 1}
|
||||||
className="text-gray-600 hover:text-blue-600 flex-shrink-0"
|
className="text-gray-600 hover:text-blue-600 flex-shrink-0"
|
||||||
title="Go up one level"
|
title="Go up one level"
|
||||||
|
onClick={goUpOneLevel}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
variant="solid"
|
variant="solid"
|
||||||
icon={<FaCloudUploadAlt />}
|
icon={<FaCloudUploadAlt />}
|
||||||
onClick={() => setUploadModalOpen(true)}
|
|
||||||
size="sm"
|
size="sm"
|
||||||
className="flex-shrink-0"
|
className="flex-shrink-0"
|
||||||
|
onClick={() => setUploadModalOpen(true)}
|
||||||
>
|
>
|
||||||
<span className="hidden sm:inline">{translate('::FileManager.UploadFiles')}</span>
|
<span className="hidden sm:inline">{translate('::FileManager.UploadFiles')}</span>
|
||||||
<span className="sm:hidden">{translate('::FileManager.Upload')}</span>
|
<span className="sm:hidden">{translate('::FileManager.Upload')}</span>
|
||||||
|
|
@ -757,9 +759,9 @@ const FileManager = () => {
|
||||||
<Button
|
<Button
|
||||||
variant="default"
|
variant="default"
|
||||||
icon={<FaFolder />}
|
icon={<FaFolder />}
|
||||||
onClick={() => setCreateFolderModalOpen(true)}
|
|
||||||
size="sm"
|
size="sm"
|
||||||
className="flex-shrink-0"
|
className="flex-shrink-0"
|
||||||
|
onClick={() => setCreateFolderModalOpen(true)}
|
||||||
>
|
>
|
||||||
<span className="hidden sm:inline">{translate('::FileManager.CreateFolder')}</span>
|
<span className="hidden sm:inline">{translate('::FileManager.CreateFolder')}</span>
|
||||||
<span className="sm:hidden">{translate('::FileManager.Create')}</span>
|
<span className="sm:hidden">{translate('::FileManager.Create')}</span>
|
||||||
|
|
@ -769,33 +771,37 @@ const FileManager = () => {
|
||||||
<Button
|
<Button
|
||||||
variant="plain"
|
variant="plain"
|
||||||
icon={<FaCopy />}
|
icon={<FaCopy />}
|
||||||
onClick={copySelectedItems}
|
|
||||||
disabled={selectedItems.length === 0}
|
disabled={selectedItems.length === 0}
|
||||||
size="sm"
|
size="sm"
|
||||||
className="text-gray-600 hover:text-blue-600 disabled:opacity-50 flex-shrink-0"
|
className="text-gray-600 hover:text-blue-600 disabled:opacity-50 flex-shrink-0"
|
||||||
title={translate('::FileManager.CopySelectedItems')}
|
title={translate('::FileManager.CopySelectedItems')}
|
||||||
|
onClick={copySelectedItems}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
variant="plain"
|
variant="plain"
|
||||||
icon={<FaCut />}
|
icon={<FaCut />}
|
||||||
onClick={cutSelectedItems}
|
|
||||||
disabled={selectedItems.length === 0}
|
disabled={selectedItems.length === 0}
|
||||||
size="sm"
|
size="sm"
|
||||||
className="text-gray-600 hover:text-orange-600 disabled:opacity-50 flex-shrink-0"
|
className="text-gray-600 hover:text-orange-600 disabled:opacity-50 flex-shrink-0"
|
||||||
title={translate('::FileManager.CutSelectedItems')}
|
title={translate('::FileManager.CutSelectedItems')}
|
||||||
|
onClick={cutSelectedItems}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
variant="plain"
|
variant="plain"
|
||||||
icon={<FaPaste />}
|
icon={<FaPaste />}
|
||||||
onClick={pasteItems}
|
|
||||||
disabled={!hasClipboardData}
|
disabled={!hasClipboardData}
|
||||||
size="sm"
|
size="sm"
|
||||||
className="text-gray-600 hover:text-green-600 disabled:opacity-50 flex-shrink-0"
|
className="text-gray-600 hover:text-green-600 disabled:opacity-50 flex-shrink-0"
|
||||||
title={translate('::FileManager.PasteSelectedItems')}
|
title={translate('::FileManager.PasteSelectedItems')}
|
||||||
|
onClick={pasteItems}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
variant="plain"
|
variant="plain"
|
||||||
icon={<FaEdit />}
|
icon={<FaEdit />}
|
||||||
|
size="sm"
|
||||||
|
disabled={selectedItems.length !== 1}
|
||||||
|
className="text-gray-600 hover:text-blue-600 flex-shrink-0"
|
||||||
|
title={translate('::FileManager.RenameSelectedItem')}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (selectedItems.length === 1) {
|
if (selectedItems.length === 1) {
|
||||||
const itemToRename = filteredItems.find((item) => item.id === selectedItems[0])
|
const itemToRename = filteredItems.find((item) => item.id === selectedItems[0])
|
||||||
|
|
@ -810,15 +816,21 @@ const FileManager = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
size="sm"
|
|
||||||
disabled={selectedItems.length !== 1}
|
|
||||||
className="text-gray-600 hover:text-blue-600 flex-shrink-0"
|
|
||||||
title={translate('::FileManager.RenameSelectedItem')}
|
|
||||||
></Button>
|
></Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="plain"
|
variant="plain"
|
||||||
icon={<FaDownload />}
|
icon={<FaDownload />}
|
||||||
|
size="sm"
|
||||||
|
disabled={
|
||||||
|
selectedItems.length !== 1 ||
|
||||||
|
(() => {
|
||||||
|
const selectedItem = filteredItems.find((item) => item.id === selectedItems[0])
|
||||||
|
return selectedItem?.type !== 'file'
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
className="text-gray-600 hover:text-green-600 flex-shrink-0"
|
||||||
|
title={translate('::FileManager.DownloadSelectedFile')}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (selectedItems.length === 1) {
|
if (selectedItems.length === 1) {
|
||||||
const itemToDownload = filteredItems.find((item) => item.id === selectedItems[0])
|
const itemToDownload = filteredItems.find((item) => item.id === selectedItems[0])
|
||||||
|
|
@ -833,26 +845,16 @@ const FileManager = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
size="sm"
|
|
||||||
disabled={
|
|
||||||
selectedItems.length !== 1 ||
|
|
||||||
(() => {
|
|
||||||
const selectedItem = filteredItems.find((item) => item.id === selectedItems[0])
|
|
||||||
return selectedItem?.type !== 'file'
|
|
||||||
})()
|
|
||||||
}
|
|
||||||
className="text-gray-600 hover:text-green-600 flex-shrink-0"
|
|
||||||
title={translate('::FileManager.DownloadSelectedFile')}
|
|
||||||
></Button>
|
></Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="plain"
|
variant="plain"
|
||||||
icon={<FaTrash />}
|
icon={<FaTrash />}
|
||||||
onClick={deleteSelectedItems}
|
|
||||||
size="sm"
|
size="sm"
|
||||||
disabled={selectedItems.length === 0}
|
disabled={selectedItems.length === 0}
|
||||||
className="text-gray-600 hover:text-red-600 flex-shrink-0"
|
className="text-gray-600 hover:text-red-600 flex-shrink-0"
|
||||||
title={translate('::FileManager.DeleteSelectedItems')}
|
title={translate('::FileManager.DeleteSelectedItems')}
|
||||||
|
onClick={deleteSelectedItems}
|
||||||
>
|
>
|
||||||
<span>{translate('::Delete')}</span> {selectedItems.length > 0 && `(${selectedItems.length})`}
|
<span>{translate('::Delete')}</span> {selectedItems.length > 0 && `(${selectedItems.length})`}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -869,11 +871,6 @@ const FileManager = () => {
|
||||||
<FaSquare />
|
<FaSquare />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
onClick={
|
|
||||||
selectedItems.length === filteredItems.filter((item) => !item.isReadOnly).length
|
|
||||||
? deselectAllItems
|
|
||||||
: selectAllItems
|
|
||||||
}
|
|
||||||
size="sm"
|
size="sm"
|
||||||
className="text-gray-600 hover:text-blue-600 flex-shrink-0"
|
className="text-gray-600 hover:text-blue-600 flex-shrink-0"
|
||||||
title={
|
title={
|
||||||
|
|
@ -881,6 +878,11 @@ const FileManager = () => {
|
||||||
? 'Deselect all selectable items'
|
? 'Deselect all selectable items'
|
||||||
: 'Select all selectable items'
|
: 'Select all selectable items'
|
||||||
}
|
}
|
||||||
|
onClick={
|
||||||
|
selectedItems.length === filteredItems.filter((item) => !item.isReadOnly).length
|
||||||
|
? deselectAllItems
|
||||||
|
: selectAllItems
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<span className="hidden lg:inline">
|
<span className="hidden lg:inline">
|
||||||
{selectedItems.length === filteredItems.filter((item) => !item.isReadOnly).length
|
{selectedItems.length === filteredItems.filter((item) => !item.isReadOnly).length
|
||||||
|
|
@ -904,9 +906,9 @@ const FileManager = () => {
|
||||||
size="sm"
|
size="sm"
|
||||||
placeholder={translate('::FileManager.SearchFiles')}
|
placeholder={translate('::FileManager.SearchFiles')}
|
||||||
value={filters.searchTerm}
|
value={filters.searchTerm}
|
||||||
onChange={(e) => setFilters((prev) => ({ ...prev, searchTerm: e.target.value }))}
|
|
||||||
prefix={<FaSearch className="text-gray-400" />}
|
prefix={<FaSearch className="text-gray-400" />}
|
||||||
className="w-full sm:w-36 md:w-48"
|
className="w-full sm:w-36 md:w-48"
|
||||||
|
onChange={(e) => setFilters((prev) => ({ ...prev, searchTerm: e.target.value }))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -954,15 +956,15 @@ const FileManager = () => {
|
||||||
size="sm"
|
size="sm"
|
||||||
icon={<FaTh />}
|
icon={<FaTh />}
|
||||||
variant={viewMode === 'grid' ? 'solid' : 'default'}
|
variant={viewMode === 'grid' ? 'solid' : 'default'}
|
||||||
onClick={() => setViewMode('grid')}
|
|
||||||
title="Grid view"
|
title="Grid view"
|
||||||
|
onClick={() => setViewMode('grid')}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
icon={<FaList />}
|
icon={<FaList />}
|
||||||
variant={viewMode === 'list' ? 'solid' : 'default'}
|
variant={viewMode === 'list' ? 'solid' : 'default'}
|
||||||
onClick={() => setViewMode('list')}
|
|
||||||
title="List view"
|
title="List view"
|
||||||
|
onClick={() => setViewMode('list')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1131,40 +1133,40 @@ const FileManager = () => {
|
||||||
{/* Modals */}
|
{/* Modals */}
|
||||||
<FileUploadModal
|
<FileUploadModal
|
||||||
isOpen={uploadModalOpen}
|
isOpen={uploadModalOpen}
|
||||||
onClose={() => setUploadModalOpen(false)}
|
|
||||||
onUpload={handleUploadFiles}
|
|
||||||
currentFolderId={currentFolderId}
|
currentFolderId={currentFolderId}
|
||||||
loading={uploading}
|
loading={uploading}
|
||||||
|
onClose={() => setUploadModalOpen(false)}
|
||||||
|
onUpload={handleUploadFiles}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<CreateFolderModal
|
<CreateFolderModal
|
||||||
isOpen={createFolderModalOpen}
|
isOpen={createFolderModalOpen}
|
||||||
onClose={() => setCreateFolderModalOpen(false)}
|
|
||||||
onCreate={handleCreateFolder}
|
|
||||||
loading={creating}
|
loading={creating}
|
||||||
currentFolderId={currentFolderId}
|
currentFolderId={currentFolderId}
|
||||||
|
onClose={() => setCreateFolderModalOpen(false)}
|
||||||
|
onCreate={handleCreateFolder}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<RenameItemModal
|
<RenameItemModal
|
||||||
isOpen={renameModalOpen}
|
isOpen={renameModalOpen}
|
||||||
|
item={itemToRename}
|
||||||
|
loading={renaming}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setRenameModalOpen(false)
|
setRenameModalOpen(false)
|
||||||
setItemToRename(undefined)
|
setItemToRename(undefined)
|
||||||
}}
|
}}
|
||||||
onRename={handleRenameItem}
|
onRename={handleRenameItem}
|
||||||
item={itemToRename}
|
|
||||||
loading={renaming}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<DeleteConfirmModal
|
<DeleteConfirmModal
|
||||||
isOpen={deleteModalOpen}
|
isOpen={deleteModalOpen}
|
||||||
|
items={itemsToDelete}
|
||||||
|
loading={deleting}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setDeleteModalOpen(false)
|
setDeleteModalOpen(false)
|
||||||
setItemsToDelete([])
|
setItemsToDelete([])
|
||||||
}}
|
}}
|
||||||
onDelete={handleDeleteItems}
|
onDelete={handleDeleteItems}
|
||||||
items={itemsToDelete}
|
|
||||||
loading={deleting}
|
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ const Breadcrumb = forwardRef<HTMLDivElement, BreadcrumbProps>((props, ref) => {
|
||||||
<FaFolder className="h-4 w-4 mr-1" />
|
<FaFolder className="h-4 w-4 mr-1" />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
onClick={() => onNavigate(item)}
|
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'flex items-center px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors',
|
'flex items-center px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors',
|
||||||
index === items.length - 1
|
index === items.length - 1
|
||||||
|
|
@ -35,6 +34,7 @@ const Breadcrumb = forwardRef<HTMLDivElement, BreadcrumbProps>((props, ref) => {
|
||||||
: 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100',
|
: 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100',
|
||||||
)}
|
)}
|
||||||
disabled={index === items.length - 1}
|
disabled={index === items.length - 1}
|
||||||
|
onClick={() => onNavigate(item)}
|
||||||
>
|
>
|
||||||
<span className="truncate max-w-32">{item.name}</span>
|
<span className="truncate max-w-32">{item.name}</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { forwardRef, useState, useEffect } from 'react'
|
import { forwardRef, useState, useEffect, type ChangeEvent, type MouseEvent } from 'react'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import {
|
import {
|
||||||
FaFolder,
|
FaFolder,
|
||||||
|
|
@ -16,7 +16,6 @@ import {
|
||||||
FaLink,
|
FaLink,
|
||||||
} from 'react-icons/fa'
|
} from 'react-icons/fa'
|
||||||
import { toast, Notification } from '@/components/ui'
|
import { toast, Notification } from '@/components/ui'
|
||||||
// import { Dropdown } from '@/components/ui' // Artık kullanmıyoruz
|
|
||||||
import type { FileItem as FileItemType, FileActionMenuItem } from '@/types/fileManagement'
|
import type { FileItem as FileItemType, FileActionMenuItem } from '@/types/fileManagement'
|
||||||
import { FILE_URL } from '@/constants/app.constant'
|
import { FILE_URL } from '@/constants/app.constant'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
|
@ -26,7 +25,7 @@ export interface FileItemProps {
|
||||||
selected?: boolean
|
selected?: boolean
|
||||||
viewMode?: 'grid' | 'list'
|
viewMode?: 'grid' | 'list'
|
||||||
onSelect?: (item: FileItemType) => void
|
onSelect?: (item: FileItemType) => void
|
||||||
onDoubleClick?: (item: FileItemType, event?: React.MouseEvent) => void
|
onDoubleClick?: (item: FileItemType, event?: MouseEvent) => void
|
||||||
onCreateFolder?: (parentItem: FileItemType) => void
|
onCreateFolder?: (parentItem: FileItemType) => void
|
||||||
onRename?: (item: FileItemType) => void
|
onRename?: (item: FileItemType) => void
|
||||||
onMove?: (item: FileItemType) => void
|
onMove?: (item: FileItemType) => void
|
||||||
|
|
@ -141,11 +140,11 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
onSelect?.(item)
|
onSelect?.(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDoubleClick = (e: React.MouseEvent) => {
|
const handleDoubleClick = (e: MouseEvent) => {
|
||||||
onDoubleClick?.(item, e)
|
onDoubleClick?.(item, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleContextMenu = (e: React.MouseEvent) => {
|
const handleContextMenu = (e: MouseEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
|
||||||
|
|
@ -171,12 +170,12 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
}
|
}
|
||||||
}, [dropdownOpen])
|
}, [dropdownOpen])
|
||||||
|
|
||||||
const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleCheckboxChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
e.stopPropagation() // Prevent item selection when clicking checkbox
|
e.stopPropagation() // Prevent item selection when clicking checkbox
|
||||||
onToggleSelect?.(item)
|
onToggleSelect?.(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCheckboxClick = (e: React.MouseEvent) => {
|
const handleCheckboxClick = (e: MouseEvent) => {
|
||||||
e.stopPropagation() // Prevent item selection when clicking checkbox
|
e.stopPropagation() // Prevent item selection when clicking checkbox
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,7 +215,7 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
() => {
|
() => {
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification type="success" title="Başarılı">
|
<Notification type="success" title="Başarılı">
|
||||||
Dosya URL'si panoya kopyalandı
|
Dosya URL'si panoya kopyalandı
|
||||||
</Notification>,
|
</Notification>,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -367,9 +366,9 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={selected}
|
checked={selected}
|
||||||
|
className="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||||
onChange={handleCheckboxChange}
|
onChange={handleCheckboxChange}
|
||||||
onClick={handleCheckboxClick}
|
onClick={handleCheckboxClick}
|
||||||
className="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div className="w-4 h-4" /> // Boş alan bırak
|
<div className="w-4 h-4" /> // Boş alan bırak
|
||||||
|
|
@ -464,9 +463,9 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={selected}
|
checked={selected}
|
||||||
|
className="w-4 h-4 text-blue-600 bg-white border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600 shadow-sm"
|
||||||
onChange={handleCheckboxChange}
|
onChange={handleCheckboxChange}
|
||||||
onClick={handleCheckboxClick}
|
onClick={handleCheckboxClick}
|
||||||
className="w-4 h-4 text-blue-600 bg-white border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600 shadow-sm"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { forwardRef, useState, useEffect } from 'react'
|
import { forwardRef, useState, useEffect, type FormEvent } from 'react'
|
||||||
import { Dialog, Button, Input, FormItem } from '@/components/ui'
|
import { Dialog, Button, Input, FormItem } from '@/components/ui'
|
||||||
import { FaTimes } from 'react-icons/fa'
|
|
||||||
import type { FileItem } from '@/types/fileManagement'
|
import type { FileItem } from '@/types/fileManagement'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
|
||||||
|
|
@ -20,7 +19,7 @@ export const CreateFolderModal = forwardRef<HTMLDivElement, CreateFolderModalPro
|
||||||
const [error, setError] = useState('')
|
const [error, setError] = useState('')
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
||||||
const handleSubmit = async (e: React.FormEvent) => {
|
const handleSubmit = async (e: FormEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
if (!folderName.trim()) {
|
if (!folderName.trim()) {
|
||||||
|
|
@ -33,7 +32,7 @@ export const CreateFolderModal = forwardRef<HTMLDivElement, CreateFolderModalPro
|
||||||
setFolderName('')
|
setFolderName('')
|
||||||
setError('')
|
setError('')
|
||||||
onClose()
|
onClose()
|
||||||
} catch (err) {
|
} catch {
|
||||||
setError('Failed to create folder')
|
setError('Failed to create folder')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -47,27 +46,27 @@ export const CreateFolderModal = forwardRef<HTMLDivElement, CreateFolderModalPro
|
||||||
return (
|
return (
|
||||||
<Dialog isOpen={isOpen} onClose={handleClose}>
|
<Dialog isOpen={isOpen} onClose={handleClose}>
|
||||||
<div ref={ref}>
|
<div ref={ref}>
|
||||||
<form onSubmit={handleSubmit} className="py-6">
|
<form className="py-6" onSubmit={handleSubmit}>
|
||||||
<FormItem label={translate('::FileManager.FolderName')} invalid={!!error} errorMessage={error}>
|
<FormItem label={translate('::FileManager.FolderName')} invalid={!!error} errorMessage={error}>
|
||||||
<Input
|
<Input
|
||||||
value={folderName}
|
|
||||||
onChange={(e) => setFolderName(e.target.value)}
|
|
||||||
autoFocus
|
autoFocus
|
||||||
|
value={folderName}
|
||||||
className="mt-2"
|
className="mt-2"
|
||||||
|
onChange={(e) => setFolderName(e.target.value)}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div className="flex justify-end space-x-2 pt-4 border-t">
|
<div className="flex justify-end space-x-2 pt-4 border-t">
|
||||||
<Button size='sm' variant="default" onClick={handleClose} disabled={loading}>
|
<Button size='sm' variant="default" disabled={loading} onClick={handleClose}>
|
||||||
{translate('::Cancel')}
|
{translate('::Cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size='sm'
|
size='sm'
|
||||||
variant="solid"
|
variant="solid"
|
||||||
onClick={handleSubmit}
|
|
||||||
loading={loading}
|
loading={loading}
|
||||||
disabled={!folderName.trim()}
|
disabled={!folderName.trim()}
|
||||||
|
onClick={handleSubmit}
|
||||||
>
|
>
|
||||||
{translate('::FileManager.CreateFolder')}
|
{translate('::FileManager.CreateFolder')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -102,7 +101,7 @@ export const RenameItemModal = forwardRef<HTMLDivElement, RenameItemModalProps>(
|
||||||
}
|
}
|
||||||
}, [item])
|
}, [item])
|
||||||
|
|
||||||
const handleSubmit = async (e: React.FormEvent) => {
|
const handleSubmit = async (e: FormEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
if (!newName.trim()) {
|
if (!newName.trim()) {
|
||||||
|
|
@ -119,7 +118,7 @@ export const RenameItemModal = forwardRef<HTMLDivElement, RenameItemModalProps>(
|
||||||
await onRename(newName.trim())
|
await onRename(newName.trim())
|
||||||
setError('')
|
setError('')
|
||||||
onClose()
|
onClose()
|
||||||
} catch (err) {
|
} catch {
|
||||||
setError(`Failed to rename ${item?.type}`)
|
setError(`Failed to rename ${item?.type}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -141,31 +140,31 @@ export const RenameItemModal = forwardRef<HTMLDivElement, RenameItemModalProps>(
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form onSubmit={handleSubmit} className="py-6">
|
<form className="py-6" onSubmit={handleSubmit}>
|
||||||
<FormItem
|
<FormItem
|
||||||
label={translate(`::FileManager.${item.type === 'folder' ? 'FolderName' : 'FileName'}`)}
|
label={translate(`::FileManager.${item.type === 'folder' ? 'FolderName' : 'FileName'}`)}
|
||||||
invalid={!!error}
|
invalid={!!error}
|
||||||
errorMessage={error}
|
errorMessage={error}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
value={newName}
|
|
||||||
onChange={(e) => setNewName(e.target.value)}
|
|
||||||
placeholder={`Enter ${translate(`::FileManager.${item.type === 'folder' ? 'FolderName' : 'FileName'}`)}`}
|
|
||||||
autoFocus
|
autoFocus
|
||||||
|
value={newName}
|
||||||
|
placeholder={`Enter ${translate(`::FileManager.${item.type === 'folder' ? 'FolderName' : 'FileName'}`)}`}
|
||||||
|
onChange={(e) => setNewName(e.target.value)}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div className="flex justify-end space-x-2 pt-4 border-t">
|
<div className="flex justify-end space-x-2 pt-4 border-t">
|
||||||
<Button size='sm' variant="default" onClick={handleClose} disabled={loading}>
|
<Button size='sm' variant="default" disabled={loading} onClick={handleClose}>
|
||||||
{translate('::Cancel')}
|
{translate('::Cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size='sm'
|
size='sm'
|
||||||
variant="solid"
|
variant="solid"
|
||||||
onClick={handleSubmit}
|
|
||||||
loading={loading}
|
loading={loading}
|
||||||
disabled={!newName.trim()}
|
disabled={!newName.trim()}
|
||||||
|
onClick={handleSubmit}
|
||||||
>
|
>
|
||||||
{translate('::App.Listform.ListformField.Rename')}
|
{translate('::App.Listform.ListformField.Rename')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -195,7 +194,7 @@ export const DeleteConfirmModal = forwardRef<HTMLDivElement, DeleteConfirmModalP
|
||||||
try {
|
try {
|
||||||
await onDelete()
|
await onDelete()
|
||||||
onClose()
|
onClose()
|
||||||
} catch (err) {
|
} catch {
|
||||||
// Error handling is done in parent component
|
// Error handling is done in parent component
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -240,14 +239,14 @@ export const DeleteConfirmModal = forwardRef<HTMLDivElement, DeleteConfirmModalP
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-end space-x-2 pt-4 border-t">
|
<div className="flex justify-end space-x-2 pt-4 border-t">
|
||||||
<Button size='sm' variant="default" onClick={onClose} disabled={loading}>
|
<Button size='sm' variant="default" disabled={loading} onClick={onClose}>
|
||||||
{translate('::Cancel')}
|
{translate('::Cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size='sm'
|
size='sm'
|
||||||
variant="solid"
|
variant="solid"
|
||||||
onClick={handleDelete}
|
|
||||||
loading={loading}
|
loading={loading}
|
||||||
|
onClick={handleDelete}
|
||||||
>
|
>
|
||||||
{translate('::Delete')}
|
{translate('::Delete')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,11 @@
|
||||||
import { forwardRef, useState, useCallback, useRef } from 'react'
|
import {
|
||||||
|
forwardRef,
|
||||||
|
useState,
|
||||||
|
useCallback,
|
||||||
|
useRef,
|
||||||
|
type ChangeEvent,
|
||||||
|
type DragEvent,
|
||||||
|
} from 'react'
|
||||||
import { Dialog, Button, Progress } from '@/components/ui'
|
import { Dialog, Button, Progress } from '@/components/ui'
|
||||||
import { FaCloudUploadAlt, FaTimes } from 'react-icons/fa'
|
import { FaCloudUploadAlt, FaTimes } from 'react-icons/fa'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
|
@ -22,7 +29,7 @@ interface UploadFileWithProgress {
|
||||||
}
|
}
|
||||||
|
|
||||||
const FileUploadModal = forwardRef<HTMLDivElement, FileUploadModalProps>((props, ref) => {
|
const FileUploadModal = forwardRef<HTMLDivElement, FileUploadModalProps>((props, ref) => {
|
||||||
const { isOpen, onClose, onUpload, currentFolderId, loading = false, className } = props
|
const { isOpen, onClose, onUpload, className } = props
|
||||||
|
|
||||||
const [uploadFiles, setUploadFiles] = useState<UploadFileWithProgress[]>([])
|
const [uploadFiles, setUploadFiles] = useState<UploadFileWithProgress[]>([])
|
||||||
const [isDragOver, setIsDragOver] = useState(false)
|
const [isDragOver, setIsDragOver] = useState(false)
|
||||||
|
|
@ -53,24 +60,24 @@ const FileUploadModal = forwardRef<HTMLDivElement, FileUploadModalProps>((props,
|
||||||
setUploadFiles((prev) => [...prev, ...newFiles])
|
setUploadFiles((prev) => [...prev, ...newFiles])
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const handleFileInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleFileInputChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
if (e.target.files) {
|
if (e.target.files) {
|
||||||
handleFilesSelect(e.target.files)
|
handleFilesSelect(e.target.files)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDragOver = useCallback((e: React.DragEvent) => {
|
const handleDragOver = useCallback((e: DragEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
setIsDragOver(true)
|
setIsDragOver(true)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const handleDragLeave = useCallback((e: React.DragEvent) => {
|
const handleDragLeave = useCallback((e: DragEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
setIsDragOver(false)
|
setIsDragOver(false)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const handleDrop = useCallback(
|
const handleDrop = useCallback(
|
||||||
(e: React.DragEvent) => {
|
(e: DragEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
setIsDragOver(false)
|
setIsDragOver(false)
|
||||||
|
|
||||||
|
|
@ -216,10 +223,6 @@ const FileUploadModal = forwardRef<HTMLDivElement, FileUploadModalProps>((props,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const clearCompletedFiles = () => {
|
|
||||||
setUploadFiles((prev) => prev.filter((f) => f.status !== 'completed'))
|
|
||||||
}
|
|
||||||
|
|
||||||
const clearErrorFiles = () => {
|
const clearErrorFiles = () => {
|
||||||
setUploadFiles((prev) => prev.filter((f) => f.status !== 'error'))
|
setUploadFiles((prev) => prev.filter((f) => f.status !== 'error'))
|
||||||
}
|
}
|
||||||
|
|
@ -231,7 +234,7 @@ const FileUploadModal = forwardRef<HTMLDivElement, FileUploadModalProps>((props,
|
||||||
const hasError = errorFiles > 0
|
const hasError = errorFiles > 0
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog isOpen={isOpen} onClose={handleClose} className={className}>
|
<Dialog isOpen={isOpen} className={className} onClose={handleClose}>
|
||||||
<div ref={ref}>
|
<div ref={ref}>
|
||||||
<div className="flex items-center justify-between pb-2 border-b">
|
<div className="flex items-center justify-between pb-2 border-b">
|
||||||
<h3 className="text-lg font-semibold">Upload Files</h3>
|
<h3 className="text-lg font-semibold">Upload Files</h3>
|
||||||
|
|
@ -251,11 +254,11 @@ const FileUploadModal = forwardRef<HTMLDivElement, FileUploadModalProps>((props,
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
ref={fileInputRef}
|
ref={fileInputRef}
|
||||||
type="file"
|
|
||||||
multiple
|
multiple
|
||||||
|
type="file"
|
||||||
className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
|
className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
|
||||||
onChange={handleFileInputChange}
|
|
||||||
disabled={uploading}
|
disabled={uploading}
|
||||||
|
onChange={handleFileInputChange}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FaCloudUploadAlt className="mx-auto h-12 w-12 text-gray-400 mb-4" />
|
<FaCloudUploadAlt className="mx-auto h-12 w-12 text-gray-400 mb-4" />
|
||||||
|
|
@ -318,9 +321,9 @@ const FileUploadModal = forwardRef<HTMLDivElement, FileUploadModalProps>((props,
|
||||||
variant="plain"
|
variant="plain"
|
||||||
size="sm"
|
size="sm"
|
||||||
icon={<FaTimes />}
|
icon={<FaTimes />}
|
||||||
onClick={() => removeFile(file.id)}
|
|
||||||
disabled={uploading}
|
disabled={uploading}
|
||||||
className="ml-2 flex-shrink-0"
|
className="ml-2 flex-shrink-0"
|
||||||
|
onClick={() => removeFile(file.id)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -349,21 +352,21 @@ const FileUploadModal = forwardRef<HTMLDivElement, FileUploadModalProps>((props,
|
||||||
{hasError && !uploading && (
|
{hasError && !uploading && (
|
||||||
<Button
|
<Button
|
||||||
variant="plain"
|
variant="plain"
|
||||||
onClick={clearErrorFiles}
|
|
||||||
className="text-red-600 hover:text-red-700"
|
className="text-red-600 hover:text-red-700"
|
||||||
|
onClick={clearErrorFiles}
|
||||||
>
|
>
|
||||||
Clear Errors
|
Clear Errors
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<Button size="sm" variant="default" onClick={handleClose} disabled={uploading}>
|
<Button size="sm" variant="default" disabled={uploading} onClick={handleClose}>
|
||||||
{uploading ? 'Uploading...' : 'Close'}
|
{uploading ? 'Uploading...' : 'Close'}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
onClick={handleUpload}
|
|
||||||
disabled={pendingFiles === 0 || uploading}
|
disabled={pendingFiles === 0 || uploading}
|
||||||
loading={uploading}
|
loading={uploading}
|
||||||
|
onClick={handleUpload}
|
||||||
>
|
>
|
||||||
{uploading ? 'Uploading...' : `Upload ${pendingFiles} File(s)`}
|
{uploading ? 'Uploading...' : `Upload ${pendingFiles} File(s)`}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,15 @@
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import {
|
||||||
|
type Dispatch,
|
||||||
|
type MutableRefObject,
|
||||||
|
type SetStateAction,
|
||||||
|
type WheelEvent,
|
||||||
|
type MouseEvent as ReactMouseEvent,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from 'react'
|
||||||
import {
|
import {
|
||||||
FaSitemap,
|
FaSitemap,
|
||||||
FaBriefcase,
|
FaBriefcase,
|
||||||
|
|
@ -19,11 +30,10 @@ import {
|
||||||
OrgChartUserDto,
|
OrgChartUserDto,
|
||||||
} from '@/services/orgChart.service'
|
} from '@/services/orgChart.service'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { APP_NAME } from '@/constants/app.constant'
|
import { AVATAR_URL, APP_NAME } from '@/constants/app.constant'
|
||||||
import Loading from '@/components/shared/Loading'
|
import Loading from '@/components/shared/Loading'
|
||||||
import { useCurrentMenuIcon } from '@/utils/hooks/useCurrentMenuIcon'
|
import { useCurrentMenuIcon } from '@/utils/hooks/useCurrentMenuIcon'
|
||||||
import { Avatar, Button } from '@/components/ui'
|
import { Avatar, Button } from '@/components/ui'
|
||||||
import { AVATAR_URL } from '@/constants/app.constant'
|
|
||||||
import { useStoreState } from '@/store'
|
import { useStoreState } from '@/store'
|
||||||
import UserProfileCard from '@/views/intranet/SocialWall/UserProfileCard'
|
import UserProfileCard from '@/views/intranet/SocialWall/UserProfileCard'
|
||||||
|
|
||||||
|
|
@ -436,9 +446,9 @@ function OrgChartNode({
|
||||||
tenantId?: string
|
tenantId?: string
|
||||||
zoom: number
|
zoom: number
|
||||||
positions: PositionMap
|
positions: PositionMap
|
||||||
setPositions: React.Dispatch<React.SetStateAction<PositionMap>>
|
setPositions: Dispatch<SetStateAction<PositionMap>>
|
||||||
nodeRefs: React.MutableRefObject<NodeRefMap>
|
nodeRefs: MutableRefObject<NodeRefMap>
|
||||||
cardRefs: React.MutableRefObject<CardRefMap>
|
cardRefs: MutableRefObject<CardRefMap>
|
||||||
requestRepaint: () => void
|
requestRepaint: () => void
|
||||||
applySelfTransform?: boolean
|
applySelfTransform?: boolean
|
||||||
}) {
|
}) {
|
||||||
|
|
@ -451,9 +461,8 @@ function OrgChartNode({
|
||||||
const levelColor = LEVEL_COLORS[depth % LEVEL_COLORS.length]
|
const levelColor = LEVEL_COLORS[depth % LEVEL_COLORS.length]
|
||||||
const borderColor = levelColor.border
|
const borderColor = levelColor.border
|
||||||
const headerBg = levelColor.header
|
const headerBg = levelColor.header
|
||||||
const badgeBg = levelColor.badge
|
|
||||||
|
|
||||||
const handleDragStart = (e: React.MouseEvent<HTMLDivElement>) => {
|
const handleDragStart = (e: ReactMouseEvent<HTMLDivElement>) => {
|
||||||
const target = e.target as HTMLElement
|
const target = e.target as HTMLElement
|
||||||
if (target.closest('[data-stop-drag="true"]')) {
|
if (target.closest('[data-stop-drag="true"]')) {
|
||||||
return
|
return
|
||||||
|
|
@ -508,12 +517,12 @@ function OrgChartNode({
|
||||||
ref={(el) => {
|
ref={(el) => {
|
||||||
cardRefs.current[node.id] = el
|
cardRefs.current[node.id] = el
|
||||||
}}
|
}}
|
||||||
onMouseDown={handleDragStart}
|
|
||||||
data-card=""
|
data-card=""
|
||||||
data-depth={depth}
|
data-depth={depth}
|
||||||
data-users-visible={showUsers ? 'true' : 'false'}
|
data-users-visible={showUsers ? 'true' : 'false'}
|
||||||
className={`relative bg-white border ${borderColor} rounded-xl shadow-sm w-36 sm:w-44 md:w-52 hover:shadow-md transition-shadow`}
|
className={`relative bg-white border ${borderColor} rounded-xl shadow-sm w-36 sm:w-44 md:w-52 hover:shadow-md transition-shadow`}
|
||||||
style={{ cursor: dragging ? 'grabbing' : 'grab' }}
|
style={{ cursor: dragging ? 'grabbing' : 'grab' }}
|
||||||
|
onMouseDown={handleDragStart}
|
||||||
>
|
>
|
||||||
{/* Header bar */}
|
{/* Header bar */}
|
||||||
<div
|
<div
|
||||||
|
|
@ -534,10 +543,6 @@ function OrgChartNode({
|
||||||
{hasChildren && (
|
{hasChildren && (
|
||||||
<Button
|
<Button
|
||||||
data-stop-drag="true"
|
data-stop-drag="true"
|
||||||
onClick={() => {
|
|
||||||
setCollapsed((c) => !c)
|
|
||||||
requestRepaint()
|
|
||||||
}}
|
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="circle"
|
shape="circle"
|
||||||
icon={
|
icon={
|
||||||
|
|
@ -548,6 +553,10 @@ function OrgChartNode({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="ml-1 !h-5 !w-5 flex-shrink-0 !px-0 text-white opacity-70 transition-opacity hover:opacity-100"
|
className="ml-1 !h-5 !w-5 flex-shrink-0 !px-0 text-white opacity-70 transition-opacity hover:opacity-100"
|
||||||
|
onClick={() => {
|
||||||
|
setCollapsed((c) => !c)
|
||||||
|
requestRepaint()
|
||||||
|
}}
|
||||||
></Button>
|
></Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -590,7 +599,7 @@ function OrgChartNode({
|
||||||
{/* Children */}
|
{/* Children */}
|
||||||
{hasChildren && !collapsed && (
|
{hasChildren && !collapsed && (
|
||||||
<div className="mt-6 sm:mt-8 md:mt-10 flex items-start gap-4 sm:gap-6 md:gap-10">
|
<div className="mt-6 sm:mt-8 md:mt-10 flex items-start gap-4 sm:gap-6 md:gap-10">
|
||||||
{node.children.map((child, idx) => {
|
{node.children.map((child) => {
|
||||||
const childPosition = positions[child.id] ?? { x: 0, y: 0 }
|
const childPosition = positions[child.id] ?? { x: 0, y: 0 }
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -639,7 +648,7 @@ function OrgChartTree({
|
||||||
tenantId?: string
|
tenantId?: string
|
||||||
zoom: number
|
zoom: number
|
||||||
positions: PositionMap
|
positions: PositionMap
|
||||||
setPositions: React.Dispatch<React.SetStateAction<PositionMap>>
|
setPositions: Dispatch<SetStateAction<PositionMap>>
|
||||||
edges: EdgeLink[]
|
edges: EdgeLink[]
|
||||||
}) {
|
}) {
|
||||||
const containerRef = useRef<HTMLDivElement>(null)
|
const containerRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
@ -836,7 +845,7 @@ const OrgChart = () => {
|
||||||
setPositions({})
|
setPositions({})
|
||||||
}, [mode])
|
}, [mode])
|
||||||
|
|
||||||
const handleWheelZoom = (e: React.WheelEvent<HTMLDivElement>) => {
|
const handleWheelZoom = (e: WheelEvent<HTMLDivElement>) => {
|
||||||
if (!e.ctrlKey) {
|
if (!e.ctrlKey) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -882,7 +891,6 @@ const OrgChart = () => {
|
||||||
<div className="flex flex-wrap items-center gap-2">
|
<div className="flex flex-wrap items-center gap-2">
|
||||||
<div className="flex items-center bg-slate-100 dark:bg-gray-800 rounded-lg p-1 gap-1">
|
<div className="flex items-center bg-slate-100 dark:bg-gray-800 rounded-lg p-1 gap-1">
|
||||||
<Button
|
<Button
|
||||||
onClick={() => setMode('department')}
|
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="none"
|
shape="none"
|
||||||
icon={<FaBuilding className="h-3.5 w-3.5 flex-shrink-0" />}
|
icon={<FaBuilding className="h-3.5 w-3.5 flex-shrink-0" />}
|
||||||
|
|
@ -892,13 +900,13 @@ const OrgChart = () => {
|
||||||
? '!bg-blue-600 !text-white shadow-sm ring-1 ring-blue-300/70 dark:ring-blue-400/70'
|
? '!bg-blue-600 !text-white shadow-sm ring-1 ring-blue-300/70 dark:ring-blue-400/70'
|
||||||
: '!bg-transparent text-slate-600 hover:!bg-white hover:text-slate-800 dark:text-gray-300 dark:hover:!bg-gray-700 dark:hover:text-white'
|
: '!bg-transparent text-slate-600 hover:!bg-white hover:text-slate-800 dark:text-gray-300 dark:hover:!bg-gray-700 dark:hover:text-white'
|
||||||
}`}
|
}`}
|
||||||
|
onClick={() => setMode('department')}
|
||||||
>
|
>
|
||||||
<span className="hidden sm:inline">
|
<span className="hidden sm:inline">
|
||||||
{translate('::App.Hr.Department') || 'Departman'}
|
{translate('::App.Hr.Department') || 'Departman'}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => setMode('jobPosition')}
|
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="none"
|
shape="none"
|
||||||
icon={<FaBriefcase className="h-3.5 w-3.5 flex-shrink-0" />}
|
icon={<FaBriefcase className="h-3.5 w-3.5 flex-shrink-0" />}
|
||||||
|
|
@ -908,6 +916,7 @@ const OrgChart = () => {
|
||||||
? '!bg-purple-600 !text-white shadow-sm ring-1 ring-purple-300/70 dark:ring-purple-400/70'
|
? '!bg-purple-600 !text-white shadow-sm ring-1 ring-purple-300/70 dark:ring-purple-400/70'
|
||||||
: '!bg-transparent text-slate-600 hover:!bg-white hover:text-slate-800 dark:text-gray-300 dark:hover:!bg-gray-700 dark:hover:text-white'
|
: '!bg-transparent text-slate-600 hover:!bg-white hover:text-slate-800 dark:text-gray-300 dark:hover:!bg-gray-700 dark:hover:text-white'
|
||||||
}`}
|
}`}
|
||||||
|
onClick={() => setMode('jobPosition')}
|
||||||
>
|
>
|
||||||
<span className="hidden sm:inline">
|
<span className="hidden sm:inline">
|
||||||
{translate('::App.Hr.JobPosition') || 'Pozisyon'}
|
{translate('::App.Hr.JobPosition') || 'Pozisyon'}
|
||||||
|
|
@ -920,8 +929,8 @@ const OrgChart = () => {
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={showUsers}
|
checked={showUsers}
|
||||||
onChange={(e) => setShowUsers(e.target.checked)}
|
|
||||||
className="h-4 w-4 rounded border-slate-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500"
|
className="h-4 w-4 rounded border-slate-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500"
|
||||||
|
onChange={(e) => setShowUsers(e.target.checked)}
|
||||||
/>
|
/>
|
||||||
<span className="hidden sm:inline">
|
<span className="hidden sm:inline">
|
||||||
{translate('::App.Definitions.OrgChart.ShowUsers') || 'Kullanıcılar'}
|
{translate('::App.Definitions.OrgChart.ShowUsers') || 'Kullanıcılar'}
|
||||||
|
|
@ -931,42 +940,42 @@ const OrgChart = () => {
|
||||||
|
|
||||||
<div className="flex items-center bg-slate-100 dark:bg-gray-800 rounded-lg p-1 gap-1">
|
<div className="flex items-center bg-slate-100 dark:bg-gray-800 rounded-lg p-1 gap-1">
|
||||||
<Button
|
<Button
|
||||||
onClick={handleZoomOut}
|
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="none"
|
shape="none"
|
||||||
icon={<FaSearchMinus className="h-3.5 w-3.5" />}
|
icon={<FaSearchMinus className="h-3.5 w-3.5" />}
|
||||||
className="!h-7 !w-7 !rounded-md !px-0 text-slate-600 hover:!bg-white hover:text-slate-800 dark:text-gray-300 dark:hover:!bg-gray-700 dark:hover:text-white sm:!h-8 sm:!w-8"
|
className="!h-7 !w-7 !rounded-md !px-0 text-slate-600 hover:!bg-white hover:text-slate-800 dark:text-gray-300 dark:hover:!bg-gray-700 dark:hover:text-white sm:!h-8 sm:!w-8"
|
||||||
title="Zoom Out"
|
title="Zoom Out"
|
||||||
|
onClick={handleZoomOut}
|
||||||
/>
|
/>
|
||||||
<span className="text-xs font-medium text-slate-600 dark:text-gray-300 px-1 min-w-[36px] sm:min-w-[46px] text-center">
|
<span className="text-xs font-medium text-slate-600 dark:text-gray-300 px-1 min-w-[36px] sm:min-w-[46px] text-center">
|
||||||
{Math.round(zoom * 100)}%
|
{Math.round(zoom * 100)}%
|
||||||
</span>
|
</span>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleZoomIn}
|
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="none"
|
shape="none"
|
||||||
icon={<FaSearchPlus className="h-3.5 w-3.5" />}
|
icon={<FaSearchPlus className="h-3.5 w-3.5" />}
|
||||||
className="!h-7 !w-7 !rounded-md !px-0 text-slate-600 hover:!bg-white hover:text-slate-800 dark:text-gray-300 dark:hover:!bg-gray-700 dark:hover:text-white sm:!h-8 sm:!w-8"
|
className="!h-7 !w-7 !rounded-md !px-0 text-slate-600 hover:!bg-white hover:text-slate-800 dark:text-gray-300 dark:hover:!bg-gray-700 dark:hover:text-white sm:!h-8 sm:!w-8"
|
||||||
title="Zoom In"
|
title="Zoom In"
|
||||||
|
onClick={handleZoomIn}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleZoomReset}
|
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="none"
|
shape="none"
|
||||||
icon={<FaUndo className="h-3.5 w-3.5" />}
|
icon={<FaUndo className="h-3.5 w-3.5" />}
|
||||||
className="!h-7 !w-7 !rounded-md !px-0 text-slate-600 hover:!bg-white hover:text-slate-800 dark:text-gray-300 dark:hover:!bg-gray-700 dark:hover:text-white sm:!h-8 sm:!w-8"
|
className="!h-7 !w-7 !rounded-md !px-0 text-slate-600 hover:!bg-white hover:text-slate-800 dark:text-gray-300 dark:hover:!bg-gray-700 dark:hover:text-white sm:!h-8 sm:!w-8"
|
||||||
title="Reset Zoom"
|
title="Reset Zoom"
|
||||||
|
onClick={handleZoomReset}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={handleExportJpg}
|
|
||||||
disabled={exporting || loading}
|
disabled={exporting || loading}
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="none"
|
shape="none"
|
||||||
icon={<FaFileImage className="h-3.5 w-3.5 flex-shrink-0" />}
|
icon={<FaFileImage className="h-3.5 w-3.5 flex-shrink-0" />}
|
||||||
className="!inline-flex !h-auto !items-center !justify-center gap-1.5 !rounded-lg bg-slate-100 !p-1.5 text-xs font-medium text-slate-600 transition-colors hover:!bg-slate-200 disabled:opacity-50 dark:bg-gray-800 dark:text-gray-300 dark:hover:!bg-gray-700 sm:!p-2 sm:text-sm"
|
className="!inline-flex !h-auto !items-center !justify-center gap-1.5 !rounded-lg bg-slate-100 !p-1.5 text-xs font-medium text-slate-600 transition-colors hover:!bg-slate-200 disabled:opacity-50 dark:bg-gray-800 dark:text-gray-300 dark:hover:!bg-gray-700 sm:!p-2 sm:text-sm"
|
||||||
title="JPG olarak indir"
|
title="JPG olarak indir"
|
||||||
|
onClick={handleExportJpg}
|
||||||
>
|
>
|
||||||
<span className="hidden sm:inline">{exporting ? 'İşleniyor…' : 'Export'}</span>
|
<span className="hidden sm:inline">{exporting ? 'İşleniyor…' : 'Export'}</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Card, Checkbox, FormContainer, FormItem, Input, Select, Button } from '@/components/ui'
|
import { Checkbox, FormContainer, FormItem, Input, Select, Button } from '@/components/ui'
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
import { SelectBoxOption } from '@/types/shared'
|
||||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import { object } from 'yup'
|
import { object } from 'yup'
|
||||||
|
|
@ -26,7 +26,7 @@ function ChartTabAnimation(props: FormEditProps) {
|
||||||
await props.onSubmit(ListFormEditTabs.ChartAnimationForm, values, formikHelpers)
|
await props.onSubmit(ListFormEditTabs.ChartAnimationForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, resetForm, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting, values }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<FormItem
|
<FormItem
|
||||||
|
|
@ -79,7 +79,7 @@ function ChartTabAnimation(props: FormEditProps) {
|
||||||
<Field type="number" name="animationDto.maxPointCountSupported" component={Input} />
|
<Field type="number" name="animationDto.maxPointCountSupported" component={Input} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ function ChartTabAnnotations(props: FormEditProps) {
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, resetForm, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting, values }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<Tabs defaultValue="annotations_general">
|
<Tabs defaultValue="annotations_general">
|
||||||
|
|
@ -121,7 +121,7 @@ function ChartTabAnnotations(props: FormEditProps) {
|
||||||
size="sm"
|
size="sm"
|
||||||
title="Edit"
|
title="Edit"
|
||||||
icon={<FaEdit />}
|
icon={<FaEdit />}
|
||||||
onClick={async (e) => {
|
onClick={async () => {
|
||||||
setJsonRowOpModalData({
|
setJsonRowOpModalData({
|
||||||
tabName: ListFormEditTabs.ChartAnnotations.GeneralJsonRow,
|
tabName: ListFormEditTabs.ChartAnnotations.GeneralJsonRow,
|
||||||
operation: 'update',
|
operation: 'update',
|
||||||
|
|
@ -660,7 +660,7 @@ function ChartTabAnnotations(props: FormEditProps) {
|
||||||
</TabContent>
|
</TabContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ function ChartTabAxis(props: FormEditProps) {
|
||||||
await props.onSubmit(ListFormEditTabs.ChartAxis.CommonAxisForm, values, formikHelpers)
|
await props.onSubmit(ListFormEditTabs.ChartAxis.CommonAxisForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, resetForm, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting, values }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<Tabs defaultValue="axis_value">
|
<Tabs defaultValue="axis_value">
|
||||||
|
|
@ -114,7 +114,7 @@ function ChartTabAxis(props: FormEditProps) {
|
||||||
size="sm"
|
size="sm"
|
||||||
title="Edit"
|
title="Edit"
|
||||||
icon={<FaEdit />}
|
icon={<FaEdit />}
|
||||||
onClick={async (e) => {
|
onClick={async () => {
|
||||||
setJsonRowOpModalData({
|
setJsonRowOpModalData({
|
||||||
tabName: ListFormEditTabs.ChartAxis.ValueAxisJsonRow,
|
tabName: ListFormEditTabs.ChartAxis.ValueAxisJsonRow,
|
||||||
operation: 'update',
|
operation: 'update',
|
||||||
|
|
@ -541,7 +541,7 @@ function ChartTabAxis(props: FormEditProps) {
|
||||||
</TabContent>
|
</TabContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import TabList from '@/components/ui/Tabs/TabList'
|
||||||
import TabNav from '@/components/ui/Tabs/TabNav'
|
import TabNav from '@/components/ui/Tabs/TabNav'
|
||||||
import { IdentityRoleDto } from '@/proxy/admin/models'
|
import { IdentityRoleDto } from '@/proxy/admin/models'
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
import { SelectBoxOption } from '@/types/shared'
|
||||||
import { Field, FieldProps, Form, Formik, FormikErrors, FormikTouched } from 'formik'
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import { FormEditProps } from '../../listForm/edit/FormEdit'
|
import { FormEditProps } from '../../listForm/edit/FormEdit'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { useStoreState } from '@/store/store'
|
import { useStoreState } from '@/store/store'
|
||||||
|
|
@ -53,7 +53,7 @@ function ChartTabCommonSettings(props: FormEditProps) {
|
||||||
await props.onSubmit(ListFormEditTabs.ChartCommon, values, formikHelpers)
|
await props.onSubmit(ListFormEditTabs.ChartCommon, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, resetForm, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting, values }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<Tabs defaultValue="commonSettings_general">
|
<Tabs defaultValue="commonSettings_general">
|
||||||
|
|
@ -716,7 +716,7 @@ function ChartTabCommonSettings(props: FormEditProps) {
|
||||||
</TabContent>
|
</TabContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ function ChartTabCrosshair(props: FormEditProps) {
|
||||||
await props.onSubmit(ListFormEditTabs.ChartCrosshairForm, values, formikHelpers)
|
await props.onSubmit(ListFormEditTabs.ChartCrosshairForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, resetForm, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting, values }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-3">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-3">
|
||||||
|
|
@ -336,7 +336,7 @@ function ChartTabCrosshair(props: FormEditProps) {
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Button, Card, Checkbox, FormContainer, FormItem, Input } from '@/components/ui'
|
import { Button, Checkbox, FormContainer, FormItem, Input } from '@/components/ui'
|
||||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import { FormEditProps } from '../../listForm/edit/FormEdit'
|
import { FormEditProps } from '../../listForm/edit/FormEdit'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
|
@ -24,7 +24,7 @@ function ChartTabExport(props: FormEditProps) {
|
||||||
await props.onSubmit(ListFormEditTabs.ChartExportForm, values, formikHelpers)
|
await props.onSubmit(ListFormEditTabs.ChartExportForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, resetForm, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<FormItem label="Enabled">
|
<FormItem label="Enabled">
|
||||||
|
|
@ -65,7 +65,7 @@ function ChartTabExport(props: FormEditProps) {
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,8 @@ import {
|
||||||
FormContainer,
|
FormContainer,
|
||||||
FormItem,
|
FormItem,
|
||||||
Input,
|
Input,
|
||||||
Select,
|
Select
|
||||||
Tabs,
|
|
||||||
} from '@/components/ui'
|
} from '@/components/ui'
|
||||||
import TabContent from '@/components/ui/Tabs/TabContent'
|
|
||||||
import TabList from '@/components/ui/Tabs/TabList'
|
|
||||||
import TabNav from '@/components/ui/Tabs/TabNav'
|
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
import { SelectBoxOption } from '@/types/shared'
|
||||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import { FormEditProps } from '../../listForm/edit/FormEdit'
|
import { FormEditProps } from '../../listForm/edit/FormEdit'
|
||||||
|
|
@ -42,7 +38,7 @@ function ChartTabLegend(props: FormEditProps) {
|
||||||
await props.onSubmit(ListFormEditTabs.ChartLegendForm, values, formikHelpers)
|
await props.onSubmit(ListFormEditTabs.ChartLegendForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, resetForm, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting, values }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||||
|
|
@ -216,7 +212,7 @@ function ChartTabLegend(props: FormEditProps) {
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ function ChartTabPanes(props: FormEditProps) {
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, resetForm, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<Card className="my-2">
|
<Card className="my-2">
|
||||||
|
|
@ -110,7 +110,7 @@ function ChartTabPanes(props: FormEditProps) {
|
||||||
size="sm"
|
size="sm"
|
||||||
title="Edit"
|
title="Edit"
|
||||||
icon={<FaEdit />}
|
icon={<FaEdit />}
|
||||||
onClick={async (e) => {
|
onClick={async () => {
|
||||||
setJsonRowOpModalData({
|
setJsonRowOpModalData({
|
||||||
tabName: ListFormEditTabs.ChartPanes.PanesJsonRow,
|
tabName: ListFormEditTabs.ChartPanes.PanesJsonRow,
|
||||||
operation: 'update',
|
operation: 'update',
|
||||||
|
|
@ -155,7 +155,7 @@ function ChartTabPanes(props: FormEditProps) {
|
||||||
setData={setJsonRowOpModalData}
|
setData={setJsonRowOpModalData}
|
||||||
/>
|
/>
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import {
|
||||||
chartSeriesSelectionModeOptions,
|
chartSeriesSelectionModeOptions,
|
||||||
chartSeriesDashStyleOptions,
|
chartSeriesDashStyleOptions,
|
||||||
} from './options'
|
} from './options'
|
||||||
import { useEffect, useState } from 'react'
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { JsonRowDialogData } from './json-row-operations/types'
|
import { JsonRowDialogData } from './json-row-operations/types'
|
||||||
import JsonRowOpDialogSeries from './json-row-operations/JsonRowOpDialogSeries'
|
import JsonRowOpDialogSeries from './json-row-operations/JsonRowOpDialogSeries'
|
||||||
import CreatableSelect from 'react-select/creatable'
|
import CreatableSelect from 'react-select/creatable'
|
||||||
|
|
@ -52,25 +52,22 @@ function ChartTabSeries(props: FormEditProps & { listFormCode: string }) {
|
||||||
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
|
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
|
||||||
|
|
||||||
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
||||||
if (!listFormValues) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
const valueAxisList = () => {
|
const valueAxisList = useMemo(() => {
|
||||||
return listFormValues?.valueAxisDto.map((key: ChartValueAxisDto) => ({
|
return (listFormValues?.valueAxisDto ?? []).map((key: ChartValueAxisDto) => ({
|
||||||
value: key.name,
|
value: key.name,
|
||||||
label: key.name,
|
label: key.name,
|
||||||
}))
|
}))
|
||||||
}
|
}, [listFormValues?.valueAxisDto])
|
||||||
|
|
||||||
const valuePaneList = () => {
|
const valuePaneList = useMemo(() => {
|
||||||
return listFormValues?.panesDto.map((key: ChartPanesDto) => ({
|
return (listFormValues?.panesDto ?? []).map((key: ChartPanesDto) => ({
|
||||||
value: key.name,
|
value: key.name,
|
||||||
label: key.name,
|
label: key.name,
|
||||||
}))
|
}))
|
||||||
}
|
}, [listFormValues?.panesDto])
|
||||||
|
|
||||||
const getFields = async () => {
|
const getFields = useCallback(async () => {
|
||||||
if (!props.listFormCode) {
|
if (!props.listFormCode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -101,13 +98,17 @@ function ChartTabSeries(props: FormEditProps & { listFormCode: string }) {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}, [props.listFormCode])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.listFormCode) {
|
if (props.listFormCode) {
|
||||||
getFields()
|
getFields()
|
||||||
}
|
}
|
||||||
}, [props.listFormCode])
|
}, [getFields, props.listFormCode])
|
||||||
|
|
||||||
|
if (!listFormValues) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik
|
<Formik
|
||||||
|
|
@ -121,7 +122,7 @@ function ChartTabSeries(props: FormEditProps & { listFormCode: string }) {
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, resetForm, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting, values }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<Tabs defaultValue="series_general">
|
<Tabs defaultValue="series_general">
|
||||||
|
|
@ -176,7 +177,7 @@ function ChartTabSeries(props: FormEditProps & { listFormCode: string }) {
|
||||||
size="sm"
|
size="sm"
|
||||||
title="Edit"
|
title="Edit"
|
||||||
icon={<FaEdit />}
|
icon={<FaEdit />}
|
||||||
onClick={async (e) => {
|
onClick={async () => {
|
||||||
setJsonRowOpModalData({
|
setJsonRowOpModalData({
|
||||||
tabName: ListFormEditTabs.ChartSeries.GeneralJsonRow,
|
tabName: ListFormEditTabs.ChartSeries.GeneralJsonRow,
|
||||||
operation: 'update',
|
operation: 'update',
|
||||||
|
|
@ -346,9 +347,9 @@ function ChartTabSeries(props: FormEditProps & { listFormCode: string }) {
|
||||||
(option) =>
|
(option) =>
|
||||||
option.value === values.commonSeriesSettingsDto.argumentField,
|
option.value === values.commonSeriesSettingsDto.argumentField,
|
||||||
)}
|
)}
|
||||||
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
|
||||||
menuPlacement="auto"
|
menuPlacement="auto"
|
||||||
maxMenuHeight={150}
|
maxMenuHeight={150}
|
||||||
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
|
|
@ -362,7 +363,7 @@ function ChartTabSeries(props: FormEditProps & { listFormCode: string }) {
|
||||||
}
|
}
|
||||||
errorMessage={errors.commonSeriesSettingsDto?.valueField}
|
errorMessage={errors.commonSeriesSettingsDto?.valueField}
|
||||||
>
|
>
|
||||||
<Field type="text" name="valueField">
|
<Field type="text" name="commonSeriesSettingsDto.valueField">
|
||||||
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
||||||
<Select
|
<Select
|
||||||
componentAs={CreatableSelect}
|
componentAs={CreatableSelect}
|
||||||
|
|
@ -374,9 +375,9 @@ function ChartTabSeries(props: FormEditProps & { listFormCode: string }) {
|
||||||
(option) =>
|
(option) =>
|
||||||
option.value === values.commonSeriesSettingsDto.valueField,
|
option.value === values.commonSeriesSettingsDto.valueField,
|
||||||
)}
|
)}
|
||||||
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
|
||||||
menuPlacement="auto"
|
menuPlacement="auto"
|
||||||
maxMenuHeight={150}
|
maxMenuHeight={150}
|
||||||
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
|
|
@ -398,9 +399,9 @@ function ChartTabSeries(props: FormEditProps & { listFormCode: string }) {
|
||||||
<Select
|
<Select
|
||||||
field={field}
|
field={field}
|
||||||
form={form}
|
form={form}
|
||||||
options={valueAxisList()}
|
options={valueAxisList}
|
||||||
isClearable={true}
|
isClearable={true}
|
||||||
value={valueAxisList()?.find(
|
value={valueAxisList.find(
|
||||||
(option) => option.value === values.commonSeriesSettingsDto.axis,
|
(option) => option.value === values.commonSeriesSettingsDto.axis,
|
||||||
)}
|
)}
|
||||||
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
|
|
@ -424,9 +425,9 @@ function ChartTabSeries(props: FormEditProps & { listFormCode: string }) {
|
||||||
<Select
|
<Select
|
||||||
field={field}
|
field={field}
|
||||||
form={form}
|
form={form}
|
||||||
options={valuePaneList()}
|
options={valuePaneList}
|
||||||
isClearable={true}
|
isClearable={true}
|
||||||
value={valuePaneList()?.find(
|
value={valuePaneList.find(
|
||||||
(option) => option.value === values.commonSeriesSettingsDto.pane,
|
(option) => option.value === values.commonSeriesSettingsDto.pane,
|
||||||
)}
|
)}
|
||||||
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
|
|
@ -523,7 +524,7 @@ function ChartTabSeries(props: FormEditProps & { listFormCode: string }) {
|
||||||
</TabContent>
|
</TabContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ const ChartTabZoomAndPan = (props: FormEditProps) => {
|
||||||
await props.onSubmit(ListFormEditTabs.ChartZoomForm, values, formikHelpers)
|
await props.onSubmit(ListFormEditTabs.ChartZoomForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, resetForm, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting, values }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||||
|
|
@ -176,7 +176,7 @@ const ChartTabZoomAndPan = (props: FormEditProps) => {
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -294,7 +294,7 @@ function FormCustomization({
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Alert, Badge, Notification, Tabs, toast } from '@/components/ui'
|
import { Badge, Notification, Tabs, toast } from '@/components/ui'
|
||||||
import TabContent from '@/components/ui/Tabs/TabContent'
|
import TabContent from '@/components/ui/Tabs/TabContent'
|
||||||
import TabList from '@/components/ui/Tabs/TabList'
|
import TabList from '@/components/ui/Tabs/TabList'
|
||||||
import TabNav from '@/components/ui/Tabs/TabNav'
|
import TabNav from '@/components/ui/Tabs/TabNav'
|
||||||
|
|
@ -7,7 +7,7 @@ import { SelectBoxOption } from '@/types/shared'
|
||||||
import { useStoreActions, useStoreState } from '@/store'
|
import { useStoreActions, useStoreState } from '@/store'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { FormikHelpers } from 'formik'
|
import { FormikHelpers } from 'formik'
|
||||||
import { useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
import { Link, useParams } from 'react-router-dom'
|
import { Link, useParams } from 'react-router-dom'
|
||||||
import FormCustomization from './FormCustomization'
|
import FormCustomization from './FormCustomization'
|
||||||
|
|
@ -27,8 +27,7 @@ import FormTabSubForm from './FormTabSubForm'
|
||||||
import FormFields from './form-fields/FormFields'
|
import FormFields from './form-fields/FormFields'
|
||||||
import { putListForms } from '@/services/admin/list-form.service'
|
import { putListForms } from '@/services/admin/list-form.service'
|
||||||
import { getRoles, getUsers } from '@/services/identity.service'
|
import { getRoles, getUsers } from '@/services/identity.service'
|
||||||
import { GridOptionsEditDto, ListFormCustomizationDto } from '@/proxy/form/models'
|
import { SelectCommandTypeEnum, GridOptionsEditDto, ListFormCustomizationDto } from '@/proxy/form/models'
|
||||||
import { SelectCommandTypeEnum } from '@/proxy/form/models'
|
|
||||||
import { IdentityRoleDto, IdentityUserDto } from '@/proxy/admin/models'
|
import { IdentityRoleDto, IdentityUserDto } from '@/proxy/admin/models'
|
||||||
import { getListFormCustomizations } from '@/services/admin/list-form-customization.service'
|
import { getListFormCustomizations } from '@/services/admin/list-form-customization.service'
|
||||||
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
|
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
|
||||||
|
|
@ -95,7 +94,7 @@ const FormEdit = () => {
|
||||||
}
|
}
|
||||||
}, [languages])
|
}, [languages])
|
||||||
|
|
||||||
const getRoleList = async () => {
|
const getRoleList = useCallback(async () => {
|
||||||
const response = await getRoles()
|
const response = await getRoles()
|
||||||
if (response.data?.items) {
|
if (response.data?.items) {
|
||||||
setRoleList(
|
setRoleList(
|
||||||
|
|
@ -105,9 +104,9 @@ const FormEdit = () => {
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}, [])
|
||||||
|
|
||||||
const getUserList = async () => {
|
const getUserList = useCallback(async () => {
|
||||||
const response = await getUsers(0, 1000)
|
const response = await getUsers(0, 1000)
|
||||||
if (response.data?.items) {
|
if (response.data?.items) {
|
||||||
setUserList(
|
setUserList(
|
||||||
|
|
@ -117,17 +116,17 @@ const FormEdit = () => {
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}, [])
|
||||||
|
|
||||||
const getCustomizations = async () => {
|
const getCustomizations = useCallback(async () => {
|
||||||
if (!listFormCode) {
|
if (!listFormCode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const resp = await getListFormCustomizations({ listFormCode, maxResultCount: 1000 })
|
const resp = await getListFormCustomizations({ listFormCode, maxResultCount: 1000 })
|
||||||
setCustomizations(resp?.data?.items)
|
setCustomizations(resp?.data?.items)
|
||||||
}
|
}, [listFormCode])
|
||||||
|
|
||||||
const refreshData = async () => {
|
const refreshData = useCallback(async () => {
|
||||||
if (!listFormCode) {
|
if (!listFormCode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +134,7 @@ const FormEdit = () => {
|
||||||
await getCustomizations()
|
await getCustomizations()
|
||||||
await getRoleList()
|
await getRoleList()
|
||||||
await getUserList()
|
await getUserList()
|
||||||
}
|
}, [getCustomizations, getListFormValues, getRoleList, getUserList, listFormCode])
|
||||||
|
|
||||||
const listFormType = listFormValues?.listFormType || 'List'
|
const listFormType = listFormValues?.listFormType || 'List'
|
||||||
const [activeFormType, setActiveFormType] = useState<string>(listFormType)
|
const [activeFormType, setActiveFormType] = useState<string>(listFormType)
|
||||||
|
|
@ -144,7 +143,7 @@ const FormEdit = () => {
|
||||||
//LİST FORM ve LİST FORM FİELDS AİT BİLGİLER
|
//LİST FORM ve LİST FORM FİELDS AİT BİLGİLER
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
refreshData()
|
refreshData()
|
||||||
}, [listFormCode])
|
}, [refreshData])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadWorkflowColumns = async () => {
|
const loadWorkflowColumns = async () => {
|
||||||
|
|
@ -378,9 +377,9 @@ const FormEdit = () => {
|
||||||
|
|
||||||
<TabContent value="details" className="px-2">
|
<TabContent value="details" className="px-2">
|
||||||
<FormTabDetails
|
<FormTabDetails
|
||||||
onSubmit={onSubmit}
|
|
||||||
roleList={roleList}
|
roleList={roleList}
|
||||||
userList={userList}
|
userList={userList}
|
||||||
|
onSubmit={onSubmit}
|
||||||
onFormTypeChange={setActiveFormType}
|
onFormTypeChange={setActiveFormType}
|
||||||
/>
|
/>
|
||||||
</TabContent>
|
</TabContent>
|
||||||
|
|
@ -442,7 +441,7 @@ const FormEdit = () => {
|
||||||
<FormTabSubForm />
|
<FormTabSubForm />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="widget" className="px-2">
|
<TabContent value="widget" className="px-2">
|
||||||
<FormTabWidgets listFormCode={listFormCode} />
|
<FormTabWidgets />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="workflow" className="px-2">
|
<TabContent value="workflow" className="px-2">
|
||||||
<FormTabWorkflow
|
<FormTabWorkflow
|
||||||
|
|
@ -478,7 +477,7 @@ const FormEdit = () => {
|
||||||
<ChartTabCommonSettings onSubmit={onSubmit} />
|
<ChartTabCommonSettings onSubmit={onSubmit} />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="series" className="px-2">
|
<TabContent value="series" className="px-2">
|
||||||
<ChartTabSeries onSubmit={onSubmit} listFormCode={listFormCode} />
|
<ChartTabSeries listFormCode={listFormCode} onSubmit={onSubmit} />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="panes" className="px-2">
|
<TabContent value="panes" className="px-2">
|
||||||
<ChartTabPanes onSubmit={onSubmit} />
|
<ChartTabPanes onSubmit={onSubmit} />
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
import { Container } from '@/components/shared'
|
import { Container } from '@/components/shared'
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
|
||||||
Checkbox,
|
Checkbox,
|
||||||
FormContainer,
|
FormContainer,
|
||||||
FormItem,
|
FormItem,
|
||||||
Input,
|
|
||||||
Select,
|
Select,
|
||||||
Tabs,
|
|
||||||
} from '@/components/ui'
|
} from '@/components/ui'
|
||||||
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
||||||
import { useStoreState } from '@/store'
|
import { useStoreState } from '@/store'
|
||||||
|
|
@ -310,7 +307,7 @@ function FormTabColumns(props: FormEditProps) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit" className="my-2">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit" className="my-2">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ function FormTabCommands() {
|
||||||
size="sm"
|
size="sm"
|
||||||
title="Edit"
|
title="Edit"
|
||||||
icon={<FaEdit />}
|
icon={<FaEdit />}
|
||||||
onClick={async (e) => {
|
onClick={async () => {
|
||||||
setJsonRowOpModalData({
|
setJsonRowOpModalData({
|
||||||
tabName: ListFormEditTabs.CommandColumnsJsonRow,
|
tabName: ListFormEditTabs.CommandColumnsJsonRow,
|
||||||
operation: 'update',
|
operation: 'update',
|
||||||
|
|
|
||||||
|
|
@ -263,10 +263,10 @@ function FormTabDatabaseDataSource(props: FormEditProps) {
|
||||||
: []
|
: []
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
|
isClearable
|
||||||
componentAs={CreatableSelect}
|
componentAs={CreatableSelect}
|
||||||
field={field}
|
field={field}
|
||||||
form={form}
|
form={form}
|
||||||
isClearable
|
|
||||||
isLoading={isLoadingDbObjects}
|
isLoading={isLoadingDbObjects}
|
||||||
options={grouped}
|
options={grouped}
|
||||||
placeholder={
|
placeholder={
|
||||||
|
|
@ -346,10 +346,10 @@ function FormTabDatabaseDataSource(props: FormEditProps) {
|
||||||
<Field type="text" autoComplete="off" name="keyFieldName">
|
<Field type="text" autoComplete="off" name="keyFieldName">
|
||||||
{({ field, form }: FieldProps<string>) => (
|
{({ field, form }: FieldProps<string>) => (
|
||||||
<Select
|
<Select
|
||||||
|
isClearable
|
||||||
componentAs={CreatableSelect}
|
componentAs={CreatableSelect}
|
||||||
field={field}
|
field={field}
|
||||||
form={form}
|
form={form}
|
||||||
isClearable
|
|
||||||
isLoading={isLoadingColumns}
|
isLoading={isLoadingColumns}
|
||||||
placeholder={
|
placeholder={
|
||||||
isLoadingColumns
|
isLoadingColumns
|
||||||
|
|
@ -387,7 +387,7 @@ function FormTabDatabaseDataSource(props: FormEditProps) {
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting}>
|
<Button block size="sm" variant="solid" loading={isSubmitting}>
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ function FormTabDatabaseDelete({
|
||||||
await onSubmit(ListFormEditTabs.Database.Delete.DeleteForm, values, formikHelpers)
|
await onSubmit(ListFormEditTabs.Database.Delete.DeleteForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, values, isSubmitting }) => (
|
{({ touched, errors, isSubmitting }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<Card className="my-2">
|
<Card className="my-2">
|
||||||
|
|
@ -116,7 +116,7 @@ function FormTabDatabaseDelete({
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting}>
|
<Button block size="sm" variant="solid" loading={isSubmitting}>
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ function FormTabDatabaseInsert({
|
||||||
await onSubmit(ListFormEditTabs.Database.Insert.InsertForm, values, formikHelpers)
|
await onSubmit(ListFormEditTabs.Database.Insert.InsertForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, values, isSubmitting }) => (
|
{({ touched, errors, isSubmitting }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<Card className="my-2">
|
<Card className="my-2">
|
||||||
|
|
@ -114,7 +114,7 @@ function FormTabDatabaseInsert({
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting}>
|
<Button block size="sm" variant="solid" loading={isSubmitting}>
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ function FormTabDatabaseSelect({
|
||||||
await onSubmit(ListFormEditTabs.Database.Select.SelectForm, values, formikHelpers)
|
await onSubmit(ListFormEditTabs.Database.Select.SelectForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, values, isSubmitting }) => (
|
{({ touched, errors, isSubmitting }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<Card className="my-2">
|
<Card className="my-2">
|
||||||
|
|
@ -65,7 +65,7 @@ function FormTabDatabaseSelect({
|
||||||
component={Input}
|
component={Input}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting}>
|
<Button block size="sm" variant="solid" loading={isSubmitting}>
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ function FormTabDatabaseUpdate({
|
||||||
await onSubmit(ListFormEditTabs.Database.Update.UpdateForm, values, formikHelpers)
|
await onSubmit(ListFormEditTabs.Database.Update.UpdateForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, values, isSubmitting }) => (
|
{({ touched, errors, isSubmitting }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<Card className="my-2">
|
<Card className="my-2">
|
||||||
|
|
@ -114,7 +114,7 @@ function FormTabDatabaseUpdate({
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting}>
|
<Button block size="sm" variant="solid" loading={isSubmitting}>
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { Container } from '@/components/shared'
|
|
||||||
import { Button, Card, Checkbox, FormContainer, FormItem, Input, Select } from '@/components/ui'
|
import { Button, Card, Checkbox, FormContainer, FormItem, Input, Select } from '@/components/ui'
|
||||||
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
||||||
import { LanguageInfo } from '@/proxy/config/models'
|
import { LanguageInfo } from '@/proxy/config/models'
|
||||||
|
|
@ -47,9 +46,6 @@ function FormTabDetails(
|
||||||
|
|
||||||
const languages = useStoreState((state) => state.abpConfig.config?.localization.languages)
|
const languages = useStoreState((state) => state.abpConfig.config?.localization.languages)
|
||||||
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
||||||
if (!listFormValues) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (languages) {
|
if (languages) {
|
||||||
|
|
@ -62,6 +58,10 @@ function FormTabDetails(
|
||||||
}
|
}
|
||||||
}, [languages])
|
}, [languages])
|
||||||
|
|
||||||
|
if (!listFormValues) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={listFormValues}
|
initialValues={listFormValues}
|
||||||
|
|
@ -437,7 +437,7 @@ function FormTabDetails(
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -454,7 +454,7 @@ function FormTabEdit(props: FormEditProps & { listFormCode: string }) {
|
||||||
)}
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting}>
|
<Button block size="sm" variant="solid" loading={isSubmitting}>
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { Container } from '@/components/shared'
|
import { Container } from '@/components/shared'
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
|
||||||
Checkbox,
|
Checkbox,
|
||||||
FormContainer,
|
FormContainer,
|
||||||
FormItem,
|
FormItem,
|
||||||
|
|
@ -18,15 +17,10 @@ import * as Yup from 'yup'
|
||||||
import { FormEditProps } from './FormEdit'
|
import { FormEditProps } from './FormEdit'
|
||||||
import {
|
import {
|
||||||
applyFilterOptions,
|
applyFilterOptions,
|
||||||
overflowWrapOptions,
|
|
||||||
sortModeOptions,
|
|
||||||
whiteSpaceOptions,
|
|
||||||
} from './options'
|
} from './options'
|
||||||
import TabList from '@/components/ui/Tabs/TabList'
|
import TabList from '@/components/ui/Tabs/TabList'
|
||||||
import TabNav from '@/components/ui/Tabs/TabNav'
|
import TabNav from '@/components/ui/Tabs/TabNav'
|
||||||
import TabContent from '@/components/ui/Tabs/TabContent'
|
import TabContent from '@/components/ui/Tabs/TabContent'
|
||||||
import { GridOptionsSortModeEnum } from '@/proxy/form/models'
|
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({})
|
const validationSchema = Yup.object().shape({})
|
||||||
|
|
||||||
|
|
@ -304,7 +298,7 @@ function FormTabFilters(props: FormEditProps) {
|
||||||
</TabContent>
|
</TabContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@ import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
import { FormEditProps } from './FormEdit'
|
import { FormEditProps } from './FormEdit'
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
import { SelectBoxOption } from '@/types/shared'
|
||||||
import { useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { getListFormFields } from '@/services/admin/list-form-field.service'
|
import { getListFormFields } from '@/services/admin/list-form-field.service'
|
||||||
import { groupBy } from 'lodash'
|
import groupBy from 'lodash/groupBy'
|
||||||
import { useParams } from 'react-router-dom'
|
import { useParams } from 'react-router-dom'
|
||||||
import { GanttScaleType } from 'devextreme/ui/gantt'
|
import { GanttScaleType } from 'devextreme/ui/gantt'
|
||||||
import { gantScaleOptions } from './options'
|
import { gantScaleOptions } from './options'
|
||||||
|
|
@ -30,7 +30,7 @@ function FormTabGantt(props: FormEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
|
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
|
||||||
|
|
||||||
const getFields = async () => {
|
const getFields = useCallback(async () => {
|
||||||
if (!listFormCode) {
|
if (!listFormCode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -61,11 +61,11 @@ function FormTabGantt(props: FormEditProps) {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}, [listFormCode])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getFields()
|
getFields()
|
||||||
}, [listFormCode])
|
}, [getFields])
|
||||||
|
|
||||||
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
||||||
if (!listFormValues) {
|
if (!listFormValues) {
|
||||||
|
|
@ -471,7 +471,7 @@ function FormTabGantt(props: FormEditProps) {
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit" className="my-2">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit" className="my-2">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ function FormTabGroup(props: FormEditProps) {
|
||||||
await props.onSubmit(ListFormEditTabs.GroupForm, values, formikHelpers)
|
await props.onSubmit(ListFormEditTabs.GroupForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<FormItem
|
<FormItem
|
||||||
|
|
@ -54,7 +54,7 @@ function FormTabGroup(props: FormEditProps) {
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ function FormTabPager(props: FormEditProps) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -26,28 +26,27 @@ function FormTabPermissions(props: FormEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
||||||
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const loadPermissions = async () => {
|
||||||
|
const response = await getPermissionsList()
|
||||||
|
if (response.data) {
|
||||||
|
setPermissions(
|
||||||
|
response.data.map((permission: PermissionDefinitionRecord) => ({
|
||||||
|
value: permission.name,
|
||||||
|
label: permission.name,
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadPermissions()
|
||||||
|
}, [])
|
||||||
|
|
||||||
if (!listFormValues) {
|
if (!listFormValues) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPermissionList = async () => {
|
|
||||||
const response = await getPermissionsList()
|
|
||||||
if (response.data) {
|
|
||||||
setPermissions(
|
|
||||||
response.data.map((permission: PermissionDefinitionRecord) => ({
|
|
||||||
value: permission.name,
|
|
||||||
label: permission.name,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (permissions) {
|
|
||||||
getPermissionList()
|
|
||||||
}
|
|
||||||
}, [permissions])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className="grid xl:grid-cols-2">
|
<Container className="grid xl:grid-cols-2">
|
||||||
<Formik
|
<Formik
|
||||||
|
|
@ -239,7 +238,7 @@ function FormTabPermissions(props: FormEditProps) {
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ function FormTabColumns(props: FormEditProps) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit" className="my-2">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit" className="my-2">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ function FormTabRow(props: FormEditProps) {
|
||||||
</Field>
|
</Field>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@ import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
import { FormEditProps } from './FormEdit'
|
import { FormEditProps } from './FormEdit'
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
import { SelectBoxOption } from '@/types/shared'
|
||||||
import { useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { getListFormFields } from '@/services/admin/list-form-field.service'
|
import { getListFormFields } from '@/services/admin/list-form-field.service'
|
||||||
import { groupBy } from 'lodash'
|
import groupBy from 'lodash/groupBy'
|
||||||
import { useParams } from 'react-router-dom'
|
import { useParams } from 'react-router-dom'
|
||||||
import { firstDayOfWeekOptions, schedulerViewOptions } from './options'
|
import { firstDayOfWeekOptions, schedulerViewOptions } from './options'
|
||||||
|
|
||||||
|
|
@ -29,7 +29,7 @@ function FormTabScheduler(props: FormEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
|
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
|
||||||
|
|
||||||
const getFields = async () => {
|
const getFields = useCallback(async () => {
|
||||||
if (!listFormCode) {
|
if (!listFormCode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -60,11 +60,11 @@ function FormTabScheduler(props: FormEditProps) {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}, [listFormCode])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getFields()
|
getFields()
|
||||||
}, [listFormCode])
|
}, [getFields])
|
||||||
|
|
||||||
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
||||||
if (!listFormValues) {
|
if (!listFormValues) {
|
||||||
|
|
@ -363,7 +363,7 @@ function FormTabScheduler(props: FormEditProps) {
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit" className="my-2">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit" className="my-2">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>{' '}
|
</Button>{' '}
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ function FormTabSearch(props: FormEditProps) {
|
||||||
await props.onSubmit(ListFormEditTabs.SearchForm, values, formikHelpers)
|
await props.onSubmit(ListFormEditTabs.SearchForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<FormItem
|
<FormItem
|
||||||
|
|
@ -55,7 +55,7 @@ function FormTabSearch(props: FormEditProps) {
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ function FormTabSelect(props: FormEditProps) {
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,20 @@
|
||||||
import { Container } from '@/components/shared'
|
import { Container } from '@/components/shared'
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
|
||||||
Checkbox,
|
|
||||||
FormContainer,
|
FormContainer,
|
||||||
FormItem,
|
FormItem,
|
||||||
Input,
|
|
||||||
Select,
|
Select,
|
||||||
Tabs,
|
|
||||||
} from '@/components/ui'
|
} from '@/components/ui'
|
||||||
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
||||||
import { useStoreState } from '@/store'
|
import { useStoreState } from '@/store'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { ApplyFilterMode } from 'devextreme/common/grids'
|
|
||||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
import { FormEditProps } from './FormEdit'
|
import { FormEditProps } from './FormEdit'
|
||||||
import {
|
import {
|
||||||
applyFilterOptions,
|
|
||||||
overflowWrapOptions,
|
|
||||||
sortModeOptions,
|
sortModeOptions,
|
||||||
whiteSpaceOptions,
|
|
||||||
} from './options'
|
} from './options'
|
||||||
import TabList from '@/components/ui/Tabs/TabList'
|
|
||||||
import TabNav from '@/components/ui/Tabs/TabNav'
|
|
||||||
import TabContent from '@/components/ui/Tabs/TabContent'
|
|
||||||
import { GridOptionsSortModeEnum } from '@/proxy/form/models'
|
import { GridOptionsSortModeEnum } from '@/proxy/form/models'
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({})
|
const validationSchema = Yup.object().shape({})
|
||||||
|
|
||||||
|
|
@ -74,7 +62,7 @@ function FormTabSorting(props: FormEditProps) {
|
||||||
</Field>
|
</Field>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ function FormTabState(props: FormEditProps) {
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import {
|
||||||
Input,
|
Input,
|
||||||
Select,
|
Select,
|
||||||
toast,
|
toast,
|
||||||
Card,
|
|
||||||
} from '@/components/ui'
|
} from '@/components/ui'
|
||||||
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
||||||
import { useStoreState } from '@/store'
|
import { useStoreState } from '@/store'
|
||||||
|
|
@ -16,9 +15,9 @@ import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
import { FormEditProps } from './FormEdit'
|
import { FormEditProps } from './FormEdit'
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
import { SelectBoxOption } from '@/types/shared'
|
||||||
import { useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { getListFormFields } from '@/services/admin/list-form-field.service'
|
import { getListFormFields } from '@/services/admin/list-form-field.service'
|
||||||
import { groupBy } from 'lodash'
|
import groupBy from 'lodash/groupBy'
|
||||||
import { useParams } from 'react-router-dom'
|
import { useParams } from 'react-router-dom'
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({})
|
const validationSchema = Yup.object().shape({})
|
||||||
|
|
@ -28,7 +27,7 @@ function FormTabTree(props: FormEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
|
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
|
||||||
|
|
||||||
const getFields = async () => {
|
const getFields = useCallback(async () => {
|
||||||
if (!listFormCode) {
|
if (!listFormCode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -59,11 +58,11 @@ function FormTabTree(props: FormEditProps) {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}, [listFormCode])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getFields()
|
getFields()
|
||||||
}, [listFormCode])
|
}, [getFields])
|
||||||
|
|
||||||
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
||||||
if (!listFormValues) {
|
if (!listFormValues) {
|
||||||
|
|
@ -185,7 +184,7 @@ function FormTabTree(props: FormEditProps) {
|
||||||
component={Checkbox}
|
component={Checkbox}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit" className="my-2">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit" className="my-2">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import { FaEdit, FaFileMedical, FaTrash } from 'react-icons/fa'
|
||||||
import { JsonRowDialogData } from './json-row-operations/types'
|
import { JsonRowDialogData } from './json-row-operations/types'
|
||||||
import JsonRowOpDialogWidget from './json-row-operations/JsonRowOpDialogWidget'
|
import JsonRowOpDialogWidget from './json-row-operations/JsonRowOpDialogWidget'
|
||||||
|
|
||||||
function FormTabWidgets(props: { listFormCode: string }) {
|
function FormTabWidgets() {
|
||||||
const [isJsonRowOpDialogOpen, setIsJsonRowOpDialogOpen] = useState(false)
|
const [isJsonRowOpDialogOpen, setIsJsonRowOpDialogOpen] = useState(false)
|
||||||
const [jsonRowOpModalData, setJsonRowOpModalData] = useState<JsonRowDialogData>()
|
const [jsonRowOpModalData, setJsonRowOpModalData] = useState<JsonRowDialogData>()
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import { workflowService, type WorkflowCriteriaDto } from '@/services/workflow.s
|
||||||
import { WorkflowDesigner } from '../workflow/WorkflowDesigner'
|
import { WorkflowDesigner } from '../workflow/WorkflowDesigner'
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
import { SelectBoxOption } from '@/types/shared'
|
||||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import { Button, Card, Checkbox, FormContainer, FormItem, Input, Select } from '@/components/ui'
|
import { Button, Card, Checkbox, FormContainer, FormItem, Select } from '@/components/ui'
|
||||||
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
||||||
import { bool, object, string } from 'yup'
|
import { bool, object, string } from 'yup'
|
||||||
import { useStoreState } from '@/store/store'
|
import { useStoreState } from '@/store/store'
|
||||||
|
|
@ -450,7 +450,7 @@ export function FormTabWorkflow(
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" type="submit" loading={isSubmitting}>
|
<Button block size="sm" variant="solid" type="submit" loading={isSubmitting}>
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,10 @@ import { FormFieldEditProps } from './FormFields'
|
||||||
import FormFieldTabPivotSetting from './FormFieldTabPivotSetting'
|
import FormFieldTabPivotSetting from './FormFieldTabPivotSetting'
|
||||||
|
|
||||||
function FormFieldEdit({
|
function FormFieldEdit({
|
||||||
listFormCode,
|
|
||||||
item,
|
item,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
fields
|
fields,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
item: ColumnFormatEditDto | null
|
item: ColumnFormatEditDto | null
|
||||||
fields: ColumnFormatEditDto[]
|
fields: ColumnFormatEditDto[]
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
|
|
@ -74,114 +72,60 @@ function FormFieldEdit({
|
||||||
<TabNav value="pivotSetting">
|
<TabNav value="pivotSetting">
|
||||||
{translate('::ListForms.ListFormFieldEdit.TabPivotSettings')}
|
{translate('::ListForms.ListFormFieldEdit.TabPivotSettings')}
|
||||||
</TabNav>
|
</TabNav>
|
||||||
</TabList>
|
</TabList>
|
||||||
<div className="pt-4">
|
<div className="pt-4">
|
||||||
<TabContent value="details">
|
<TabContent value="details">
|
||||||
<FormFieldTabDetails
|
<FormFieldTabDetails initialValues={item} onSubmit={onSubmit} />
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="options">
|
<TabContent value="options">
|
||||||
<FormFieldTabOptions
|
<FormFieldTabOptions initialValues={item} onSubmit={onSubmit} />
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="permissions">
|
<TabContent value="permissions">
|
||||||
<FormFieldTabPermissions
|
<FormFieldTabPermissions initialValues={item} onSubmit={onSubmit} />
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="customization">
|
<TabContent value="customization">
|
||||||
<FormFieldTabCustomization
|
<FormFieldTabCustomization initialValues={item} onSubmit={onSubmit} />
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="filtering">
|
<TabContent value="filtering">
|
||||||
<FormFieldTabFiltering
|
<FormFieldTabFiltering initialValues={item} onSubmit={onSubmit} />
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="headering">
|
<TabContent value="headering">
|
||||||
<FormFieldTabHeadering
|
<FormFieldTabHeadering initialValues={item} onSubmit={onSubmit} />
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="grouping">
|
<TabContent value="grouping">
|
||||||
<FormFieldTabGrouping
|
<FormFieldTabGrouping initialValues={item} onSubmit={onSubmit} />
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="groupSummary">
|
<TabContent value="groupSummary">
|
||||||
<FormFieldTabGroupSummary
|
<FormFieldTabGroupSummary
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
initialValues={item}
|
||||||
onSubmit={onSubmit}
|
|
||||||
fields={fields}
|
fields={fields}
|
||||||
|
onSubmit={onSubmit}
|
||||||
/>
|
/>
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="totalSummary">
|
<TabContent value="totalSummary">
|
||||||
<FormFieldTabTotalSummary
|
<FormFieldTabTotalSummary
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
initialValues={item}
|
||||||
onSubmit={onSubmit}
|
|
||||||
fields={fields}
|
fields={fields}
|
||||||
|
onSubmit={onSubmit}
|
||||||
/>
|
/>
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="joinOptions">
|
<TabContent value="joinOptions">
|
||||||
<FormFieldTabJoinOptions
|
<FormFieldTabJoinOptions initialValues={item} onSubmit={onSubmit} />
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="lookup">
|
<TabContent value="lookup">
|
||||||
<FormFieldTabLookup
|
<FormFieldTabLookup initialValues={item} onSubmit={onSubmit} />
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="cssOptions">
|
<TabContent value="cssOptions">
|
||||||
<FormFieldTabCssOptions
|
<FormFieldTabCssOptions initialValues={item} onSubmit={onSubmit} />
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="validationRules">
|
<TabContent value="validationRules">
|
||||||
<FormFieldTabValidationRules
|
<FormFieldTabValidationRules initialValues={item} onSubmit={onSubmit} />
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="conditionalFormatting">
|
<TabContent value="conditionalFormatting">
|
||||||
<FormFieldTabConditionalFormatting
|
<FormFieldTabConditionalFormatting initialValues={item} onSubmit={onSubmit} />
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="pivotSetting">
|
<TabContent value="pivotSetting">
|
||||||
<FormFieldTabPivotSetting
|
<FormFieldTabPivotSetting initialValues={item} onSubmit={onSubmit} />
|
||||||
listFormCode={listFormCode}
|
|
||||||
initialValues={item}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
</div>
|
</div>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,9 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabConditionalFormatting({
|
function FormFieldTabConditionalFormatting({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
@ -219,7 +217,7 @@ function FormFieldTabConditionalFormatting({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, resetForm, values }) => (
|
{({ touched, errors, values }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<FormItem
|
<FormItem
|
||||||
|
|
@ -316,7 +314,7 @@ function FormFieldTabConditionalFormatting({
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isLoading} type="submit">
|
<Button block size="sm" variant="solid" loading={isLoading} type="submit">
|
||||||
{isLoading ? translate('::Saving') : translate('::Save')}
|
{isLoading ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,9 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabCssOptions({
|
function FormFieldTabCssOptions({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
@ -31,7 +29,7 @@ function FormFieldTabCssOptions({
|
||||||
await onSubmit(ListFormFieldEditTabs.CssOptionsForm, values, formikHelpers)
|
await onSubmit(ListFormFieldEditTabs.CssOptionsForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<FormItem
|
<FormItem
|
||||||
|
|
@ -63,7 +61,7 @@ function FormFieldTabCssOptions({
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" className="mt-1" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,9 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabCustomization({
|
function FormFieldTabCustomization({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
@ -39,7 +37,7 @@ function FormFieldTabCustomization({
|
||||||
await onSubmit(ListFormFieldEditTabs.CustomizationForm, values, formikHelpers)
|
await onSubmit(ListFormFieldEditTabs.CustomizationForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, isSubmitting, values }) => (
|
{({ isSubmitting, values }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<FormItem label={translate('::ListForms.ListFormFieldEdit.CustomizationFixed')}>
|
<FormItem label={translate('::ListForms.ListFormFieldEdit.CustomizationFixed')}>
|
||||||
|
|
@ -70,7 +68,7 @@ function FormFieldTabCustomization({
|
||||||
</Field>
|
</Field>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" className="mt-1" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,9 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabDetails({
|
function FormFieldTabDetails({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
@ -156,7 +154,7 @@ function FormFieldTabDetails({
|
||||||
onClose={() => setIsEditorOptionsDialogOpen(false)}
|
onClose={() => setIsEditorOptionsDialogOpen(false)}
|
||||||
onApply={(val) => setFieldValue('editorOptions', val)}
|
onApply={(val) => setFieldValue('editorOptions', val)}
|
||||||
/>
|
/>
|
||||||
<Button size="sm" className="mt-1" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,9 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabFiltering({
|
function FormFieldTabFiltering({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
@ -36,7 +34,7 @@ function FormFieldTabFiltering({
|
||||||
await onSubmit(ListFormFieldEditTabs.FilteringForm, values, formikHelpers)
|
await onSubmit(ListFormFieldEditTabs.FilteringForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<FormItem
|
<FormItem
|
||||||
|
|
@ -84,7 +82,7 @@ function FormFieldTabFiltering({
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" className="mt-1" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,10 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabGroupSummary({
|
function FormFieldTabGroupSummary({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
fields,
|
fields,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
fields: ColumnFormatEditDto[]
|
fields: ColumnFormatEditDto[]
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
|
|
@ -176,7 +174,7 @@ function FormFieldTabGroupSummary({
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,9 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabGrouping({
|
function FormFieldTabGrouping({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
@ -36,7 +34,7 @@ function FormFieldTabGrouping({
|
||||||
await onSubmit(ListFormFieldEditTabs.GroupingForm, values, formikHelpers)
|
await onSubmit(ListFormFieldEditTabs.GroupingForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<FormItem label={translate('::ListForms.ListFormFieldEdit.GroupingAllowGrouping')}>
|
<FormItem label={translate('::ListForms.ListFormFieldEdit.GroupingAllowGrouping')}>
|
||||||
|
|
@ -61,7 +59,7 @@ function FormFieldTabGrouping({
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" className="mt-1" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,9 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabHeadering({
|
function FormFieldTabHeadering({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
@ -36,7 +34,7 @@ function FormFieldTabHeadering({
|
||||||
await onSubmit(ListFormFieldEditTabs.HeaderingForm, values, formikHelpers)
|
await onSubmit(ListFormFieldEditTabs.HeaderingForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<FormItem
|
<FormItem
|
||||||
|
|
@ -65,7 +63,7 @@ function FormFieldTabHeadering({
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" className="mt-1" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { Container } from '@/components/shared'
|
import { Button, Card, FormItem, Input, Select } from '@/components/ui'
|
||||||
import { Button, Card, FormContainer, FormItem, Input, Select } from '@/components/ui'
|
|
||||||
import {
|
import {
|
||||||
ColumnFormatEditDto,
|
ColumnFormatEditDto,
|
||||||
GridColumnJoinConditionEnum,
|
GridColumnJoinConditionEnum,
|
||||||
|
|
@ -29,11 +28,9 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabJoinOptions({
|
function FormFieldTabJoinOptions({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
@ -234,7 +231,7 @@ function FormFieldTabJoinOptions({
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<Button size="sm" className="mt-1" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { Container } from '@/components/shared'
|
import { Button, Card, FormItem, Input, Select } from '@/components/ui'
|
||||||
import { Button, Card, Checkbox, FormContainer, FormItem, Input, Select } from '@/components/ui'
|
|
||||||
import { ColumnFormatEditDto, ListFormFieldEditTabs } from '@/proxy/admin/list-form-field/models'
|
import { ColumnFormatEditDto, ListFormFieldEditTabs } from '@/proxy/admin/list-form-field/models'
|
||||||
import type { DatabaseColumnDto, SqlObjectExplorerDto } from '@/proxy/sql-query-manager/models'
|
import type { DatabaseColumnDto, SqlObjectExplorerDto } from '@/proxy/sql-query-manager/models'
|
||||||
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
|
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
|
||||||
|
|
@ -70,11 +69,11 @@ function TablePickerModal({
|
||||||
{step === 'columns' && (
|
{step === 'columns' && (
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setStep('table')}
|
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="circle"
|
shape="circle"
|
||||||
icon={<FaArrowLeft className="text-xs" />}
|
icon={<FaArrowLeft className="text-xs" />}
|
||||||
className="!h-6 !w-6 !px-0 text-gray-400 transition-colors hover:!bg-transparent hover:text-indigo-500"
|
className="!h-6 !w-6 !px-0 text-gray-400 transition-colors hover:!bg-transparent hover:text-indigo-500"
|
||||||
|
onClick={() => setStep('table')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<span className="text-sm font-semibold text-gray-700 dark:text-gray-200">
|
<span className="text-sm font-semibold text-gray-700 dark:text-gray-200">
|
||||||
|
|
@ -85,11 +84,11 @@ function TablePickerModal({
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={onClose}
|
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="circle"
|
shape="circle"
|
||||||
icon={<FaTimes />}
|
icon={<FaTimes />}
|
||||||
className="!h-7 !w-7 !px-0 text-gray-400 hover:!bg-transparent hover:text-gray-600 dark:hover:text-gray-200"
|
className="!h-7 !w-7 !px-0 text-gray-400 hover:!bg-transparent hover:text-gray-600 dark:hover:text-gray-200"
|
||||||
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -100,9 +99,9 @@ function TablePickerModal({
|
||||||
<input
|
<input
|
||||||
autoFocus
|
autoFocus
|
||||||
value={tableSearch}
|
value={tableSearch}
|
||||||
onChange={(e) => setTableSearch(e.target.value)}
|
|
||||||
placeholder={translate('::Search') || 'Ara...'}
|
placeholder={translate('::Search') || 'Ara...'}
|
||||||
className="w-full text-xs px-2 py-1.5 rounded border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-800 text-gray-700 dark:text-gray-200 focus:outline-none focus:border-indigo-400"
|
className="w-full text-xs px-2 py-1.5 rounded border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-800 text-gray-700 dark:text-gray-200 focus:outline-none focus:border-indigo-400"
|
||||||
|
onChange={(e) => setTableSearch(e.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="overflow-y-auto flex-1 p-2">
|
<div className="overflow-y-auto flex-1 p-2">
|
||||||
|
|
@ -117,6 +116,9 @@ function TablePickerModal({
|
||||||
<Button
|
<Button
|
||||||
key={t.fullName}
|
key={t.fullName}
|
||||||
type="button"
|
type="button"
|
||||||
|
variant="plain"
|
||||||
|
shape="none"
|
||||||
|
className="w-full !h-auto !justify-start !rounded !px-3 !py-2 text-left font-mono text-xs text-gray-700 transition-colors hover:!bg-indigo-50 dark:text-gray-200 dark:hover:!bg-indigo-900/30"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setPickerTable(t)
|
setPickerTable(t)
|
||||||
setStep('columns')
|
setStep('columns')
|
||||||
|
|
@ -137,9 +139,6 @@ function TablePickerModal({
|
||||||
setIsLoadingColumns(false)
|
setIsLoadingColumns(false)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
variant="plain"
|
|
||||||
shape="none"
|
|
||||||
className="w-full !h-auto !justify-start !rounded !px-3 !py-2 text-left font-mono text-xs text-gray-700 transition-colors hover:!bg-indigo-50 dark:text-gray-200 dark:hover:!bg-indigo-900/30"
|
|
||||||
>
|
>
|
||||||
<span className="text-gray-400 mr-1">{t.schemaName}.</span>
|
<span className="text-gray-400 mr-1">{t.schemaName}.</span>
|
||||||
{t.tableName}
|
{t.tableName}
|
||||||
|
|
@ -165,8 +164,8 @@ function TablePickerModal({
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
value={keyCol}
|
value={keyCol}
|
||||||
onChange={(e) => setKeyCol(e.target.value)}
|
|
||||||
className="w-full text-xs h-8 px-2 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"
|
className="w-full text-xs h-8 px-2 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"
|
||||||
|
onChange={(e) => setKeyCol(e.target.value)}
|
||||||
>
|
>
|
||||||
<option value="">-- Seçiniz --</option>
|
<option value="">-- Seçiniz --</option>
|
||||||
{pickerColumns.map((c) => (
|
{pickerColumns.map((c) => (
|
||||||
|
|
@ -182,8 +181,8 @@ function TablePickerModal({
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
value={nameCol}
|
value={nameCol}
|
||||||
onChange={(e) => setNameCol(e.target.value)}
|
|
||||||
className="w-full text-xs h-8 px-2 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"
|
className="w-full text-xs h-8 px-2 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"
|
||||||
|
onChange={(e) => setNameCol(e.target.value)}
|
||||||
>
|
>
|
||||||
<option value="">-- Seçiniz --</option>
|
<option value="">-- Seçiniz --</option>
|
||||||
{pickerColumns.map((c) => (
|
{pickerColumns.map((c) => (
|
||||||
|
|
@ -204,8 +203,10 @@ function TablePickerModal({
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Button
|
<Button
|
||||||
|
block
|
||||||
type="button"
|
type="button"
|
||||||
disabled={!keyCol || !nameCol}
|
disabled={!keyCol || !nameCol}
|
||||||
|
variant="solid"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onSelect(
|
onSelect(
|
||||||
buildLookupQuery({
|
buildLookupQuery({
|
||||||
|
|
@ -216,8 +217,6 @@ function TablePickerModal({
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
block
|
|
||||||
variant="solid"
|
|
||||||
>
|
>
|
||||||
{translate('::OK')}
|
{translate('::OK')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -248,11 +247,9 @@ function getNormalizedInitialValues(initialValues: ColumnFormatEditDto) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function FormFieldTabLookup({
|
function FormFieldTabLookup({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
@ -317,11 +314,11 @@ function FormFieldTabLookup({
|
||||||
extra={
|
extra={
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={openTablePicker}
|
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="none"
|
shape="none"
|
||||||
icon={<FaPlus className="text-[8px]" />}
|
icon={<FaPlus className="text-[8px]" />}
|
||||||
className="ml-2 !h-auto !items-center gap-1 !rounded border border-indigo-200 bg-indigo-50 !px-1.5 !py-0.5 text-[10px] font-medium text-indigo-600 transition-colors hover:!bg-indigo-100 dark:border-indigo-700 dark:bg-indigo-900/20 dark:text-indigo-400 dark:hover:!bg-indigo-800/40"
|
className="ml-2 !h-auto !items-center gap-1 !rounded border border-indigo-200 bg-indigo-50 !px-1.5 !py-0.5 text-[10px] font-medium text-indigo-600 transition-colors hover:!bg-indigo-100 dark:border-indigo-700 dark:bg-indigo-900/20 dark:text-indigo-400 dark:hover:!bg-indigo-800/40"
|
||||||
|
onClick={openTablePicker}
|
||||||
>
|
>
|
||||||
{translate('::ListForms.Wizard.Step3.GenerateFromTable') || 'Tablodan Oluştur'}
|
{translate('::ListForms.Wizard.Step3.GenerateFromTable') || 'Tablodan Oluştur'}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -465,7 +462,7 @@ function FormFieldTabLookup({
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<Button size="sm" className="mt-1" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { Container } from '@/components/shared'
|
import { Button, Card, Checkbox, FormItem, Input, Select } from '@/components/ui'
|
||||||
import { Button, Card, Checkbox, FormContainer, FormItem, Input, Select } from '@/components/ui'
|
|
||||||
import { ColumnFormatEditDto, ListFormFieldEditTabs } from '@/proxy/admin/list-form-field/models'
|
import { ColumnFormatEditDto, ListFormFieldEditTabs } from '@/proxy/admin/list-form-field/models'
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
import { SelectBoxOption } from '@/types/shared'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
|
@ -22,11 +21,9 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabOptions({
|
function FormFieldTabOptions({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
@ -113,7 +110,7 @@ function FormFieldTabOptions({
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button size="sm" className="mt-1" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,9 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabPermissions({
|
function FormFieldTabPermissions({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
@ -159,7 +157,7 @@ function FormFieldTabPermissions({
|
||||||
<Field name="permissionDto.i" component={Checkbox} />
|
<Field name="permissionDto.i" component={Checkbox} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" className="mt-1" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { Container } from '@/components/shared'
|
import { Button, Card, Checkbox, FormItem, Select } from '@/components/ui'
|
||||||
import { Button, Card, Checkbox, FormContainer, FormItem, Input, Select } from '@/components/ui'
|
|
||||||
import { ColumnFormatEditDto, ListFormFieldEditTabs } from '@/proxy/admin/list-form-field/models'
|
import { ColumnFormatEditDto, ListFormFieldEditTabs } from '@/proxy/admin/list-form-field/models'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
|
|
@ -28,11 +27,9 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabPivotSetting({
|
function FormFieldTabPivotSetting({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
@ -214,7 +211,7 @@ function FormFieldTabPivotSetting({
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<Button size="sm" className="mt-1" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import { columnSummaryTypeListOptions } from '../options'
|
||||||
import { FormFieldEditProps } from './FormFields'
|
import { FormFieldEditProps } from './FormFields'
|
||||||
import { tooltipFormatListOptions } from '@/proxy/admin/list-form/options'
|
import { tooltipFormatListOptions } from '@/proxy/admin/list-form/options'
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
import { SelectBoxOption } from '@/types/shared'
|
||||||
import { useState } from 'react'
|
|
||||||
|
|
||||||
const schema = object().shape({
|
const schema = object().shape({
|
||||||
columnTotalSummaryDto: object()
|
columnTotalSummaryDto: object()
|
||||||
|
|
@ -24,12 +23,10 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabTotalSummary({
|
function FormFieldTabTotalSummary({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
fields,
|
fields,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
fields: ColumnFormatEditDto[]
|
fields: ColumnFormatEditDto[]
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
|
|
@ -177,7 +174,7 @@ function FormFieldTabTotalSummary({
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" className="mt-1" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -60,11 +60,9 @@ const schema = object().shape({
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabValidationRules({
|
function FormFieldTabValidationRules({
|
||||||
listFormCode,
|
|
||||||
initialValues,
|
initialValues,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
@ -229,7 +227,7 @@ function FormFieldTabValidationRules({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, resetForm, values }) => (
|
{({ touched, errors, values }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<FormItem
|
<FormItem
|
||||||
|
|
@ -355,7 +353,7 @@ function FormFieldTabValidationRules({
|
||||||
<Field name="trim" placeholder="Trim" component={Checkbox} />
|
<Field name="trim" placeholder="Trim" component={Checkbox} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" className="mt-1" block variant="solid" loading={isLoading} type="submit">
|
<Button block size="sm" className="mt-1" variant="solid" loading={isLoading} type="submit">
|
||||||
{isLoading ? translate('::Saving') : translate('::Save')}
|
{isLoading ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import setNull from '@/utils/setNull'
|
import setNull from '@/utils/setNull'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import { Field, FieldProps, Form, Formik, FormikHelpers } from 'formik'
|
import { Field, FieldProps, Form, Formik, FormikHelpers } from 'formik'
|
||||||
import { useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { FaFileMedical, FaCopy, FaEyeSlash, FaMinus, FaTimes, FaTable } from 'react-icons/fa'
|
import { FaFileMedical, FaCopy, FaEyeSlash, FaMinus, FaTimes, FaTable } from 'react-icons/fa'
|
||||||
import { number, object, string } from 'yup'
|
import { number, object, string } from 'yup'
|
||||||
import FormFieldEdit from './FormFieldEdit'
|
import FormFieldEdit from './FormFieldEdit'
|
||||||
|
|
@ -219,7 +219,7 @@ function FormFields({
|
||||||
await getFields()
|
await getFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFields = async (cultureName?: string, roleId?: string, userId?: string) => {
|
const getFields = useCallback(async (cultureName?: string, roleId?: string, userId?: string) => {
|
||||||
if (!listFormCode) {
|
if (!listFormCode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -254,11 +254,11 @@ function FormFields({
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}, [listFormCode])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getFields()
|
getFields()
|
||||||
}, [listFormCode])
|
}, [getFields])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!fields || !row) {
|
if (!fields || !row) {
|
||||||
|
|
@ -266,10 +266,10 @@ function FormFields({
|
||||||
}
|
}
|
||||||
|
|
||||||
const newRow = fields.find((f) => f.id === row.id)
|
const newRow = fields.find((f) => f.id === row.id)
|
||||||
if (newRow) {
|
if (newRow && newRow !== row) {
|
||||||
setRow(newRow)
|
setRow(newRow)
|
||||||
}
|
}
|
||||||
}, [fields])
|
}, [fields, row])
|
||||||
|
|
||||||
const onSubmit = async (
|
const onSubmit = async (
|
||||||
editType: string,
|
editType: string,
|
||||||
|
|
@ -390,7 +390,7 @@ function FormFields({
|
||||||
</Field>
|
</Field>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? '...' : translate('::ListForms.ListFormField.Filter')}
|
{isSubmitting ? '...' : translate('::ListForms.ListFormField.Filter')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
@ -454,14 +454,14 @@ function FormFields({
|
||||||
<TBody>
|
<TBody>
|
||||||
{fields.map((field) => (
|
{fields.map((field) => (
|
||||||
<Tr
|
<Tr
|
||||||
|
key={field.id}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'cursor-pointer',
|
'cursor-pointer',
|
||||||
field.id === row?.id ? 'bg-sozsoft-active dark:bg-gray-600' : '',
|
field.id === row?.id ? 'bg-sozsoft-active dark:bg-gray-600' : '',
|
||||||
)}
|
)}
|
||||||
onClick={(e: any) => {
|
onClick={() => {
|
||||||
setRow(field)
|
setRow(field)
|
||||||
}}
|
}}
|
||||||
key={field.id}
|
|
||||||
>
|
>
|
||||||
<Td className="flex items-center !p-0">
|
<Td className="flex items-center !p-0">
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -505,7 +505,7 @@ function FormFields({
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
<div className="2xl:col-span-3 lg:col-span-3 xl:col-span-2">
|
<div className="2xl:col-span-3 lg:col-span-3 xl:col-span-2">
|
||||||
<FormFieldEdit listFormCode={listFormCode} item={row} onSubmit={onSubmit} fields={fields} />
|
<FormFieldEdit item={row} fields={fields} onSubmit={onSubmit} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</AdaptableCard>
|
</AdaptableCard>
|
||||||
|
|
@ -684,7 +684,7 @@ function FormFields({
|
||||||
</Field>
|
</Field>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
@ -793,7 +793,7 @@ function FormFields({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, resetForm, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting, values }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size="sm">
|
<FormContainer size="sm">
|
||||||
<FormItem
|
<FormItem
|
||||||
|
|
@ -1023,7 +1023,7 @@ function FormFields({
|
||||||
<Field name="copiedFields.pivotSetting" component={Checkbox} className="mr-1" />
|
<Field name="copiedFields.pivotSetting" component={Checkbox} className="mr-1" />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
<Button size="sm" block variant="solid" loading={isSubmitting} type="submit">
|
<Button block size="sm" variant="solid" loading={isSubmitting} type="submit">
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Button, Dialog } from '@/components/ui'
|
import { Button, Dialog } from '@/components/ui'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
import { FaCheck, FaCode, FaPlus, FaSlidersH, FaTimes, FaTrash } from 'react-icons/fa'
|
import { FaCheck, FaCode, FaPlus, FaTimes, FaTrash } from 'react-icons/fa'
|
||||||
|
|
||||||
type CustomOption = {
|
type CustomOption = {
|
||||||
id: string
|
id: string
|
||||||
|
|
@ -295,51 +295,52 @@ function EditorOptionsBuilderDialog({
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={clearOptions}
|
|
||||||
title="editorOptions alanını boşaltır. Backend'e boş string kaydedilir."
|
title="editorOptions alanını boşaltır. Backend'e boş string kaydedilir."
|
||||||
|
onClick={clearOptions}
|
||||||
>
|
>
|
||||||
NULL / Empty
|
NULL / Empty
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => addPreset({ disabled: true })}
|
|
||||||
title='{"disabled": true} ekler.'
|
title='{"disabled": true} ekler.'
|
||||||
|
onClick={() => addPreset({ disabled: true })}
|
||||||
>
|
>
|
||||||
disabled
|
disabled
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => addPreset({ tooltip: { enabled: true } })}
|
|
||||||
title='{"tooltip": {"enabled": true}} ekler.'
|
title='{"tooltip": {"enabled": true}} ekler.'
|
||||||
|
onClick={() => addPreset({ tooltip: { enabled: true } })}
|
||||||
>
|
>
|
||||||
Tooltip
|
Tooltip
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => addPreset({ format: { type: 'fixedPoint', precision: 2 } })}
|
|
||||||
title="Ondalık format precision 2 ekler."
|
title="Ondalık format precision 2 ekler."
|
||||||
|
onClick={() => addPreset({ format: { type: 'fixedPoint', precision: 2 } })}
|
||||||
>
|
>
|
||||||
fixedPoint precision 2
|
fixedPoint precision 2
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
title="Pasif ve precision 2 fixedPoint formatını birlikte ekler."
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
addPreset({
|
addPreset({
|
||||||
disabled: true,
|
disabled: true,
|
||||||
format: { type: 'fixedPoint', precision: 2 },
|
format: { type: 'fixedPoint', precision: 2 },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
title="Pasif ve precision 2 fixedPoint formatını birlikte ekler."
|
|
||||||
>
|
>
|
||||||
disabled fixedPoint 2
|
disabled fixedPoint 2
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
title="Precision 1, mask behavior, spin buttons ve pasif ayarını ekler."
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
addPreset({
|
addPreset({
|
||||||
format: { type: 'fixedPoint', precision: 1 },
|
format: { type: 'fixedPoint', precision: 1 },
|
||||||
|
|
@ -348,13 +349,13 @@ function EditorOptionsBuilderDialog({
|
||||||
disabled: true,
|
disabled: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
title="Precision 1, mask behavior, spin buttons ve pasif ayarını ekler."
|
|
||||||
>
|
>
|
||||||
disabled fixedPoint 1
|
disabled fixedPoint 1
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
title="NumberBox için precision 2, mask behavior ve spin buttons ekler."
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
addPreset({
|
addPreset({
|
||||||
format: { type: 'fixedPoint', precision: 2 },
|
format: { type: 'fixedPoint', precision: 2 },
|
||||||
|
|
@ -362,34 +363,34 @@ function EditorOptionsBuilderDialog({
|
||||||
showSpinButtons: true,
|
showSpinButtons: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
title="NumberBox için precision 2, mask behavior ve spin buttons ekler."
|
|
||||||
>
|
>
|
||||||
numberSpin precision 2
|
numberSpin precision 2
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => addPreset({ format: 'dd/MM/yyyy', displayFormat: 'dd/MM/yyyy' })}
|
|
||||||
title="DateBox için gün/ay/yıl formatını ekler."
|
title="DateBox için gün/ay/yıl formatını ekler."
|
||||||
|
onClick={() => addPreset({ format: 'dd/MM/yyyy', displayFormat: 'dd/MM/yyyy' })}
|
||||||
>
|
>
|
||||||
date dd/MM/yyyy
|
date dd/MM/yyyy
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
title="DateBox için gün/ay/yıl saat:dakika formatını ekler."
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
addPreset({
|
addPreset({
|
||||||
format: 'dd/MM/yyyy HH:mm',
|
format: 'dd/MM/yyyy HH:mm',
|
||||||
displayFormat: 'dd/MM/yyyy HH:mm',
|
displayFormat: 'dd/MM/yyyy HH:mm',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
title="DateBox için gün/ay/yıl saat:dakika formatını ekler."
|
|
||||||
>
|
>
|
||||||
dateTime dd/MM/yyyy HH:mm
|
dateTime dd/MM/yyyy HH:mm
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
title="Telefon maskesi, yer tutucu ve Türkçe hata mesajı ekler."
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
addPreset({
|
addPreset({
|
||||||
format: 'phoneGlobal',
|
format: 'phoneGlobal',
|
||||||
|
|
@ -400,13 +401,13 @@ function EditorOptionsBuilderDialog({
|
||||||
placeholder: '(555) 123-4567',
|
placeholder: '(555) 123-4567',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
title="Telefon maskesi, yer tutucu ve Türkçe hata mesajı ekler."
|
|
||||||
>
|
>
|
||||||
phoneGlobal mask
|
phoneGlobal mask
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
title="Saat seçimi için dxDateBox time picker ayarları ekler."
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
addPreset({
|
addPreset({
|
||||||
type: 'time',
|
type: 'time',
|
||||||
|
|
@ -417,32 +418,31 @@ function EditorOptionsBuilderDialog({
|
||||||
width: '100%',
|
width: '100%',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
title="Saat seçimi için dxDateBox time picker ayarları ekler."
|
|
||||||
>
|
>
|
||||||
time picker
|
time picker
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => addPreset({ width: 80, height: 80, multiple: true })}
|
|
||||||
title="ImageUpload için 80x80 ve multiple ayarlarını ekler."
|
title="ImageUpload için 80x80 ve multiple ayarlarını ekler."
|
||||||
|
onClick={() => addPreset({ width: 80, height: 80, multiple: true })}
|
||||||
>
|
>
|
||||||
multi image
|
multi image
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="button" size="sm" onClick={() => addPreset({ height: 60 })} title='{"height": 60} ekler.'>
|
<Button type="button" size="sm" title='{"height": 60} ekler.' onClick={() => addPreset({ height: 60 })}>
|
||||||
Height 60
|
Height 60
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="button" size="sm" onClick={() => addPreset({ height: 100 })} title='{"height": 100} ekler.'>
|
<Button type="button" size="sm" title='{"height": 100} ekler.' onClick={() => addPreset({ height: 100 })}>
|
||||||
Height 100
|
Height 100
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="button" size="sm" onClick={() => addPreset({ height: 200 })} title='{"height": 200} ekler.'>
|
<Button type="button" size="sm" title='{"height": 200} ekler.' onClick={() => addPreset({ height: 200 })}>
|
||||||
Height 200
|
Height 200
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => addPreset(buildHtmlEditorOptions())}
|
|
||||||
title="HtmlEditor toolbar, image upload ve media resizing ayarlarını ekler."
|
title="HtmlEditor toolbar, image upload ve media resizing ayarlarını ekler."
|
||||||
|
onClick={() => addPreset(buildHtmlEditorOptions())}
|
||||||
>
|
>
|
||||||
htmlEditor toolbar
|
htmlEditor toolbar
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -451,12 +451,12 @@ function EditorOptionsBuilderDialog({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
|
preventScroll
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
width={1320}
|
width={1320}
|
||||||
height="88vh"
|
height="88vh"
|
||||||
contentClassName="flex flex-col"
|
contentClassName="flex flex-col"
|
||||||
style={{ overlay: { zIndex: 1300 } }}
|
style={{ overlay: { zIndex: 1300 } }}
|
||||||
preventScroll
|
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
onRequestClose={onClose}
|
onRequestClose={onClose}
|
||||||
>
|
>
|
||||||
|
|
@ -545,9 +545,9 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options.width)}
|
value={toInputValue(options.width)}
|
||||||
onChange={(event) => setOptionValue('width', event.target.value)}
|
|
||||||
placeholder="100% veya 240"
|
placeholder="100% veya 240"
|
||||||
title="Örnek: 100%, 240, 80"
|
title="Örnek: 100%, 240, 80"
|
||||||
|
onChange={(event) => setOptionValue('width', event.target.value)}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="text-xs text-gray-500">
|
<label className="text-xs text-gray-500">
|
||||||
|
|
@ -555,15 +555,15 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options.height)}
|
value={toInputValue(options.height)}
|
||||||
|
placeholder="200"
|
||||||
|
type="number"
|
||||||
|
title="Editor yüksekliği. Örnek: 60, 100, 200"
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setOptionValue(
|
setOptionValue(
|
||||||
'height',
|
'height',
|
||||||
event.target.value ? Number(event.target.value) : undefined,
|
event.target.value ? Number(event.target.value) : undefined,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
placeholder="200"
|
|
||||||
type="number"
|
|
||||||
title="Editor yüksekliği. Örnek: 60, 100, 200"
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="text-xs text-gray-500">
|
<label className="text-xs text-gray-500">
|
||||||
|
|
@ -571,9 +571,9 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options.placeholder)}
|
value={toInputValue(options.placeholder)}
|
||||||
onChange={(event) => setOptionValue('placeholder', event.target.value)}
|
|
||||||
placeholder="Placeholder"
|
placeholder="Placeholder"
|
||||||
title="Editor boşken görünecek metin."
|
title="Editor boşken görünecek metin."
|
||||||
|
onChange={(event) => setOptionValue('placeholder', event.target.value)}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -592,9 +592,9 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options.label)}
|
value={toInputValue(options.label)}
|
||||||
onChange={(event) => setOptionValue('label', event.target.value)}
|
|
||||||
placeholder="Alan etiketi"
|
placeholder="Alan etiketi"
|
||||||
title="Editor içi label metni."
|
title="Editor içi label metni."
|
||||||
|
onChange={(event) => setOptionValue('label', event.target.value)}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="text-xs text-gray-500">
|
<label className="text-xs text-gray-500">
|
||||||
|
|
@ -602,8 +602,8 @@ function EditorOptionsBuilderDialog({
|
||||||
<select
|
<select
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toSelectValue(options.labelMode)}
|
value={toSelectValue(options.labelMode)}
|
||||||
onChange={(event) => setOptionValue('labelMode', event.target.value)}
|
|
||||||
title="Label gösterim modu."
|
title="Label gösterim modu."
|
||||||
|
onChange={(event) => setOptionValue('labelMode', event.target.value)}
|
||||||
>
|
>
|
||||||
<option value="">Seç</option>
|
<option value="">Seç</option>
|
||||||
<option value="static">static</option>
|
<option value="static">static</option>
|
||||||
|
|
@ -617,8 +617,8 @@ function EditorOptionsBuilderDialog({
|
||||||
<select
|
<select
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toSelectValue(options.stylingMode)}
|
value={toSelectValue(options.stylingMode)}
|
||||||
onChange={(event) => setOptionValue('stylingMode', event.target.value)}
|
|
||||||
title="DevExtreme editor görünüm stili."
|
title="DevExtreme editor görünüm stili."
|
||||||
|
onChange={(event) => setOptionValue('stylingMode', event.target.value)}
|
||||||
>
|
>
|
||||||
<option value="">Seç</option>
|
<option value="">Seç</option>
|
||||||
<option value="outlined">outlined</option>
|
<option value="outlined">outlined</option>
|
||||||
|
|
@ -631,9 +631,9 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options.hint)}
|
value={toInputValue(options.hint)}
|
||||||
onChange={(event) => setOptionValue('hint', event.target.value)}
|
|
||||||
placeholder="Tooltip/hint metni"
|
placeholder="Tooltip/hint metni"
|
||||||
title="Editor üzerine gelince gösterilecek hint."
|
title="Editor üzerine gelince gösterilecek hint."
|
||||||
|
onChange={(event) => setOptionValue('hint', event.target.value)}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="text-xs text-gray-500">
|
<label className="text-xs text-gray-500">
|
||||||
|
|
@ -641,9 +641,9 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options.valueChangeEvent)}
|
value={toInputValue(options.valueChangeEvent)}
|
||||||
onChange={(event) => setOptionValue('valueChangeEvent', event.target.value)}
|
|
||||||
placeholder="change veya input"
|
placeholder="change veya input"
|
||||||
title="Değer değişimini tetikleyecek DOM event adı. Örnek: change, input, keyup."
|
title="Değer değişimini tetikleyecek DOM event adı. Örnek: change, input, keyup."
|
||||||
|
onChange={(event) => setOptionValue('valueChangeEvent', event.target.value)}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="text-xs text-gray-500">
|
<label className="text-xs text-gray-500">
|
||||||
|
|
@ -651,11 +651,11 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(getByPath(options, 'inputAttr.aria-label'))}
|
value={toInputValue(getByPath(options, 'inputAttr.aria-label'))}
|
||||||
|
placeholder="Erişilebilir ad"
|
||||||
|
title="Input için aria-label."
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setOptionPathValue('inputAttr.aria-label', event.target.value)
|
setOptionPathValue('inputAttr.aria-label', event.target.value)
|
||||||
}
|
}
|
||||||
placeholder="Erişilebilir ad"
|
|
||||||
title="Input için aria-label."
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -674,8 +674,8 @@ function EditorOptionsBuilderDialog({
|
||||||
<select
|
<select
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toSelectValue(options.mode)}
|
value={toSelectValue(options.mode)}
|
||||||
onChange={(event) => setOptionValue('mode', event.target.value)}
|
|
||||||
title="Input mode. TextBox/NumberBox için kullanılabilir."
|
title="Input mode. TextBox/NumberBox için kullanılabilir."
|
||||||
|
onChange={(event) => setOptionValue('mode', event.target.value)}
|
||||||
>
|
>
|
||||||
<option value="">Seç</option>
|
<option value="">Seç</option>
|
||||||
<option value="text">text</option>
|
<option value="text">text</option>
|
||||||
|
|
@ -692,15 +692,15 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options.maxLength)}
|
value={toInputValue(options.maxLength)}
|
||||||
|
placeholder="50"
|
||||||
|
type="number"
|
||||||
|
title="Maksimum karakter sayısı."
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setOptionValue(
|
setOptionValue(
|
||||||
'maxLength',
|
'maxLength',
|
||||||
event.target.value ? Number(event.target.value) : undefined,
|
event.target.value ? Number(event.target.value) : undefined,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
placeholder="50"
|
|
||||||
type="number"
|
|
||||||
title="Maksimum karakter sayısı."
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="text-xs text-gray-500">
|
<label className="text-xs text-gray-500">
|
||||||
|
|
@ -708,9 +708,9 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options.mask)}
|
value={toInputValue(options.mask)}
|
||||||
onChange={(event) => setOptionValue('mask', event.target.value)}
|
|
||||||
placeholder="(000) 000-0000"
|
placeholder="(000) 000-0000"
|
||||||
title="TextBox mask değeri."
|
title="TextBox mask değeri."
|
||||||
|
onChange={(event) => setOptionValue('mask', event.target.value)}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="text-xs text-gray-500">
|
<label className="text-xs text-gray-500">
|
||||||
|
|
@ -718,9 +718,9 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options.maskInvalidMessage)}
|
value={toInputValue(options.maskInvalidMessage)}
|
||||||
onChange={(event) => setOptionValue('maskInvalidMessage', event.target.value)}
|
|
||||||
placeholder="Geçerli değer girin"
|
placeholder="Geçerli değer girin"
|
||||||
title="Mask geçersiz olduğunda gösterilecek mesaj."
|
title="Mask geçersiz olduğunda gösterilecek mesaj."
|
||||||
|
onChange={(event) => setOptionValue('maskInvalidMessage', event.target.value)}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="text-xs text-gray-500">
|
<label className="text-xs text-gray-500">
|
||||||
|
|
@ -728,8 +728,8 @@ function EditorOptionsBuilderDialog({
|
||||||
<select
|
<select
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toSelectValue(options.showMaskMode)}
|
value={toSelectValue(options.showMaskMode)}
|
||||||
onChange={(event) => setOptionValue('showMaskMode', event.target.value)}
|
|
||||||
title="Mask ne zaman gösterilsin?"
|
title="Mask ne zaman gösterilsin?"
|
||||||
|
onChange={(event) => setOptionValue('showMaskMode', event.target.value)}
|
||||||
>
|
>
|
||||||
<option value="">Seç</option>
|
<option value="">Seç</option>
|
||||||
<option value="always">always</option>
|
<option value="always">always</option>
|
||||||
|
|
@ -741,9 +741,9 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(getByPath(options, 'maskRules.X'))}
|
value={toInputValue(getByPath(options, 'maskRules.X'))}
|
||||||
onChange={(event) => setOptionPathValue('maskRules.X', event.target.value)}
|
|
||||||
placeholder="[0-9]"
|
placeholder="[0-9]"
|
||||||
title="Custom mask rule. Örnek: X -> [0-9]"
|
title="Custom mask rule. Örnek: X -> [0-9]"
|
||||||
|
onChange={(event) => setOptionPathValue('maskRules.X', event.target.value)}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -763,15 +763,15 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options[key])}
|
value={toInputValue(options[key])}
|
||||||
|
placeholder={key === 'step' ? '1' : '0'}
|
||||||
|
type="number"
|
||||||
|
title={`${key} numeric option.`}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setOptionValue(
|
setOptionValue(
|
||||||
key,
|
key,
|
||||||
event.target.value ? Number(event.target.value) : undefined,
|
event.target.value ? Number(event.target.value) : undefined,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
placeholder={key === 'step' ? '1' : '0'}
|
|
||||||
type="number"
|
|
||||||
title={`${key} numeric option.`}
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
))}
|
))}
|
||||||
|
|
@ -780,8 +780,8 @@ function EditorOptionsBuilderDialog({
|
||||||
<select
|
<select
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toSelectValue(getByPath(options, 'format.type'))}
|
value={toSelectValue(getByPath(options, 'format.type'))}
|
||||||
onChange={(event) => setOptionPathValue('format.type', event.target.value)}
|
|
||||||
title="NumberBox format type."
|
title="NumberBox format type."
|
||||||
|
onChange={(event) => setOptionPathValue('format.type', event.target.value)}
|
||||||
>
|
>
|
||||||
<option value="">Seç</option>
|
<option value="">Seç</option>
|
||||||
<option value="fixedPoint">fixedPoint</option>
|
<option value="fixedPoint">fixedPoint</option>
|
||||||
|
|
@ -795,15 +795,15 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(getByPath(options, 'format.precision'))}
|
value={toInputValue(getByPath(options, 'format.precision'))}
|
||||||
|
placeholder="2"
|
||||||
|
type="number"
|
||||||
|
title="Ondalık hassasiyeti."
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setOptionPathValue(
|
setOptionPathValue(
|
||||||
'format.precision',
|
'format.precision',
|
||||||
event.target.value ? Number(event.target.value) : undefined,
|
event.target.value ? Number(event.target.value) : undefined,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
placeholder="2"
|
|
||||||
type="number"
|
|
||||||
title="Ondalık hassasiyeti."
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -822,8 +822,8 @@ function EditorOptionsBuilderDialog({
|
||||||
<select
|
<select
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toSelectValue(options.type)}
|
value={toSelectValue(options.type)}
|
||||||
onChange={(event) => setOptionValue('type', event.target.value)}
|
|
||||||
title="DateBox type."
|
title="DateBox type."
|
||||||
|
onChange={(event) => setOptionValue('type', event.target.value)}
|
||||||
>
|
>
|
||||||
<option value="">Seç</option>
|
<option value="">Seç</option>
|
||||||
<option value="date">date</option>
|
<option value="date">date</option>
|
||||||
|
|
@ -836,8 +836,8 @@ function EditorOptionsBuilderDialog({
|
||||||
<select
|
<select
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toSelectValue(options.pickerType)}
|
value={toSelectValue(options.pickerType)}
|
||||||
onChange={(event) => setOptionValue('pickerType', event.target.value)}
|
|
||||||
title="DateBox picker type."
|
title="DateBox picker type."
|
||||||
|
onChange={(event) => setOptionValue('pickerType', event.target.value)}
|
||||||
>
|
>
|
||||||
<option value="">Seç</option>
|
<option value="">Seç</option>
|
||||||
<option value="calendar">calendar</option>
|
<option value="calendar">calendar</option>
|
||||||
|
|
@ -851,9 +851,9 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options.displayFormat)}
|
value={toInputValue(options.displayFormat)}
|
||||||
onChange={(event) => setOptionValue('displayFormat', event.target.value)}
|
|
||||||
placeholder="dd/MM/yyyy veya HH:mm"
|
placeholder="dd/MM/yyyy veya HH:mm"
|
||||||
title="DateBox display format."
|
title="DateBox display format."
|
||||||
|
onChange={(event) => setOptionValue('displayFormat', event.target.value)}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="text-xs text-gray-500">
|
<label className="text-xs text-gray-500">
|
||||||
|
|
@ -861,11 +861,11 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options.dateSerializationFormat)}
|
value={toInputValue(options.dateSerializationFormat)}
|
||||||
|
placeholder="yyyy-MM-ddTHH:mm:ss"
|
||||||
|
title="Kaydedilecek date serialization format."
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setOptionValue('dateSerializationFormat', event.target.value)
|
setOptionValue('dateSerializationFormat', event.target.value)
|
||||||
}
|
}
|
||||||
placeholder="yyyy-MM-ddTHH:mm:ss"
|
|
||||||
title="Kaydedilecek date serialization format."
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="text-xs text-gray-500">
|
<label className="text-xs text-gray-500">
|
||||||
|
|
@ -873,15 +873,15 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options.interval)}
|
value={toInputValue(options.interval)}
|
||||||
|
placeholder="5"
|
||||||
|
type="number"
|
||||||
|
title="Time list aralığı dakika cinsinden."
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setOptionValue(
|
setOptionValue(
|
||||||
'interval',
|
'interval',
|
||||||
event.target.value ? Number(event.target.value) : undefined,
|
event.target.value ? Number(event.target.value) : undefined,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
placeholder="5"
|
|
||||||
type="number"
|
|
||||||
title="Time list aralığı dakika cinsinden."
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="text-xs text-gray-500">
|
<label className="text-xs text-gray-500">
|
||||||
|
|
@ -889,9 +889,9 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={toInputValue(options.invalidDateMessage)}
|
value={toInputValue(options.invalidDateMessage)}
|
||||||
onChange={(event) => setOptionValue('invalidDateMessage', event.target.value)}
|
|
||||||
placeholder="Geçerli tarih/saat girin"
|
placeholder="Geçerli tarih/saat girin"
|
||||||
title="Geçersiz tarih mesajı."
|
title="Geçersiz tarih mesajı."
|
||||||
|
onChange={(event) => setOptionValue('invalidDateMessage', event.target.value)}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -932,6 +932,8 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={`${baseInputClass} col-span-4`}
|
className={`${baseInputClass} col-span-4`}
|
||||||
value={option.path}
|
value={option.path}
|
||||||
|
placeholder="path.to.option"
|
||||||
|
title="Nokta ile nested path yaz. Örnek: toolbar.multiline"
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setCustomOptions((current) =>
|
setCustomOptions((current) =>
|
||||||
current.map((item) =>
|
current.map((item) =>
|
||||||
|
|
@ -939,8 +941,6 @@ function EditorOptionsBuilderDialog({
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
placeholder="path.to.option"
|
|
||||||
title="Nokta ile nested path yaz. Örnek: toolbar.multiline"
|
|
||||||
/>
|
/>
|
||||||
<select
|
<select
|
||||||
className={`${baseInputClass} col-span-2`}
|
className={`${baseInputClass} col-span-2`}
|
||||||
|
|
@ -963,6 +963,8 @@ function EditorOptionsBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={`${baseInputClass} col-span-5`}
|
className={`${baseInputClass} col-span-5`}
|
||||||
value={option.value}
|
value={option.value}
|
||||||
|
placeholder={option.type === 'boolean' ? 'true / false' : 'value'}
|
||||||
|
title="Tip JSON ise object/array yazabilirsin. Tip boolean ise true veya false yaz."
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setCustomOptions((current) =>
|
setCustomOptions((current) =>
|
||||||
current.map((item) =>
|
current.map((item) =>
|
||||||
|
|
@ -970,8 +972,6 @@ function EditorOptionsBuilderDialog({
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
placeholder={option.type === 'boolean' ? 'true / false' : 'value'}
|
|
||||||
title="Tip JSON ise object/array yazabilirsin. Tip boolean ise true veya false yaz."
|
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { SelectBoxOption } from '@/types/shared'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import Editor from '@monaco-editor/react'
|
import Editor from '@monaco-editor/react'
|
||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
import { FaBolt, FaCheck, FaCode, FaMagic, FaPlus, FaTimes, FaTrash } from 'react-icons/fa'
|
import { FaCheck, FaCode, FaMagic, FaPlus, FaTimes, FaTrash } from 'react-icons/fa'
|
||||||
|
|
||||||
type CopyMapping = {
|
type CopyMapping = {
|
||||||
id: string
|
id: string
|
||||||
|
|
@ -597,12 +597,6 @@ function EditorScriptBuilderDialog({
|
||||||
setAmountTotalField((current) => current || findField('TotalAmount'))
|
setAmountTotalField((current) => current || findField('TotalAmount'))
|
||||||
}
|
}
|
||||||
|
|
||||||
const fillTimeDefaults = () => {
|
|
||||||
setTimeStartField((current) => current || findField('StartTime'))
|
|
||||||
setTimeEndField((current) => current || findField('EndTime'))
|
|
||||||
setTimeTargetField((current) => current || findField('TotalHours'))
|
|
||||||
}
|
|
||||||
|
|
||||||
const resetBuilderSelections = () => {
|
const resetBuilderSelections = () => {
|
||||||
setCopyMappings([])
|
setCopyMappings([])
|
||||||
setDaysStartField('')
|
setDaysStartField('')
|
||||||
|
|
@ -834,12 +828,12 @@ function EditorScriptBuilderDialog({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
|
preventScroll
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
width={1100}
|
width={1100}
|
||||||
height="82vh"
|
height="82vh"
|
||||||
contentClassName="flex flex-col"
|
contentClassName="flex flex-col"
|
||||||
style={{ overlay: { zIndex: 1300 } }}
|
style={{ overlay: { zIndex: 1300 } }}
|
||||||
preventScroll
|
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
onRequestClose={onClose}
|
onRequestClose={onClose}
|
||||||
>
|
>
|
||||||
|
|
@ -898,6 +892,8 @@ function EditorScriptBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={mapping.source}
|
value={mapping.source}
|
||||||
|
placeholder="Örn: unitPrice veya Customer.Name"
|
||||||
|
title="Seçilen kayıttaki kolon/path. Örnek: Quantity, UnitPrice, Customer.Name"
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setCopyMappings((current) =>
|
setCopyMappings((current) =>
|
||||||
current.map((item) =>
|
current.map((item) =>
|
||||||
|
|
@ -907,8 +903,6 @@ function EditorScriptBuilderDialog({
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
placeholder="Örn: unitPrice veya Customer.Name"
|
|
||||||
title="Seçilen kayıttaki kolon/path. Örnek: Quantity, UnitPrice, Customer.Name"
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<div className="col-span-12 md:col-span-5">
|
<div className="col-span-12 md:col-span-5">
|
||||||
|
|
@ -1012,11 +1006,11 @@ function EditorScriptBuilderDialog({
|
||||||
action.operator === 'empty' ||
|
action.operator === 'empty' ||
|
||||||
action.operator === 'notEmpty'
|
action.operator === 'notEmpty'
|
||||||
}
|
}
|
||||||
|
placeholder="Örn: Aktif, 1000"
|
||||||
|
title="Koşulda kullanılacak sabit değer. Örnek: Aktif, 0, True"
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
updateConditionalAction(action.id, { value: event.target.value })
|
updateConditionalAction(action.id, { value: event.target.value })
|
||||||
}
|
}
|
||||||
placeholder="Örn: Aktif, 1000"
|
|
||||||
title="Koşulda kullanılacak sabit değer. Örnek: Aktif, 0, True"
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<div className={actionIconCellClass}>
|
<div className={actionIconCellClass}>
|
||||||
|
|
@ -1054,7 +1048,7 @@ function EditorScriptBuilderDialog({
|
||||||
<option value="confirm">Onay iste</option>
|
<option value="confirm">Onay iste</option>
|
||||||
<option value="calculate">Formül hesapla</option>
|
<option value="calculate">Formül hesapla</option>
|
||||||
<option value="setReadOnly">ReadOnly ayarla</option>
|
<option value="setReadOnly">ReadOnly ayarla</option>
|
||||||
<option value="apiToField">API sonucunu field'a yaz</option>
|
<option value="apiToField">API sonucunu field'a yaz</option>
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
|
@ -1077,11 +1071,11 @@ function EditorScriptBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={action.textValue}
|
value={action.textValue}
|
||||||
|
placeholder="text, {Field} or {selected.Name}"
|
||||||
|
title="Sabit metin veya token yaz. Örnek: {Name}, {value}, {selected.DisplayName}"
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
updateConditionalAction(action.id, { textValue: event.target.value })
|
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>
|
</label>
|
||||||
)}
|
)}
|
||||||
|
|
@ -1129,11 +1123,11 @@ function EditorScriptBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={action.apiUrl}
|
value={action.apiUrl}
|
||||||
|
placeholder="/api/path/{Id}"
|
||||||
|
title="Token kullanabilirsin: /api/orders/{OrderId}, /api/x/{selected.Id}, /api/y/{value}"
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
updateConditionalAction(action.id, { apiUrl: event.target.value })
|
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>
|
||||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-3`}>
|
<label className={`${fieldLabelClass} col-span-12 md:col-span-3`}>
|
||||||
|
|
@ -1141,13 +1135,13 @@ function EditorScriptBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={action.responsePath}
|
value={action.responsePath}
|
||||||
|
placeholder="data.value"
|
||||||
|
title="API JSON cevabından okunacak path. Boş bırakırsan tüm JSON hedef field'a yazılır."
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
updateConditionalAction(action.id, {
|
updateConditionalAction(action.id, {
|
||||||
responsePath: event.target.value,
|
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>
|
</label>
|
||||||
</>
|
</>
|
||||||
|
|
@ -1160,13 +1154,13 @@ function EditorScriptBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={action.textValue}
|
value={action.textValue}
|
||||||
|
placeholder="/report?id={Id}&type={selected.Type}"
|
||||||
|
title="Açılacak URL. Token destekler: {Id}, {value}, {selected.Type}"
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
updateConditionalAction(action.id, {
|
updateConditionalAction(action.id, {
|
||||||
textValue: event.target.value,
|
textValue: event.target.value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
placeholder="/report?id={Id}&type={selected.Type}"
|
|
||||||
title="Açılacak URL. Token destekler: {Id}, {value}, {selected.Type}"
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className={`${fieldLabelClass} col-span-12 md:col-span-2`}>
|
<label className={`${fieldLabelClass} col-span-12 md:col-span-2`}>
|
||||||
|
|
@ -1194,11 +1188,11 @@ function EditorScriptBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={action.message}
|
value={action.message}
|
||||||
|
placeholder="{Field} tokenları ile mesaj"
|
||||||
|
title="Alert/confirm mesajı. Token destekler: {Name}, {value}, {selected.Name}"
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
updateConditionalAction(action.id, { message: event.target.value })
|
updateConditionalAction(action.id, { message: event.target.value })
|
||||||
}
|
}
|
||||||
placeholder="{Field} tokenları ile mesaj"
|
|
||||||
title="Alert/confirm mesajı. Token destekler: {Name}, {value}, {selected.Name}"
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
)}
|
)}
|
||||||
|
|
@ -1209,11 +1203,11 @@ function EditorScriptBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={action.formula}
|
value={action.formula}
|
||||||
|
placeholder="Number(data.Quantity || 0) * Number(data.UnitPrice || 0)"
|
||||||
|
title="JavaScript expression yaz. data=formData, selected=selectedItem, value=e.value olarak kullanılır."
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
updateConditionalAction(action.id, { formula: event.target.value })
|
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>
|
</label>
|
||||||
)}
|
)}
|
||||||
|
|
@ -1292,9 +1286,9 @@ function EditorScriptBuilderDialog({
|
||||||
<input
|
<input
|
||||||
className={baseInputClass}
|
className={baseInputClass}
|
||||||
value={serviceCall}
|
value={serviceCall}
|
||||||
onChange={(event) => setServiceCall(event.target.value)}
|
|
||||||
placeholder="UiEvalService.ApiGenerateBackgroundWorkers();"
|
placeholder="UiEvalService.ApiGenerateBackgroundWorkers();"
|
||||||
title="Global servis çağrısı. Örnek: UiEvalService.ApiGenerateBackgroundWorkers();"
|
title="Global servis çağrısı. Örnek: UiEvalService.ApiGenerateBackgroundWorkers();"
|
||||||
|
onChange={(event) => setServiceCall(event.target.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -1340,7 +1334,6 @@ function EditorScriptBuilderDialog({
|
||||||
language="typescript"
|
language="typescript"
|
||||||
theme="vs-dark"
|
theme="vs-dark"
|
||||||
value={scriptEditorValue}
|
value={scriptEditorValue}
|
||||||
onChange={(nextValue) => setScriptEditorValue(nextValue || '')}
|
|
||||||
options={{
|
options={{
|
||||||
automaticLayout: true,
|
automaticLayout: true,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
|
@ -1349,6 +1342,7 @@ function EditorScriptBuilderDialog({
|
||||||
tabSize: 2,
|
tabSize: 2,
|
||||||
wordWrap: 'on',
|
wordWrap: 'on',
|
||||||
}}
|
}}
|
||||||
|
onChange={(nextValue) => setScriptEditorValue(nextValue || '')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -88,10 +88,10 @@ function JsonRowOpDialogAnnotation({
|
||||||
id="annotationOperation"
|
id="annotationOperation"
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
preventScroll={true}
|
preventScroll={true}
|
||||||
onClose={handleClose}
|
|
||||||
onRequestClose={handleClose}
|
|
||||||
width={900}
|
width={900}
|
||||||
height="90vh"
|
height="90vh"
|
||||||
|
onClose={handleClose}
|
||||||
|
onRequestClose={handleClose}
|
||||||
>
|
>
|
||||||
{(data.operation === 'create' || data.operation === 'update') && (
|
{(data.operation === 'create' || data.operation === 'update') && (
|
||||||
<Formik
|
<Formik
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import { useStoreActions } from '@/store'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { Field, FieldArray, FieldProps, Form, Formik } from 'formik'
|
import { Field, FieldArray, FieldProps, Form, Formik } from 'formik'
|
||||||
import groupBy from 'lodash/groupBy'
|
import groupBy from 'lodash/groupBy'
|
||||||
import { Dispatch, SetStateAction, useEffect, useState } from 'react'
|
import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'
|
||||||
import { FaBolt, FaCalendarMinus, FaCalendarPlus, FaSlidersH, FaTag } from 'react-icons/fa'
|
import { FaBolt, FaCalendarMinus, FaCalendarPlus, FaSlidersH, FaTag } from 'react-icons/fa'
|
||||||
import { number, object, string } from 'yup'
|
import { number, object, string } from 'yup'
|
||||||
import {
|
import {
|
||||||
|
|
@ -82,7 +82,7 @@ function JsonRowOpDialogEditForm({
|
||||||
const [scriptBuilderIndex, setScriptBuilderIndex] = useState<number | null>(null)
|
const [scriptBuilderIndex, setScriptBuilderIndex] = useState<number | null>(null)
|
||||||
const [isHelperOpen, setIsHelperOpen] = useState(false)
|
const [isHelperOpen, setIsHelperOpen] = useState(false)
|
||||||
|
|
||||||
const getFields = async () => {
|
const getFields = useCallback(async () => {
|
||||||
if (!listFormCode) {
|
if (!listFormCode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +113,7 @@ function JsonRowOpDialogEditForm({
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}, [listFormCode])
|
||||||
|
|
||||||
const handleClose = async (e?: any) => {
|
const handleClose = async (e?: any) => {
|
||||||
if (e) {
|
if (e) {
|
||||||
|
|
@ -133,7 +133,7 @@ function JsonRowOpDialogEditForm({
|
||||||
if (isOpen && data) {
|
if (isOpen && data) {
|
||||||
getFields()
|
getFields()
|
||||||
}
|
}
|
||||||
}, [isOpen, data])
|
}, [isOpen, data, getFields])
|
||||||
|
|
||||||
if (!data || !fieldList?.length) {
|
if (!data || !fieldList?.length) {
|
||||||
return null
|
return null
|
||||||
|
|
@ -279,10 +279,10 @@ function JsonRowOpDialogEditForm({
|
||||||
|
|
||||||
<Dialog
|
<Dialog
|
||||||
isOpen={isHelperOpen}
|
isOpen={isHelperOpen}
|
||||||
onClose={() => setIsHelperOpen(false)}
|
|
||||||
onRequestClose={() => setIsHelperOpen(false)}
|
|
||||||
preventScroll={true}
|
preventScroll={true}
|
||||||
width={1000}
|
width={1000}
|
||||||
|
onClose={() => setIsHelperOpen(false)}
|
||||||
|
onRequestClose={() => setIsHelperOpen(false)}
|
||||||
>
|
>
|
||||||
<h5 className="mb-4">Helper</h5>
|
<h5 className="mb-4">Helper</h5>
|
||||||
|
|
||||||
|
|
@ -396,11 +396,11 @@ function JsonRowOpDialogEditForm({
|
||||||
)
|
)
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
menuPlacement="auto"
|
||||||
|
maxMenuHeight={150}
|
||||||
onChange={(option) =>
|
onChange={(option) =>
|
||||||
form.setFieldValue(field.name, option?.value)
|
form.setFieldValue(field.name, option?.value)
|
||||||
}
|
}
|
||||||
menuPlacement="auto"
|
|
||||||
maxMenuHeight={150}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
|
|
@ -422,12 +422,12 @@ function JsonRowOpDialogEditForm({
|
||||||
(option) =>
|
(option) =>
|
||||||
option.value === values.items?.at(index)?.editorType2,
|
option.value === values.items?.at(index)?.editorType2,
|
||||||
)}
|
)}
|
||||||
onChange={(option) =>
|
|
||||||
form.setFieldValue(field.name, option?.value)
|
|
||||||
}
|
|
||||||
className="flex-1"
|
className="flex-1"
|
||||||
menuPlacement="auto"
|
menuPlacement="auto"
|
||||||
maxMenuHeight={150}
|
maxMenuHeight={150}
|
||||||
|
onChange={(option) =>
|
||||||
|
form.setFieldValue(field.name, option?.value)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ import {
|
||||||
} from '@/components/ui'
|
} from '@/components/ui'
|
||||||
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 } from '@/store'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import { Dispatch, SetStateAction, useEffect, useState } from 'react'
|
import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'
|
||||||
import { object, string } from 'yup'
|
import { object, string } from 'yup'
|
||||||
import { JsonRowDialogData } from './types'
|
import { JsonRowDialogData } from './types'
|
||||||
import {
|
import {
|
||||||
|
|
@ -22,10 +22,10 @@ import {
|
||||||
postListFormJsonRow,
|
postListFormJsonRow,
|
||||||
putListFormJsonRow,
|
putListFormJsonRow,
|
||||||
} from '@/services/admin/list-form.service'
|
} from '@/services/admin/list-form.service'
|
||||||
import { cascadeFilterOperator, colSpanOptions } from '../options'
|
import { cascadeFilterOperator } from '../options'
|
||||||
import CreatableSelect from 'react-select/creatable'
|
import CreatableSelect from 'react-select/creatable'
|
||||||
import { getListFormFields } from '@/services/admin/list-form-field.service'
|
import { getListFormFields } from '@/services/admin/list-form-field.service'
|
||||||
import { groupBy } from 'lodash'
|
import groupBy from 'lodash/groupBy'
|
||||||
import { extraFilterControlTypeOptions } from '@/proxy/admin/list-form/options'
|
import { extraFilterControlTypeOptions } from '@/proxy/admin/list-form/options'
|
||||||
|
|
||||||
const schema = object().shape({
|
const schema = object().shape({
|
||||||
|
|
@ -73,7 +73,7 @@ function JsonRowOpDialogExtraFilter({
|
||||||
setIsOpen(false)
|
setIsOpen(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFields = async () => {
|
const getFields = useCallback(async () => {
|
||||||
if (!listFormCode) {
|
if (!listFormCode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -104,13 +104,13 @@ function JsonRowOpDialogExtraFilter({
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}, [listFormCode])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOpen && data) {
|
if (isOpen && data) {
|
||||||
getFields()
|
getFields()
|
||||||
}
|
}
|
||||||
}, [isOpen, data])
|
}, [isOpen, data, getFields])
|
||||||
|
|
||||||
if (!data || !fieldList?.length) {
|
if (!data || !fieldList?.length) {
|
||||||
return null
|
return null
|
||||||
|
|
@ -121,9 +121,9 @@ function JsonRowOpDialogExtraFilter({
|
||||||
id="extraFilterOperation"
|
id="extraFilterOperation"
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
preventScroll={true}
|
preventScroll={true}
|
||||||
|
width={data.operation === 'create' || data.operation === 'update' ? 'sm' : '450px'}
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
onRequestClose={handleClose}
|
onRequestClose={handleClose}
|
||||||
width={data.operation === 'create' || data.operation === 'update' ? 'sm' : '450px'}
|
|
||||||
>
|
>
|
||||||
{(data.operation === 'create' || data.operation === 'update') && (
|
{(data.operation === 'create' || data.operation === 'update') && (
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,13 @@ import {
|
||||||
FormItem,
|
FormItem,
|
||||||
Input,
|
Input,
|
||||||
Notification,
|
Notification,
|
||||||
Select,
|
|
||||||
Tabs,
|
|
||||||
toast,
|
toast,
|
||||||
} from '@/components/ui'
|
} from '@/components/ui'
|
||||||
import { ListFormJsonRowDto } from '@/proxy/admin/list-form/models'
|
import { ListFormJsonRowDto } from '@/proxy/admin/list-form/models'
|
||||||
import { useStoreActions } from '@/store'
|
import { useStoreActions } from '@/store'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import { Dispatch, SetStateAction, useEffect, useState } from 'react'
|
import { Dispatch, SetStateAction } from 'react'
|
||||||
import { number, object, string } from 'yup'
|
import { number, object, string } from 'yup'
|
||||||
import { JsonRowDialogData } from './types'
|
import { JsonRowDialogData } from './types'
|
||||||
import {
|
import {
|
||||||
|
|
@ -114,7 +112,7 @@ function JsonRowOpDialogPane({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, values, isSubmitting }) => (
|
{({ touched, errors, isSubmitting }) => (
|
||||||
<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-2">
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import { SelectBoxOption } from '@/types/shared'
|
||||||
import { useStoreActions, useStoreState } from '@/store'
|
import { useStoreActions, useStoreState } from '@/store'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import { Dispatch, SetStateAction, useEffect, useState } from 'react'
|
import { Dispatch, SetStateAction } from 'react'
|
||||||
import { boolean, number, object, string } from 'yup'
|
import { boolean, number, object, string } from 'yup'
|
||||||
import { JsonRowDialogData } from './types'
|
import { JsonRowDialogData } from './types'
|
||||||
import {
|
import {
|
||||||
|
|
@ -30,7 +30,6 @@ import {
|
||||||
columnSummaryTypeListOptions,
|
columnSummaryTypeListOptions,
|
||||||
} from '../options'
|
} from '../options'
|
||||||
import { ChartPanesDto, ChartValueAxisDto } from '@/proxy/admin/charts/models'
|
import { ChartPanesDto, ChartValueAxisDto } from '@/proxy/admin/charts/models'
|
||||||
import CreatableSelect from 'react-select/creatable'
|
|
||||||
import { tooltipFormatListOptions } from '@/proxy/admin/list-form/options'
|
import { tooltipFormatListOptions } from '@/proxy/admin/list-form/options'
|
||||||
|
|
||||||
const schema = object().shape({
|
const schema = object().shape({
|
||||||
|
|
@ -129,10 +128,10 @@ function JsonRowOpDialogSeries({
|
||||||
id="paneOperation"
|
id="paneOperation"
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
preventScroll={true}
|
preventScroll={true}
|
||||||
onClose={handleClose}
|
|
||||||
onRequestClose={handleClose}
|
|
||||||
width={900}
|
width={900}
|
||||||
height="90vh"
|
height="90vh"
|
||||||
|
onClose={handleClose}
|
||||||
|
onRequestClose={handleClose}
|
||||||
>
|
>
|
||||||
{(data.operation === 'create' || data.operation === 'update') && (
|
{(data.operation === 'create' || data.operation === 'update') && (
|
||||||
<Formik
|
<Formik
|
||||||
|
|
@ -282,9 +281,9 @@ function JsonRowOpDialogSeries({
|
||||||
value={fieldList?.find(
|
value={fieldList?.find(
|
||||||
(option) => option.value === values.argumentField,
|
(option) => option.value === values.argumentField,
|
||||||
)}
|
)}
|
||||||
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
|
||||||
menuPlacement="auto"
|
menuPlacement="auto"
|
||||||
maxMenuHeight={150}
|
maxMenuHeight={150}
|
||||||
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
|
|
@ -303,9 +302,9 @@ function JsonRowOpDialogSeries({
|
||||||
isClearable={true}
|
isClearable={true}
|
||||||
options={fieldList}
|
options={fieldList}
|
||||||
value={fieldList?.find((option) => option.value === values.valueField)}
|
value={fieldList?.find((option) => option.value === values.valueField)}
|
||||||
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
|
||||||
menuPlacement="auto"
|
menuPlacement="auto"
|
||||||
maxMenuHeight={150}
|
maxMenuHeight={150}
|
||||||
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ function JsonRowOpDialogSubForm({
|
||||||
}
|
}
|
||||||
|
|
||||||
loadData()
|
loadData()
|
||||||
}, [isOpen, listFormValues?.listFormCode])
|
}, [isOpen, listFormValues?.listFormCode, translate])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@ import {
|
||||||
import SqlEditor from '@/views/developerKit/SqlEditor'
|
import SqlEditor from '@/views/developerKit/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 } from '@/store'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import { Dispatch, SetStateAction, useEffect, useState } from 'react'
|
import { Dispatch, SetStateAction } from 'react'
|
||||||
import { number, object, string } from 'yup'
|
import { number, object, string } from 'yup'
|
||||||
import { JsonRowDialogData } from './types'
|
import { JsonRowDialogData } from './types'
|
||||||
import {
|
import {
|
||||||
|
|
@ -77,10 +77,10 @@ function JsonRowOpDialogWidget({
|
||||||
id="widgetOperation"
|
id="widgetOperation"
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
preventScroll={true}
|
preventScroll={true}
|
||||||
onClose={handleClose}
|
|
||||||
onRequestClose={handleClose}
|
|
||||||
width={data.operation === 'create' || data.operation === 'update' ? 900 : 450}
|
width={data.operation === 'create' || data.operation === 'update' ? 900 : 450}
|
||||||
height="90vh"
|
height="90vh"
|
||||||
|
onClose={handleClose}
|
||||||
|
onRequestClose={handleClose}
|
||||||
>
|
>
|
||||||
{(data.operation === 'create' || data.operation === 'update') && (
|
{(data.operation === 'create' || data.operation === 'update') && (
|
||||||
<Formik
|
<Formik
|
||||||
|
|
@ -243,13 +243,9 @@ function JsonRowOpDialogWidget({
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div>
|
<div>
|
||||||
<code className="text-xs bg-gray-800 p-1 rounded block mt-1">
|
<code className="text-xs bg-gray-800 p-1 rounded block mt-1">
|
||||||
SELECT 'Aktif' as title, COUNT(Id) as value,
|
{
|
||||||
<br />
|
"SELECT 'Aktif' as title, COUNT(Id) as value, 'blue' as color, 'FaChartBar' as icon, 'Aktif kayıtlar' as subTitle FROM YourTable WHERE IsActive = 1"
|
||||||
'blue' as color, 'FaChartBar' as icon,
|
}
|
||||||
<br />
|
|
||||||
'Aktif kayıtlar' as subTitle
|
|
||||||
<br />
|
|
||||||
FROM YourTable WHERE IsActive = 1
|
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -269,8 +265,8 @@ function JsonRowOpDialogWidget({
|
||||||
>
|
>
|
||||||
<SqlEditor
|
<SqlEditor
|
||||||
value={values.sqlQuery || ''}
|
value={values.sqlQuery || ''}
|
||||||
onChange={(value) => setFieldValue('sqlQuery', value || '')}
|
|
||||||
height="35vh"
|
height="35vh"
|
||||||
|
onChange={(value) => setFieldValue('sqlQuery', value || '')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import { useLocation, useNavigate } from 'react-router-dom'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
import { getMenus } from '@/services/menu.service'
|
import { getMenus } from '@/services/menu.service'
|
||||||
import { getPermissions } from '@/services/identity.service'
|
import { getPermissions } from '@/services/identity.service'
|
||||||
import { DbTypeEnum, SelectCommandTypeEnum } from '@/proxy/form/models'
|
|
||||||
import { getDataSources } from '@/services/data-source.service'
|
import { getDataSources } from '@/services/data-source.service'
|
||||||
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
|
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
|
||||||
import type { SqlObjectExplorerDto, DatabaseColumnDto } from '@/proxy/sql-query-manager/models'
|
import type { SqlObjectExplorerDto, DatabaseColumnDto } from '@/proxy/sql-query-manager/models'
|
||||||
|
|
@ -32,13 +31,15 @@ import { Container } from '@/components/shared'
|
||||||
import { sqlDataTypeToDbType } from '../edit/options'
|
import { sqlDataTypeToDbType } from '../edit/options'
|
||||||
import { useStoreActions } from '@/store/store'
|
import { useStoreActions } from '@/store/store'
|
||||||
import { deleteWizardFile, getWizardFile, postListFormWizard } from '@/services/wizard.service'
|
import { deleteWizardFile, getWizardFile, postListFormWizard } from '@/services/wizard.service'
|
||||||
import { UiLookupDataSourceTypeEnum } from '@/proxy/form/models'
|
|
||||||
import { ListFormWizardDto } from '@/proxy/admin/wizard/models'
|
import { ListFormWizardDto } from '@/proxy/admin/wizard/models'
|
||||||
import {
|
import {
|
||||||
ListFormWorkflowCriteriaDto,
|
ListFormWorkflowCriteriaDto,
|
||||||
SubFormDto,
|
SubFormDto,
|
||||||
WidgetEditDto,
|
WidgetEditDto,
|
||||||
WorkflowDto,
|
WorkflowDto,
|
||||||
|
UiLookupDataSourceTypeEnum,
|
||||||
|
DbTypeEnum,
|
||||||
|
SelectCommandTypeEnum,
|
||||||
} from '@/proxy/form/models'
|
} from '@/proxy/form/models'
|
||||||
|
|
||||||
// ─── Formik initial values & validation ──────────────────────────────────────
|
// ─── Formik initial values & validation ──────────────────────────────────────
|
||||||
|
|
@ -271,7 +272,9 @@ const Wizard = () => {
|
||||||
setSelectCommandColumns(cols)
|
setSelectCommandColumns(cols)
|
||||||
const colNames = new Set(cols.map((c) => c.columnName.toLowerCase()))
|
const colNames = new Set(cols.map((c) => c.columnName.toLowerCase()))
|
||||||
const hasTenantColumn = colNames.has('tenantid')
|
const hasTenantColumn = colNames.has('tenantid')
|
||||||
const selectableColumns = cols.filter((c) => isAutoSelectedColumn(c.columnName, hasTenantColumn))
|
const selectableColumns = cols.filter((c) =>
|
||||||
|
isAutoSelectedColumn(c.columnName, hasTenantColumn),
|
||||||
|
)
|
||||||
setSelectedColumns(new Set(selectableColumns.map((c) => c.columnName)))
|
setSelectedColumns(new Set(selectableColumns.map((c) => c.columnName)))
|
||||||
setEditingGroups([])
|
setEditingGroups([])
|
||||||
// Auto-check isTenant / isBranch based on column presence
|
// Auto-check isTenant / isBranch based on column presence
|
||||||
|
|
@ -297,7 +300,11 @@ const Wizard = () => {
|
||||||
const toggleColumn = (col: string) =>
|
const toggleColumn = (col: string) =>
|
||||||
setSelectedColumns((prev) => {
|
setSelectedColumns((prev) => {
|
||||||
const next = new Set(prev)
|
const next = new Set(prev)
|
||||||
next.has(col) ? next.delete(col) : next.add(col)
|
if (next.has(col)) {
|
||||||
|
next.delete(col)
|
||||||
|
} else {
|
||||||
|
next.add(col)
|
||||||
|
}
|
||||||
return next
|
return next
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -548,15 +555,17 @@ const Wizard = () => {
|
||||||
const previousSpacedLabel = toSpacedLabel(formik?.values.wizardName ?? '')
|
const previousSpacedLabel = toSpacedLabel(formik?.values.wizardName ?? '')
|
||||||
const derived = deriveListFormCode(name)
|
const derived = deriveListFormCode(name)
|
||||||
|
|
||||||
const setAutoText = (field: keyof Pick<
|
const setAutoText = (
|
||||||
ListFormWizardDto,
|
field: keyof Pick<
|
||||||
| 'languageTextMenuEn'
|
ListFormWizardDto,
|
||||||
| 'languageTextMenuTr'
|
| 'languageTextMenuEn'
|
||||||
| 'languageTextTitleEn'
|
| 'languageTextMenuTr'
|
||||||
| 'languageTextTitleTr'
|
| 'languageTextTitleEn'
|
||||||
| 'languageTextDescEn'
|
| 'languageTextTitleTr'
|
||||||
| 'languageTextDescTr'
|
| 'languageTextDescEn'
|
||||||
>) => {
|
| 'languageTextDescTr'
|
||||||
|
>,
|
||||||
|
) => {
|
||||||
const current = formik?.values[field]
|
const current = formik?.values[field]
|
||||||
if (!current || current === previousSpacedLabel) {
|
if (!current || current === previousSpacedLabel) {
|
||||||
formik?.setFieldValue(field, spacedLabel)
|
formik?.setFieldValue(field, spacedLabel)
|
||||||
|
|
@ -789,7 +798,7 @@ const Wizard = () => {
|
||||||
setSubmitting(false)
|
setSubmitting(false)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, isSubmitting, values }) => (
|
{({ touched, errors, values }) => (
|
||||||
<Form onKeyDown={preventEnterSubmit}>
|
<Form onKeyDown={preventEnterSubmit}>
|
||||||
<FormContainer size={currentStep >= 2 ? undefined : 'sm'}>
|
<FormContainer size={currentStep >= 2 ? undefined : 'sm'}>
|
||||||
{/* ─── Step 1: Basic Info ─────────────────────────────── */}
|
{/* ─── Step 1: Basic Info ─────────────────────────────── */}
|
||||||
|
|
@ -856,7 +865,6 @@ const Wizard = () => {
|
||||||
groups={editingGroups}
|
groups={editingGroups}
|
||||||
onGroupsChange={setEditingGroups}
|
onGroupsChange={setEditingGroups}
|
||||||
dbObjects={dbObjects}
|
dbObjects={dbObjects}
|
||||||
isLoadingDbObjects={isLoadingDbObjects}
|
|
||||||
dsCode={currentDataSource}
|
dsCode={currentDataSource}
|
||||||
translate={translate}
|
translate={translate}
|
||||||
onBack={() => setCurrentStep(1)}
|
onBack={() => setCurrentStep(1)}
|
||||||
|
|
|
||||||
|
|
@ -321,7 +321,8 @@ function MenuTreeInline({
|
||||||
const toggle = (code: string) =>
|
const toggle = (code: string) =>
|
||||||
setExpanded((prev) => {
|
setExpanded((prev) => {
|
||||||
const n = new Set(prev)
|
const n = new Set(prev)
|
||||||
n.has(code) ? n.delete(code) : n.add(code)
|
if (n.has(code)) n.delete(code)
|
||||||
|
else n.add(code)
|
||||||
return n
|
return n
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,6 @@ export interface WizardStep3Props {
|
||||||
groups: WizardGroup[]
|
groups: WizardGroup[]
|
||||||
onGroupsChange: (groups: WizardGroup[]) => void
|
onGroupsChange: (groups: WizardGroup[]) => void
|
||||||
dbObjects: SqlObjectExplorerDto | null
|
dbObjects: SqlObjectExplorerDto | null
|
||||||
isLoadingDbObjects: boolean
|
|
||||||
dsCode: string
|
dsCode: string
|
||||||
translate: (key: string) => string
|
translate: (key: string) => string
|
||||||
onBack: () => void
|
onBack: () => void
|
||||||
|
|
@ -794,7 +793,6 @@ const WizardStep3 = ({
|
||||||
groups,
|
groups,
|
||||||
onGroupsChange,
|
onGroupsChange,
|
||||||
dbObjects,
|
dbObjects,
|
||||||
isLoadingDbObjects: _isLoadingDbObjects,
|
|
||||||
dsCode,
|
dsCode,
|
||||||
translate,
|
translate,
|
||||||
onBack,
|
onBack,
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue