Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
frontend
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Package registry
Container registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
videoag
frontend
Commits
aa789863
Verified
Commit
aa789863
authored
9 months ago
by
Dorian Koch
Browse files
Options
Downloads
Patches
Plain Diff
More changelog improvements, closes
#12
parent
cdfd1821
No related branches found
No related tags found
No related merge requests found
Pipeline
#6421
failed
9 months ago
Stage: test
Changes
1
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/pages/internal/changelog.tsx
+305
-107
305 additions, 107 deletions
src/pages/internal/changelog.tsx
with
305 additions
and
107 deletions
src/pages/internal/changelog.tsx
+
305
−
107
View file @
aa789863
...
@@ -7,7 +7,262 @@ import { useFilteredDataView, PagingNavigation, FilterInput } from "@/components
...
@@ -7,7 +7,262 @@ import { useFilteredDataView, PagingNavigation, FilterInput } from "@/components
import
{
DateTime
}
from
"
luxon
"
;
import
{
DateTime
}
from
"
luxon
"
;
import
{
showError
,
ErrorPage
}
from
"
@/misc/ErrorHandlers
"
;
import
{
showError
,
ErrorPage
}
from
"
@/misc/ErrorHandlers
"
;
import
type
{
GetChangelogResponse
,
int
}
from
"
@/api/api_v1_types
"
;
import
type
{
changelog_entry
,
GetChangelogResponse
,
int
}
from
"
@/api/api_v1_types
"
;
import
{
useEffect
,
useState
}
from
"
react
"
;
function
ValToStr
({
val
}:
{
val
:
any
})
{
const
[
expand
,
setExpand
]
=
useState
(
false
);
if
(
val
===
null
)
{
return
<
span
className
=
"fst-italic text-muted"
>
null
</
span
>;
}
if
(
val
===
undefined
)
{
return
<
span
className
=
"fst-italic text-muted"
>
undefined
</
span
>;
}
const
stringifiedVal
=
JSON
.
stringify
(
val
);
if
(
stringifiedVal
.
length
>
100
)
{
if
(
!
expand
)
{
return
(
<
span
>
{
stringifiedVal
.
substring
(
0
,
100
)
}
<
button
type
=
"button"
className
=
"btn btn-link p-0 align-baseline text-decoration-underline"
onClick
=
{
(
e
)
=>
{
setExpand
(
true
);
}
}
>
...
</
button
>
</
span
>
);
}
return
(
<
span
>
{
stringifiedVal
}
<
br
/>
<
button
type
=
"button"
className
=
"btn btn-secondary btn-sm"
onClick
=
{
(
e
)
=>
{
setExpand
(
false
);
}
}
>
Hide
</
button
>
</
span
>
);
}
return
stringifiedVal
;
}
function
Modification
({
i
,
filterLevel
,
formattedDate
,
resolveUser
,
}:
{
i
:
changelog_entry
;
filterLevel
:
(
lvl
:
number
)
=>
()
=>
void
;
formattedDate
:
string
;
resolveUser
:
(
id
:
number
)
=>
string
;
})
{
const
reloadFunc
=
useReloadBoundary
();
const
api
=
useBackendContext
();
const
undo
=
()
=>
{
if
(
i
.
type
!==
"
modification
"
)
{
alert
(
"
TODO: Not implemented
"
);
return
;
}
if
(
!
confirm
(
"
Wirklich zurücksetzen?
"
))
{
return
;
}
let
updates
:
{
[
key
:
string
]:
any
}
=
{};
updates
[
i
.
field_description
!
.
id
]
=
i
.
old_value
;
api
.
updateOMObject
(
i
.
object_type
!
,
i
.
object_id
!
,
{
updates
:
updates
,
expected_current_values
:
{},
//TODO have something here?
})
.
then
(
reloadFunc
)
.
catch
((
e
)
=>
{
showError
(
e
,
"
Exception while reverting change
"
);
});
};
return
(
<
tr
key
=
{
i
.
id
}
>
<
td
>
{
formattedDate
}
</
td
>
<
td
>
{
resolveUser
(
i
.
modifying_user_id
)
}
</
td
>
<
td
>
{
i
.
type
}
</
td
>
<
td
>
<
button
type
=
"button"
className
=
"btn btn-link p-0 align-baseline"
onClick
=
{
filterLevel
(
1
)
}
>
{
`
${
i
.
object_type
}
`
}
</
button
>
.
<
button
type
=
"button"
className
=
"btn btn-link p-0 align-baseline"
onClick
=
{
filterLevel
(
2
)
}
>
{
`
${
i
.
object_id
}
`
}
</
button
>
.
<
button
type
=
"button"
className
=
"btn btn-link p-0 align-baseline"
onClick
=
{
filterLevel
(
3
)
}
>
{
`
${
i
.
field_description
!
.
id
}
`
}
</
button
>
{
` (
${
i
.
field_description
?.
type
}
)`
}
</
td
>
<
td
>
<
ValToStr
val
=
{
i
.
old_value
}
/>
</
td
>
<
td
>
<
ValToStr
val
=
{
i
.
new_value
}
/>
</
td
>
<
td
>
<
button
className
=
"btn btn-warning"
onClick
=
{
undo
}
>
revert to old
</
button
>
</
td
>
</
tr
>
);
}
function
DeletionChange
({
i
,
filterLevel
,
formattedDate
,
resolveUser
,
}:
{
i
:
changelog_entry
;
filterLevel
:
(
lvl
:
number
)
=>
()
=>
void
;
formattedDate
:
string
;
resolveUser
:
(
id
:
number
)
=>
string
;
})
{
const
reloadFunc
=
useReloadBoundary
();
const
api
=
useBackendContext
();
const
undelete
=
()
=>
{
if
(
i
.
type
!==
"
deletion_change
"
||
i
.
is_now_deleted
===
false
)
{
alert
(
"
invalid action!
"
);
return
;
}
if
(
!
confirm
(
"
Wirklich wiederherstellen?
"
))
{
return
;
}
api
.
resurrectOMObject
(
i
.
object_type
!
,
i
.
object_id
!
)
.
then
(
reloadFunc
)
.
catch
((
e
)
=>
{
showError
(
e
,
"
Exception while reverting change
"
);
});
};
return
(
<
tr
key
=
{
i
.
id
}
>
<
td
>
{
formattedDate
}
</
td
>
<
td
>
{
resolveUser
(
i
.
modifying_user_id
)
}
</
td
>
<
td
>
{
i
.
type
}
</
td
>
<
td
>
<
button
type
=
"button"
className
=
"btn btn-link p-0 align-baseline"
onClick
=
{
filterLevel
(
1
)
}
>
{
`
${
i
.
object_type
}
`
}
</
button
>
.
<
button
type
=
"button"
className
=
"btn btn-link p-0 align-baseline"
onClick
=
{
filterLevel
(
2
)
}
>
{
`
${
i
.
object_id
}
`
}
</
button
>
</
td
>
{
i
.
is_now_deleted
?
(
<>
<
td
>
<
span
className
=
"fst-italic text-muted"
>
not deleted
</
span
>
</
td
>
<
td
>
<
span
className
=
"fst-italic text-danger"
>
deleted
</
span
>
</
td
>
</>
)
:
(
<>
<
td
>
<
span
className
=
"fst-italic text-danger"
>
deleted
</
span
>
</
td
>
<
td
>
<
span
className
=
"fst-italic text-muted"
>
not deleted
</
span
>
</
td
>
</>
)
}
<
td
>
{
i
.
is_now_deleted
===
true
&&
(
<
button
className
=
"btn btn-warning"
onClick
=
{
undelete
}
>
undelete
</
button
>
)
}
</
td
>
</
tr
>
);
}
function
Creation
({
i
,
filterLevel
,
formattedDate
,
resolveUser
,
}:
{
i
:
changelog_entry
;
filterLevel
:
(
lvl
:
number
)
=>
()
=>
void
;
formattedDate
:
string
;
resolveUser
:
(
id
:
number
)
=>
string
;
})
{
const
reloadFunc
=
useReloadBoundary
();
const
api
=
useBackendContext
();
return
(
<
tr
key
=
{
i
.
id
}
>
<
td
>
{
formattedDate
}
</
td
>
<
td
>
{
resolveUser
(
i
.
modifying_user_id
)
}
</
td
>
<
td
>
{
i
.
type
}
</
td
>
<
td
>
<
button
type
=
"button"
className
=
"btn btn-link p-0 align-baseline"
onClick
=
{
filterLevel
(
1
)
}
>
{
`
${
i
.
object_type
}
`
}
</
button
>
.
<
button
type
=
"button"
className
=
"btn btn-link p-0 align-baseline"
onClick
=
{
filterLevel
(
2
)
}
>
{
`
${
i
.
object_id
}
`
}
</
button
>
{
typeof
i
.
variant
===
"
string
"
&&
` (variant:
${
i
.
variant
}
)`
}
</
td
>
<
td
>
<
ValToStr
val
=
{
i
.
old_value
}
/>
</
td
>
<
td
>
<
ValToStr
val
=
{
i
.
new_value
}
/>
</
td
>
<
td
></
td
>
</
tr
>
);
}
function
ChangelogList
({
function
ChangelogList
({
changelog
,
changelog
,
...
@@ -21,8 +276,25 @@ function ChangelogList({
...
@@ -21,8 +276,25 @@ function ChangelogList({
updateNow
:
boolean
,
updateNow
:
boolean
,
)
=>
void
;
)
=>
void
;
})
{
})
{
const
reloadFunc
=
useReloadBoundary
();
const
api
=
useBackendContext
();
const
api
=
useBackendContext
();
const
[
usersData
,
setUsersData
]
=
useState
<
{
[
key
:
number
]:
string
}
>
({});
useEffect
(()
=>
{
api
.
getUsers
().
then
((
data
)
=>
{
let
users
:
{
[
key
:
number
]:
string
}
=
{};
data
.
users
.
forEach
((
u
)
=>
{
users
[
u
.
id
]
=
u
.
name
;
});
setUsersData
(
users
);
});
},
[
api
]);
const
resolveUser
=
(
id
:
number
)
=>
{
if
(
usersData
[
id
])
{
return
`
${
usersData
[
id
]}
(
${
id
}
)`
;
}
return
id
+
""
;
};
return
(
return
(
<>
<>
...
@@ -76,79 +348,38 @@ function ChangelogList({
...
@@ -76,79 +348,38 @@ function ChangelogList({
};
};
};
};
let
pfad
=
<></>;
let
pfad
=
<></>;
const
formattedDate
=
DateTime
.
fromISO
(
i
.
change_time
).
toFormat
(
"
yyyy-MM-dd HH:mm:ss
"
,
);
switch
(
i
.
type
)
{
switch
(
i
.
type
)
{
case
"
modification
"
:
case
"
modification
"
:
pfad
=
(
return
(
<>
<
Modification
<
button
i
=
{
i
}
type
=
"button"
filterLevel
=
{
filterLevel
}
className
=
"btn btn-link p-0 align-baseline"
formattedDate
=
{
formattedDate
}
onClick
=
{
filterLevel
(
1
)
}
resolveUser
=
{
resolveUser
}
>
/>
{
`
${
i
.
object_type
}
`
}
</
button
>
.
<
button
type
=
"button"
className
=
"btn btn-link p-0 align-baseline"
onClick
=
{
filterLevel
(
2
)
}
>
{
`
${
i
.
object_id
}
`
}
</
button
>
.
<
button
type
=
"button"
className
=
"btn btn-link p-0 align-baseline"
onClick
=
{
filterLevel
(
3
)
}
>
{
`
${
i
.
field_description
!
.
id
}
`
}
</
button
>
{
` (
${
i
.
field_description
?.
type
}
)`
}
</>
);
);
break
;
case
"
creation
"
:
case
"
creation
"
:
pfad
=
(
return
(
<>
<
Creation
<
button
i
=
{
i
}
type
=
"button"
filterLevel
=
{
filterLevel
}
className
=
"btn btn-link p-0 align-baseline"
formattedDate
=
{
formattedDate
}
onClick
=
{
filterLevel
(
1
)
}
resolveUser
=
{
resolveUser
}
>
/>
{
`
${
i
.
object_type
}
`
}
</
button
>
.
<
button
type
=
"button"
className
=
"btn btn-link p-0 align-baseline"
onClick
=
{
filterLevel
(
2
)
}
>
{
`
${
i
.
object_id
}
`
}
</
button
>
{
typeof
i
.
variant
===
"
string
"
&&
` (variant:
${
i
.
variant
}
)`
}
</>
);
);
break
;
case
"
deletion_change
"
:
case
"
deletion_change
"
:
pfad
=
(
return
(
<>
<
DeletionChange
<
button
i
=
{
i
}
type
=
"button"
filterLevel
=
{
filterLevel
}
className
=
"btn btn-link p-0 align-baseline"
formattedDate
=
{
formattedDate
}
onClick
=
{
filterLevel
(
1
)
}
resolveUser
=
{
resolveUser
}
>
/>
{
`
${
i
.
object_type
}
`
}
</
button
>
.
<
button
type
=
"button"
className
=
"btn btn-link p-0 align-baseline"
onClick
=
{
filterLevel
(
2
)
}
>
{
`
${
i
.
object_id
}
`
}
</
button
>
</>
);
);
break
;
case
"
unknown
"
:
case
"
unknown
"
:
pfad
=
(
pfad
=
(
<>
{
`
${
i
.
unknown_type
}
.
${
i
.
unknown_field
}
, id=
${
i
.
object_id
}
`
}
</>
<>
{
`
${
i
.
unknown_type
}
.
${
i
.
unknown_field
}
, id=
${
i
.
object_id
}
`
}
</>
...
@@ -157,53 +388,20 @@ function ChangelogList({
...
@@ -157,53 +388,20 @@ function ChangelogList({
default
:
default
:
pfad
=
<>
{
i
.
type
}
</>;
pfad
=
<>
{
i
.
type
}
</>;
}
}
const
valToStr
=
(
val
:
any
)
=>
{
if
(
val
===
null
)
{
return
<
span
className
=
"fst-italic text-muted"
>
null
</
span
>;
}
if
(
val
===
undefined
)
{
return
<
span
className
=
"fst-italic text-muted"
>
undefined
</
span
>;
}
return
JSON
.
stringify
(
val
);
};
const
formattedDate
=
DateTime
.
fromISO
(
i
.
change_time
).
toFormat
(
"
yyyy-MM-dd HH:mm:ss
"
,
);
const
undo
=
()
=>
{
if
(
i
.
type
!==
"
modification
"
)
{
alert
(
"
TODO: Not implemented
"
);
return
;
}
if
(
!
confirm
(
"
Wirklich zurücksetzen?
"
))
{
return
;
}
let
updates
:
{
[
key
:
string
]:
any
}
=
{};
updates
[
i
.
field_description
!
.
id
]
=
i
.
old_value
;
api
.
updateOMObject
(
i
.
object_type
!
,
i
.
object_id
!
,
{
updates
:
updates
,
expected_current_values
:
{},
//TODO have something here?
})
.
then
(
reloadFunc
)
.
catch
((
e
)
=>
{
showError
(
e
,
"
Exception while reverting change
"
);
});
};
return
(
return
(
<
tr
key
=
{
i
.
id
}
>
<
tr
key
=
{
i
.
id
}
>
<
td
>
{
formattedDate
}
</
td
>
<
td
>
{
formattedDate
}
</
td
>
<
td
>
{
i
.
modifying_user_id
}
</
td
>
<
td
>
{
resolveUser
(
i
.
modifying_user_id
)
}
</
td
>
<
td
>
{
i
.
type
}
</
td
>
<
td
>
{
i
.
type
}
</
td
>
<
td
>
{
pfad
}
</
td
>
<
td
>
{
pfad
}
</
td
>
<
td
>
{
valToStr
(
i
.
old_value
)
}
</
td
>
<
td
>
{
valToStr
(
i
.
new_value
)
}
</
td
>
<
td
>
<
td
>
{
i
.
type
===
"
modification
"
&&
(
<
ValToStr
val
=
{
i
.
old_value
}
/>
<
button
className
=
"btn btn-warning"
onClick
=
{
undo
}
>
</
td
>
revert to old
<
td
>
</
button
>
<
ValToStr
val
=
{
i
.
new_value
}
/>
)
}
</
td
>
</
td
>
<
td
></
td
>
</
tr
>
</
tr
>
);
);
})
}
})
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment