Mobile ve Desktop IsPopupFullScreen
This commit is contained in:
parent
a7db340011
commit
0f46de0381
9 changed files with 64 additions and 39 deletions
|
|
@ -4,6 +4,7 @@ namespace Sozsoft.Platform.ListForms.DynamicApi;
|
|||
|
||||
public class CreateUpdateUserInput
|
||||
{
|
||||
public string Avatar { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Surname { get; set; }
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ public class PlatformIdentityAppService : ApplicationService
|
|||
LoginEndDate = user.GetLoginEndDate(),
|
||||
ConcurrencyStamp = user.ConcurrencyStamp,
|
||||
LastPasswordChangeTime = user.LastPasswordChangeTime,
|
||||
Avatar = user.GetAvatar(),
|
||||
|
||||
EmailConfirmed = user.EmailConfirmed,
|
||||
PhoneNumberConfirmed = user.PhoneNumberConfirmed,
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ public class ListFormDynamicApiAppService : PlatformAppService, IListFormDynamic
|
|||
user.SetDepartmentId(ParseGuid(input.Data.DepartmentId));
|
||||
user.SetJobPositionId(ParseGuid(input.Data.JobPositionId));
|
||||
user.SetIsVerified(verify);
|
||||
user.SetAvatar(input.Data.Avatar);
|
||||
|
||||
(await userManager.CreateAsync(user, input.Data.Password)).CheckErrors();
|
||||
await userManager.SetLockoutEnabledAsync(user, true);
|
||||
|
|
@ -138,6 +139,12 @@ public class ListFormDynamicApiAppService : PlatformAppService, IListFormDynamic
|
|||
user.SetJobPositionId(ParseGuid(input.Data.JobPositionId));
|
||||
}
|
||||
|
||||
if (input.Data.Avatar != null)
|
||||
{
|
||||
user.SetJobPositionId(ParseGuid(input.Data.Avatar));
|
||||
}
|
||||
|
||||
|
||||
(await userManager.UpdateAsync(user)).CheckErrors();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ const FormEdit = (
|
|||
return (
|
||||
<>
|
||||
<Container
|
||||
className={`${isNotePanelVisible && !isSubForm ? 'mr-[400px]' : ''} transition-all duration-300`}
|
||||
className={`${isNotePanelVisible && !isSubForm ? 'lg:mr-[375px]' : ''} transition-all duration-300`}
|
||||
>
|
||||
{!isSubForm && (
|
||||
<Helmet
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ const FormView = (
|
|||
return (
|
||||
<>
|
||||
<Container
|
||||
className={`${isNotePanelVisible && !isSubForm ? 'mr-[400px]' : ''} transition-all duration-300`}
|
||||
className={`${isNotePanelVisible && !isSubForm ? 'lg:mr-[375px]' : ''} transition-all duration-300`}
|
||||
>
|
||||
{!isSubForm && (
|
||||
<Helmet
|
||||
|
|
|
|||
|
|
@ -339,13 +339,13 @@ export const NoteList: React.FC<NoteListProps> = ({
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<div className="relative min-w-0 overflow-x-hidden">
|
||||
<Tabs
|
||||
value={currentTab}
|
||||
onChange={(val) => setCurrentTab(val as 'notes' | 'audit')}
|
||||
variant="underline"
|
||||
>
|
||||
<TabList className="mb-2 border-0 dark:bg-gray-800">
|
||||
<TabList className="mb-2 flex-wrap border-0 dark:bg-gray-800">
|
||||
<TabNav value="notes">
|
||||
{translate('::ListForms.ListForm.Notes')}
|
||||
<Badge className="ml-2 bg-blue-500" content={`${notes?.length ?? 0}`} />
|
||||
|
|
@ -358,7 +358,7 @@ export const NoteList: React.FC<NoteListProps> = ({
|
|||
|
||||
<div className="mb-2 flex min-h-10 items-center justify-end border-y border-gray-200 bg-gray-50 px-1 py-1 dark:border-gray-700 dark:bg-gray-900">
|
||||
{currentTab === 'notes' ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex flex-wrap items-center justify-end gap-2">
|
||||
<Button
|
||||
variant="default"
|
||||
size="xs"
|
||||
|
|
@ -404,7 +404,7 @@ export const NoteList: React.FC<NoteListProps> = ({
|
|||
<p className="text-sm">{translate('::ListForms.ListForm.Notes.Empty')}</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-5 ml-5">
|
||||
<div className="space-y-5 pl-7">
|
||||
{notes.map((note, index) => {
|
||||
const files = note.filesJson ? JSON.parse(note.filesJson) : []
|
||||
const creationDate = note.creationTime ? new Date(note.creationTime) : null
|
||||
|
|
@ -413,7 +413,7 @@ export const NoteList: React.FC<NoteListProps> = ({
|
|||
return (
|
||||
<div
|
||||
key={note.id || index}
|
||||
className={`relative bg-white border-l-4 rounded-lg shadow-sm hover:shadow-md transition-shadow duration-200 dark:bg-gray-900 dark:border-purple-600 ${border}`}
|
||||
className={`relative min-w-0 bg-white border-l-4 rounded-lg shadow-sm hover:shadow-md transition-shadow duration-200 dark:bg-gray-900 dark:border-purple-600 ${border}`}
|
||||
>
|
||||
{/* Timeline Düğmesi */}
|
||||
<div className="absolute -left-7 top-4 bg-white rounded-full border-2 border-gray-300 p-2">
|
||||
|
|
@ -422,8 +422,8 @@ export const NoteList: React.FC<NoteListProps> = ({
|
|||
|
||||
<div className="p-4">
|
||||
{/* Header */}
|
||||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<div className="min-w-0">
|
||||
<div className="flex items-center gap-1 text-sm font-semibold text-gray-800 dark:text-gray-200">
|
||||
<Avatar
|
||||
size={25}
|
||||
|
|
@ -453,7 +453,7 @@ export const NoteList: React.FC<NoteListProps> = ({
|
|||
</div>
|
||||
|
||||
{/* Body */}
|
||||
<div className="mt-3 ml-1">
|
||||
<div className="mt-3 ml-1 break-words">
|
||||
{note.subject && (
|
||||
<h4 className="text-sm font-bold text-gray-900 mb-1">{note.subject}</h4>
|
||||
)}
|
||||
|
|
@ -503,7 +503,7 @@ export const NoteList: React.FC<NoteListProps> = ({
|
|||
<p className="text-sm">{translate('::ListForms.ListForm.AuditLogs.Empty')}</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-4 ml-5">
|
||||
<div className="space-y-4 pl-7">
|
||||
{auditItems.map(({ log, matchedActions }) => {
|
||||
const execTime = log.executionTime ? new Date(log.executionTime) : null
|
||||
const changeCount = log.entityChangeCount ?? log.entityChanges?.length ?? 0
|
||||
|
|
@ -552,7 +552,7 @@ export const NoteList: React.FC<NoteListProps> = ({
|
|||
return (
|
||||
<div
|
||||
key={log.id}
|
||||
className="relative bg-white border-l-4 rounded-lg shadow-sm hover:shadow-md transition-shadow duration-200 border-purple-400 dark:bg-gray-900 dark:border-purple-600"
|
||||
className="relative min-w-0 bg-white border-l-4 rounded-lg shadow-sm hover:shadow-md transition-shadow duration-200 border-purple-400 dark:bg-gray-900 dark:border-purple-600"
|
||||
>
|
||||
<div className="absolute -left-7 top-4 bg-white rounded-full border-2 border-gray-300 p-2">
|
||||
<FaHistory className="text-purple-600" />
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import { noteService } from '@/services/note.service'
|
|||
import { NoteDto } from '@/proxy/note/models'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
|
||||
const NOTE_PANEL_WIDTH = 375
|
||||
|
||||
interface NotePanelProps {
|
||||
entityName: string
|
||||
entityId: string
|
||||
|
|
@ -144,18 +146,20 @@ export const NotePanel: React.FC<NotePanelProps> = ({
|
|||
|
||||
{/* Panel */}
|
||||
<div
|
||||
className={`fixed right-0 top-0 h-full bg-white border-l border-gray-500 shadow-xl transform transition-transform duration-300 ease-in-out z-30 dark:bg-gray-800 ${isVisible ? 'translate-x-0' : 'translate-x-full'}`}
|
||||
style={{ width: '450px' }}
|
||||
className={`fixed right-0 top-0 h-full max-w-full bg-white border-l border-gray-500 shadow-xl transform transition-transform duration-300 ease-in-out z-30 dark:bg-gray-800 ${isVisible ? 'translate-x-0' : 'translate-x-full'}`}
|
||||
style={{ width: `min(100vw, ${NOTE_PANEL_WIDTH}px)` }}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className="flex flex-col h-full">
|
||||
<div className="p-2 border-b border-gray-200 dark:bg-gray-900 dark:border-gray-700">
|
||||
{/* Üst Satır: Başlık, Kayıt Bilgisi Toggle ve Kapat Butonu */}
|
||||
<div className="flex items-center justify-between mx-1 my-1">
|
||||
<div className="flex flex-col gap-1 text-sm text-gray-700">
|
||||
<span className="font-medium text-black dark:text-white">{entityName}</span>
|
||||
<div className="flex items-start justify-between gap-2 mx-1 my-1">
|
||||
<div className="flex min-w-0 flex-col gap-1 text-sm text-gray-700">
|
||||
<span className="break-words font-medium text-black dark:text-white">
|
||||
{entityName}
|
||||
</span>
|
||||
|
||||
<code className="py-1 rounded text-gray-800 text-xs font-mono w-fit">
|
||||
<code className="py-1 rounded text-gray-800 text-xs font-mono break-all">
|
||||
<Badge className="bg-blue-100 text-blue-600 dark:bg-blue-600 dark:text-blue-100" content={entityId} />
|
||||
</code>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ const Grid = (props: GridProps) => {
|
|||
const { listFormCode, searchParams, isSubForm, level, gridDto: extGridDto } = props
|
||||
const { translate } = useLocalization()
|
||||
const currentUser = useStoreState((state) => state.auth.user)
|
||||
const useMobileEditPopup = useRef(isMobileViewport() || isTouchLikeDevice()).current
|
||||
const useMobileEditPopup = isMobileViewport() || isTouchLikeDevice()
|
||||
|
||||
const gridRef = useRef<DataGridRef>()
|
||||
const refListFormCode = useRef('')
|
||||
|
|
@ -520,7 +520,9 @@ const Grid = (props: GridProps) => {
|
|||
}
|
||||
|
||||
setMode('new')
|
||||
setIsPopupFullScreen(gridDto?.gridOptions.editingOptionDto?.popup?.fullScreen ?? false)
|
||||
setIsPopupFullScreen(
|
||||
useMobileEditPopup || (gridDto?.gridOptions.editingOptionDto?.popup?.fullScreen ?? false),
|
||||
)
|
||||
|
||||
e.promise = (async () => {
|
||||
const rawFilter = searchParams?.get('filter')
|
||||
|
|
@ -609,7 +611,7 @@ const Grid = (props: GridProps) => {
|
|||
editingFormDataRef.current = { ...(e.data || {}) }
|
||||
})()
|
||||
},
|
||||
[gridDto, searchParams, extraFilters, getNextSequenceValue],
|
||||
[gridDto, searchParams, extraFilters, getNextSequenceValue, useMobileEditPopup],
|
||||
)
|
||||
|
||||
const onRowInserting = useCallback(
|
||||
|
|
@ -659,7 +661,9 @@ const Grid = (props: GridProps) => {
|
|||
isEditingRef.current = true
|
||||
editingFormDataRef.current = { ...(e.data || {}) }
|
||||
setMode('edit')
|
||||
setIsPopupFullScreen(gridDto?.gridOptions.editingOptionDto?.popup?.fullScreen ?? false)
|
||||
setIsPopupFullScreen(
|
||||
useMobileEditPopup || (gridDto?.gridOptions.editingOptionDto?.popup?.fullScreen ?? false),
|
||||
)
|
||||
const columns = e.component.option('columns') as GridColumnData[]
|
||||
|
||||
// FormEditingExtraItem field ise datayı doldur
|
||||
|
|
@ -676,7 +680,7 @@ const Grid = (props: GridProps) => {
|
|||
e.data[col.dataField] = json[field[1]]
|
||||
})
|
||||
},
|
||||
[gridDto, mode],
|
||||
[gridDto, mode, useMobileEditPopup],
|
||||
)
|
||||
|
||||
const onDataErrorOccurred = useCallback((e: DataGridTypes.DataErrorOccurredEvent<any, any>) => {
|
||||
|
|
@ -965,9 +969,11 @@ const Grid = (props: GridProps) => {
|
|||
}
|
||||
|
||||
if (gridDto.gridOptions.editingOptionDto?.popup) {
|
||||
setIsPopupFullScreen(gridDto.gridOptions.editingOptionDto?.popup?.fullScreen ?? false)
|
||||
setIsPopupFullScreen(
|
||||
useMobileEditPopup || (gridDto.gridOptions.editingOptionDto?.popup?.fullScreen ?? false),
|
||||
)
|
||||
}
|
||||
}, [gridDto])
|
||||
}, [gridDto, useMobileEditPopup])
|
||||
|
||||
// extraFilters değişikliklerini useMemo ile optimize et
|
||||
const filterParams = useMemo(() => {
|
||||
|
|
@ -1557,8 +1563,8 @@ const Grid = (props: GridProps) => {
|
|||
width: useMobileEditPopup
|
||||
? '100%'
|
||||
: gridDto.gridOptions.editingOptionDto?.popup?.width,
|
||||
height: useMobileEditPopup
|
||||
? '100dvh'
|
||||
height: useMobileEditPopup && isPopupFullScreen
|
||||
? '100%'
|
||||
: gridDto.gridOptions.editingOptionDto?.popup?.height,
|
||||
position: useMobileEditPopup
|
||||
? {
|
||||
|
|
@ -1607,7 +1613,7 @@ const Grid = (props: GridProps) => {
|
|||
? translate('::Normal Boyut')
|
||||
: translate('::Tam Ekran'),
|
||||
stylingMode: 'text',
|
||||
onClick: () => setIsPopupFullScreen(!isPopupFullScreen),
|
||||
onClick: () => setIsPopupFullScreen((current) => !current),
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
@ -1834,7 +1840,7 @@ const Grid = (props: GridProps) => {
|
|||
<Template name={'cellEditImageUpload'} render={ImageUploadEditorComponent} />
|
||||
<Template
|
||||
name={'cellEditImageViewer'}
|
||||
render={(data) => (
|
||||
render={(data: any) => (
|
||||
<ImageViewerEditorComponent
|
||||
{...data}
|
||||
fallbackFormData={editingFormDataRef.current}
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ const Tree = (props: TreeProps) => {
|
|||
const { listFormCode, searchParams, isSubForm, level, gridDto: extGridDto } = props
|
||||
const { translate } = useLocalization()
|
||||
const currentUser = useStoreState((state) => state.auth.user)
|
||||
const useMobileEditPopup = useRef(isMobileViewport() || isTouchLikeDevice()).current
|
||||
const useMobileEditPopup = isMobileViewport() || isTouchLikeDevice()
|
||||
|
||||
const gridRef = useRef<TreeListRef>()
|
||||
const refListFormCode = useRef('')
|
||||
|
|
@ -554,7 +554,9 @@ const Tree = (props: TreeProps) => {
|
|||
}
|
||||
|
||||
setMode('new')
|
||||
setIsPopupFullScreen(gridDto?.gridOptions.editingOptionDto?.popup?.fullScreen ?? false)
|
||||
setIsPopupFullScreen(
|
||||
useMobileEditPopup || (gridDto?.gridOptions.editingOptionDto?.popup?.fullScreen ?? false),
|
||||
)
|
||||
|
||||
for (const colFormat of gridDto?.columnFormats) {
|
||||
if (!colFormat.fieldName) {
|
||||
|
|
@ -656,7 +658,9 @@ const Tree = (props: TreeProps) => {
|
|||
isEditingRef.current = true
|
||||
editingFormDataRef.current = { ...(e.data || {}) }
|
||||
setMode('edit')
|
||||
setIsPopupFullScreen(gridDto?.gridOptions.editingOptionDto?.popup?.fullScreen ?? false)
|
||||
setIsPopupFullScreen(
|
||||
useMobileEditPopup || (gridDto?.gridOptions.editingOptionDto?.popup?.fullScreen ?? false),
|
||||
)
|
||||
const columns = e.component.option('columns') as GridColumnData[]
|
||||
columns?.forEach((col) => {
|
||||
if (!col.dataField?.includes(':')) {
|
||||
|
|
@ -920,7 +924,9 @@ const Tree = (props: TreeProps) => {
|
|||
}
|
||||
|
||||
if (gridDto.gridOptions.editingOptionDto?.popup) {
|
||||
setIsPopupFullScreen(gridDto.gridOptions.editingOptionDto?.popup?.fullScreen ?? false)
|
||||
setIsPopupFullScreen(
|
||||
useMobileEditPopup || (gridDto.gridOptions.editingOptionDto?.popup?.fullScreen ?? false),
|
||||
)
|
||||
}
|
||||
|
||||
// Set initial expanded row keys
|
||||
|
|
@ -929,7 +935,7 @@ const Tree = (props: TreeProps) => {
|
|||
} else if (gridDto.gridOptions.treeOptionDto?.autoExpandAll) {
|
||||
setExpandedRowKeys([])
|
||||
}
|
||||
}, [gridDto])
|
||||
}, [gridDto, useMobileEditPopup])
|
||||
|
||||
useEffect(() => {
|
||||
if (!gridDto) return
|
||||
|
|
@ -1209,8 +1215,8 @@ const Tree = (props: TreeProps) => {
|
|||
width: useMobileEditPopup
|
||||
? '100%'
|
||||
: gridDto.gridOptions.editingOptionDto?.popup?.width,
|
||||
height: useMobileEditPopup
|
||||
? '100dvh'
|
||||
height: useMobileEditPopup && isPopupFullScreen
|
||||
? '100%'
|
||||
: gridDto.gridOptions.editingOptionDto?.popup?.height,
|
||||
position: useMobileEditPopup
|
||||
? {
|
||||
|
|
@ -1259,7 +1265,7 @@ const Tree = (props: TreeProps) => {
|
|||
? translate('::Normal Boyut')
|
||||
: translate('::Tam Ekran'),
|
||||
stylingMode: 'text',
|
||||
onClick: () => setIsPopupFullScreen(!isPopupFullScreen),
|
||||
onClick: () => setIsPopupFullScreen((current) => !current),
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
@ -1604,7 +1610,7 @@ const Tree = (props: TreeProps) => {
|
|||
<Template name={'cellEditGridBox'} render={GridBoxEditorComponent} />
|
||||
<Template
|
||||
name={'cellEditImageViewer'}
|
||||
render={(data) => (
|
||||
render={(data: any) => (
|
||||
<ImageViewerEditorComponent
|
||||
{...data}
|
||||
fallbackFormData={editingFormDataRef.current}
|
||||
|
|
|
|||
Loading…
Reference in a new issue