mirror of
https://github.com/MizuchiLabs/mantrae.git
synced 2025-12-16 20:05:17 -06:00
fix some ui errors
This commit is contained in:
@@ -8,7 +8,7 @@ managed:
|
||||
- file_option: go_package
|
||||
module: buf.build/bufbuild/protovalidate
|
||||
plugins:
|
||||
- local: protoc-gen-go
|
||||
- protoc_builtin: go
|
||||
out: proto/gen
|
||||
opt: paths=source_relative
|
||||
- local: protoc-gen-connect-go
|
||||
|
||||
2
go.mod
2
go.mod
@@ -12,7 +12,7 @@ require (
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.5
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.17
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.70
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.82.0
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.83.0
|
||||
github.com/caarlos0/env/v11 v11.3.1
|
||||
github.com/cloudflare/cloudflare-go v0.115.0
|
||||
github.com/coreos/go-oidc/v3 v3.14.1
|
||||
|
||||
4
go.sum
4
go.sum
@@ -48,8 +48,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 h1:t0E6FzRE
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17/go.mod h1:ygpklyoaypuyDvOM5ujWGrYWpAK3h7ugnmKCU/76Ys4=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17 h1:qcLWgdhq45sDM9na4cvXax9dyLitn8EYBRl8Ak4XtG4=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17/go.mod h1:M+jkjBFZ2J6DJrjMv2+vkBbuht6kxJYtJiwoVgX4p4U=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.82.0 h1:JubM8CGDDFaAOmBrd8CRYNr49ZNgEAiLwGwgNMdS0nw=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.82.0/go.mod h1:kUklwasNoCn5YpyAqC/97r6dzTA1SRKJfKq16SXeoDU=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.83.0 h1:5Y75q0RPQoAbieyOuGLhjV9P3txvYgXv2lg0UwJOfmE=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.83.0/go.mod h1:kUklwasNoCn5YpyAqC/97r6dzTA1SRKJfKq16SXeoDU=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 h1:AIRJ3lfb2w/1/8wOOSqYb9fUKGwQbtysJ2H1MofRUPg=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.5/go.mod h1:b7SiVprpU+iGazDUqvRSLf5XmCdn+JtT1on7uNL6Ipc=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 h1:BpOxT3yhLwSJ77qIY3DoHAQjZsc4HEGfMCE4NGy3uFg=
|
||||
|
||||
@@ -17,6 +17,8 @@ type AuditEvent struct {
|
||||
ProfileID *int64
|
||||
Event string
|
||||
Details string
|
||||
UserID *string
|
||||
AgentID *string
|
||||
}
|
||||
|
||||
// NewAuditInterceptor automatically logs CRUD operations
|
||||
@@ -28,17 +30,25 @@ func NewAuditInterceptor(app *config.App) connect.UnaryInterceptorFunc {
|
||||
|
||||
// Only audit on successful operations
|
||||
if err == nil {
|
||||
var params db.CreateAuditLogParams
|
||||
params.UserID = GetUserIDFromContext(ctx)
|
||||
params.AgentID = GetAgentIDFromContext(ctx)
|
||||
if auditEvent := extractAuditEvent(req, resp); auditEvent != nil {
|
||||
if auditEvent.Details == "" || auditEvent.Event == "" {
|
||||
slog.Warn("audit event is missing details or event", "event", auditEvent)
|
||||
return resp, err
|
||||
}
|
||||
// Log audit event asynchronously to avoid blocking the response
|
||||
go func(auditCtx context.Context) {
|
||||
if auditErr := createAuditLog(auditCtx, app.Conn.GetQuery(), *auditEvent); auditErr != nil {
|
||||
slog.Warn("failed to create audit log", "error", auditErr)
|
||||
go func() {
|
||||
params.ProfileID = auditEvent.ProfileID
|
||||
params.Event = auditEvent.Event
|
||||
if auditEvent.Details != "" {
|
||||
params.Details = &auditEvent.Details
|
||||
}
|
||||
}(ctx)
|
||||
if err = app.Conn.GetQuery().CreateAuditLog(context.Background(), params); err != nil {
|
||||
slog.Error("failed to create audit log", "error", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -242,12 +242,16 @@ func (s *UserService) CreateUser(
|
||||
params := db.CreateUserParams{
|
||||
ID: id.String(),
|
||||
Username: req.Msg.Username,
|
||||
Password: req.Msg.Password,
|
||||
IsAdmin: req.Msg.IsAdmin,
|
||||
}
|
||||
if req.Msg.Email != "" {
|
||||
params.Email = &req.Msg.Email
|
||||
}
|
||||
hash, err := util.HashPassword(req.Msg.Password)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
params.Password = hash
|
||||
|
||||
result, err := s.app.Conn.GetQuery().CreateUser(ctx, params)
|
||||
if err != nil {
|
||||
|
||||
@@ -5,17 +5,20 @@ import (
|
||||
mantraev1 "github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1"
|
||||
)
|
||||
|
||||
func AuditLogsToProto(logs []db.AuditLog) []*mantraev1.AuditLog {
|
||||
func AuditLogsToProto(logs []db.ListAuditLogsRow) []*mantraev1.AuditLog {
|
||||
var auditLogs []*mantraev1.AuditLog
|
||||
for _, l := range logs {
|
||||
auditLogs = append(auditLogs, &mantraev1.AuditLog{
|
||||
Id: l.ID,
|
||||
ProfileId: SafeInt64(l.ProfileID),
|
||||
UserId: SafeString(l.UserID),
|
||||
AgentId: SafeString(l.AgentID),
|
||||
Event: l.Event,
|
||||
Details: SafeString(l.Details),
|
||||
CreatedAt: SafeTimestamp(l.CreatedAt),
|
||||
Id: l.ID,
|
||||
ProfileId: SafeInt64(l.ProfileID),
|
||||
ProfileName: SafeString(l.ProfileName),
|
||||
UserId: SafeString(l.UserID),
|
||||
UserName: SafeString(l.UserName),
|
||||
AgentId: SafeString(l.AgentID),
|
||||
AgentName: SafeString(l.AgentName),
|
||||
Event: l.Event,
|
||||
Details: SafeString(l.Details),
|
||||
CreatedAt: SafeTimestamp(l.CreatedAt),
|
||||
})
|
||||
}
|
||||
return auditLogs
|
||||
|
||||
@@ -236,8 +236,7 @@ CREATE TABLE audit_logs (
|
||||
agent_id TEXT,
|
||||
event TEXT NOT NULL,
|
||||
details TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (profile_id) REFERENCES profiles (id) ON DELETE CASCADE
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
|
||||
@@ -7,6 +7,7 @@ package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
const countAuditLogs = `-- name: CountAuditLogs :one
|
||||
@@ -69,11 +70,23 @@ func (q *Queries) DeleteOldAuditLogs(ctx context.Context) error {
|
||||
|
||||
const listAuditLogs = `-- name: ListAuditLogs :many
|
||||
SELECT
|
||||
id, profile_id, user_id, agent_id, event, details, created_at
|
||||
a.id,
|
||||
a.profile_id,
|
||||
p.name AS profile_name,
|
||||
a.user_id,
|
||||
u.username AS user_name,
|
||||
a.agent_id,
|
||||
ag.hostname AS agent_name,
|
||||
a.event,
|
||||
a.details,
|
||||
a.created_at
|
||||
FROM
|
||||
audit_logs
|
||||
audit_logs a
|
||||
LEFT JOIN profiles p ON a.profile_id = p.id
|
||||
LEFT JOIN users u ON a.user_id = u.id
|
||||
LEFT JOIN agents ag ON a.agent_id = ag.id
|
||||
ORDER BY
|
||||
created_at DESC
|
||||
a.created_at DESC
|
||||
LIMIT
|
||||
?
|
||||
OFFSET
|
||||
@@ -85,20 +98,36 @@ type ListAuditLogsParams struct {
|
||||
Offset int64 `json:"offset"`
|
||||
}
|
||||
|
||||
func (q *Queries) ListAuditLogs(ctx context.Context, arg ListAuditLogsParams) ([]AuditLog, error) {
|
||||
type ListAuditLogsRow struct {
|
||||
ID int64 `json:"id"`
|
||||
ProfileID *int64 `json:"profileId"`
|
||||
ProfileName *string `json:"profileName"`
|
||||
UserID *string `json:"userId"`
|
||||
UserName *string `json:"userName"`
|
||||
AgentID *string `json:"agentId"`
|
||||
AgentName *string `json:"agentName"`
|
||||
Event string `json:"event"`
|
||||
Details *string `json:"details"`
|
||||
CreatedAt *time.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
func (q *Queries) ListAuditLogs(ctx context.Context, arg ListAuditLogsParams) ([]ListAuditLogsRow, error) {
|
||||
rows, err := q.query(ctx, q.listAuditLogsStmt, listAuditLogs, arg.Limit, arg.Offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []AuditLog
|
||||
var items []ListAuditLogsRow
|
||||
for rows.Next() {
|
||||
var i AuditLog
|
||||
var i ListAuditLogsRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ProfileID,
|
||||
&i.ProfileName,
|
||||
&i.UserID,
|
||||
&i.UserName,
|
||||
&i.AgentID,
|
||||
&i.AgentName,
|
||||
&i.Event,
|
||||
&i.Details,
|
||||
&i.CreatedAt,
|
||||
|
||||
@@ -120,7 +120,7 @@ type Querier interface {
|
||||
GetUserByUsername(ctx context.Context, username string) (User, error)
|
||||
ListAdminUsers(ctx context.Context, arg ListAdminUsersParams) ([]User, error)
|
||||
ListAgents(ctx context.Context, arg ListAgentsParams) ([]Agent, error)
|
||||
ListAuditLogs(ctx context.Context, arg ListAuditLogsParams) ([]AuditLog, error)
|
||||
ListAuditLogs(ctx context.Context, arg ListAuditLogsParams) ([]ListAuditLogsRow, error)
|
||||
ListDnsProviders(ctx context.Context, arg ListDnsProvidersParams) ([]DnsProvider, error)
|
||||
ListEntryPoints(ctx context.Context, arg ListEntryPointsParams) ([]EntryPoint, error)
|
||||
ListErrors(ctx context.Context) ([]Error, error)
|
||||
|
||||
@@ -144,8 +144,7 @@ CREATE TABLE audit_logs (
|
||||
agent_id TEXT,
|
||||
event TEXT NOT NULL,
|
||||
details TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (profile_id) REFERENCES profiles (id) ON DELETE CASCADE
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Migrate data from old traefik table to new traefik_instances
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
-- name: ListAuditLogs :many
|
||||
SELECT
|
||||
*
|
||||
a.id,
|
||||
a.profile_id,
|
||||
p.name AS profile_name,
|
||||
a.user_id,
|
||||
u.username AS user_name,
|
||||
a.agent_id,
|
||||
ag.hostname AS agent_name,
|
||||
a.event,
|
||||
a.details,
|
||||
a.created_at
|
||||
FROM
|
||||
audit_logs
|
||||
audit_logs a
|
||||
LEFT JOIN profiles p ON a.profile_id = p.id
|
||||
LEFT JOIN users u ON a.user_id = u.id
|
||||
LEFT JOIN agents ag ON a.agent_id = ag.id
|
||||
ORDER BY
|
||||
created_at DESC
|
||||
a.created_at DESC
|
||||
LIMIT
|
||||
?
|
||||
OFFSET
|
||||
|
||||
@@ -27,11 +27,14 @@ type AuditLog struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
ProfileId int64 `protobuf:"varint,2,opt,name=profile_id,json=profileId,proto3" json:"profile_id,omitempty"`
|
||||
UserId string `protobuf:"bytes,3,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
AgentId string `protobuf:"bytes,4,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`
|
||||
Event string `protobuf:"bytes,5,opt,name=event,proto3" json:"event,omitempty"`
|
||||
Details string `protobuf:"bytes,6,opt,name=details,proto3" json:"details,omitempty"`
|
||||
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
ProfileName string `protobuf:"bytes,3,opt,name=profile_name,json=profileName,proto3" json:"profile_name,omitempty"`
|
||||
UserId string `protobuf:"bytes,4,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
UserName string `protobuf:"bytes,5,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"`
|
||||
AgentId string `protobuf:"bytes,6,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`
|
||||
AgentName string `protobuf:"bytes,7,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"`
|
||||
Event string `protobuf:"bytes,8,opt,name=event,proto3" json:"event,omitempty"`
|
||||
Details string `protobuf:"bytes,9,opt,name=details,proto3" json:"details,omitempty"`
|
||||
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -80,6 +83,13 @@ func (x *AuditLog) GetProfileId() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *AuditLog) GetProfileName() string {
|
||||
if x != nil {
|
||||
return x.ProfileName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuditLog) GetUserId() string {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
@@ -87,6 +97,13 @@ func (x *AuditLog) GetUserId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuditLog) GetUserName() string {
|
||||
if x != nil {
|
||||
return x.UserName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuditLog) GetAgentId() string {
|
||||
if x != nil {
|
||||
return x.AgentId
|
||||
@@ -94,6 +111,13 @@ func (x *AuditLog) GetAgentId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuditLog) GetAgentName() string {
|
||||
if x != nil {
|
||||
return x.AgentName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuditLog) GetEvent() string {
|
||||
if x != nil {
|
||||
return x.Event
|
||||
@@ -228,58 +252,64 @@ var file_mantrae_v1_auditlog_proto_rawDesc = string([]byte{
|
||||
0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd8, 0x01, 0x0a, 0x08, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb7, 0x02, 0x0a, 0x08, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c,
|
||||
0x6f, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02,
|
||||
0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49,
|
||||
0x64, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x67,
|
||||
0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67,
|
||||
0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64,
|
||||
0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65,
|
||||
0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
|
||||
0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74,
|
||||
0x22, 0xc4, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f,
|
||||
0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x71, 0x0a, 0x05, 0x6c, 0x69, 0x6d,
|
||||
0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x56, 0xba, 0x48, 0x53, 0xba, 0x01, 0x50,
|
||||
0x0a, 0x0b, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x29, 0x6c,
|
||||
0x69, 0x6d, 0x69, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x65, 0x69, 0x74,
|
||||
0x68, 0x65, 0x72, 0x20, 0x2d, 0x31, 0x20, 0x6f, 0x72, 0x20, 0x67, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x30, 0x1a, 0x16, 0x74, 0x68, 0x69, 0x73, 0x20, 0x3d,
|
||||
0x3d, 0x20, 0x2d, 0x31, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x3e, 0x20, 0x30,
|
||||
0x48, 0x00, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, 0x12, 0x24, 0x0a, 0x06,
|
||||
0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x42, 0x07, 0xba, 0x48,
|
||||
0x04, 0x22, 0x02, 0x28, 0x00, 0x48, 0x01, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x88,
|
||||
0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x09, 0x0a, 0x07,
|
||||
0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x6d, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x41,
|
||||
0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x33, 0x0a, 0x0a, 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x65, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x09, 0x61, 0x75, 0x64, 0x69,
|
||||
0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61,
|
||||
0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0x6c, 0x0a, 0x0f, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c,
|
||||
0x6f, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x59, 0x0a, 0x0d, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x20, 0x2e, 0x6d, 0x61, 0x6e,
|
||||
0x74, 0x72, 0x61, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x64, 0x69,
|
||||
0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d,
|
||||
0x61, 0x6e, 0x74, 0x72, 0x61, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75,
|
||||
0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x03, 0x90, 0x02, 0x01, 0x42, 0xa7, 0x01, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x61, 0x6e,
|
||||
0x74, 0x72, 0x61, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x41, 0x75, 0x64, 0x69, 0x74, 0x6c, 0x6f,
|
||||
0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x7a, 0x75, 0x63, 0x68, 0x69, 0x6c, 0x61, 0x62, 0x73,
|
||||
0x2f, 0x6d, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67,
|
||||
0x65, 0x6e, 0x2f, 0x6d, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x61,
|
||||
0x6e, 0x74, 0x72, 0x61, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x4d, 0x58, 0x58, 0xaa, 0x02, 0x0a,
|
||||
0x4d, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0a, 0x4d, 0x61, 0x6e,
|
||||
0x74, 0x72, 0x61, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x16, 0x4d, 0x61, 0x6e, 0x74, 0x72, 0x61,
|
||||
0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0xea, 0x02, 0x0b, 0x4d, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a,
|
||||
0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x67,
|
||||
0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67,
|
||||
0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74,
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65,
|
||||
0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74,
|
||||
0x61, 0x69, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f,
|
||||
0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22,
|
||||
0xc4, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67,
|
||||
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x71, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69,
|
||||
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x56, 0xba, 0x48, 0x53, 0xba, 0x01, 0x50, 0x0a,
|
||||
0x0b, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x29, 0x6c, 0x69,
|
||||
0x6d, 0x69, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x65, 0x69, 0x74, 0x68,
|
||||
0x65, 0x72, 0x20, 0x2d, 0x31, 0x20, 0x6f, 0x72, 0x20, 0x67, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72,
|
||||
0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x30, 0x1a, 0x16, 0x74, 0x68, 0x69, 0x73, 0x20, 0x3d, 0x3d,
|
||||
0x20, 0x2d, 0x31, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x3e, 0x20, 0x30, 0x48,
|
||||
0x00, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, 0x12, 0x24, 0x0a, 0x06, 0x6f,
|
||||
0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x42, 0x07, 0xba, 0x48, 0x04,
|
||||
0x22, 0x02, 0x28, 0x00, 0x48, 0x01, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x88, 0x01,
|
||||
0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x5f,
|
||||
0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x6d, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75,
|
||||
0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x33, 0x0a, 0x0a, 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x65, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x09, 0x61, 0x75, 0x64, 0x69, 0x74,
|
||||
0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c,
|
||||
0x43, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0x6c, 0x0a, 0x0f, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f,
|
||||
0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x59, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x20, 0x2e, 0x6d, 0x61, 0x6e, 0x74,
|
||||
0x72, 0x61, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x64, 0x69, 0x74,
|
||||
0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x61,
|
||||
0x6e, 0x74, 0x72, 0x61, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x64,
|
||||
0x69, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03,
|
||||
0x90, 0x02, 0x01, 0x42, 0xa7, 0x01, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x61, 0x6e, 0x74,
|
||||
0x72, 0x61, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x41, 0x75, 0x64, 0x69, 0x74, 0x6c, 0x6f, 0x67,
|
||||
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x7a, 0x75, 0x63, 0x68, 0x69, 0x6c, 0x61, 0x62, 0x73, 0x2f,
|
||||
0x6d, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65,
|
||||
0x6e, 0x2f, 0x6d, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x61, 0x6e,
|
||||
0x74, 0x72, 0x61, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x4d, 0x58, 0x58, 0xaa, 0x02, 0x0a, 0x4d,
|
||||
0x61, 0x6e, 0x74, 0x72, 0x61, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0a, 0x4d, 0x61, 0x6e, 0x74,
|
||||
0x72, 0x61, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x16, 0x4d, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x65,
|
||||
0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea,
|
||||
0x02, 0x0b, 0x4d, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
})
|
||||
|
||||
var (
|
||||
|
||||
@@ -483,12 +483,21 @@ components:
|
||||
- string
|
||||
title: profile_id
|
||||
format: int64
|
||||
profileName:
|
||||
type: string
|
||||
title: profile_name
|
||||
userId:
|
||||
type: string
|
||||
title: user_id
|
||||
userName:
|
||||
type: string
|
||||
title: user_name
|
||||
agentId:
|
||||
type: string
|
||||
title: agent_id
|
||||
agentName:
|
||||
type: string
|
||||
title: agent_name
|
||||
event:
|
||||
type: string
|
||||
title: event
|
||||
|
||||
@@ -14,11 +14,14 @@ service AuditLogService {
|
||||
message AuditLog {
|
||||
int64 id = 1;
|
||||
int64 profile_id = 2;
|
||||
string user_id = 3;
|
||||
string agent_id = 4;
|
||||
string event = 5;
|
||||
string details = 6;
|
||||
google.protobuf.Timestamp created_at = 7;
|
||||
string profile_name = 3;
|
||||
string user_id = 4;
|
||||
string user_name = 5;
|
||||
string agent_id = 6;
|
||||
string agent_name = 7;
|
||||
string event = 8;
|
||||
string details = 9;
|
||||
google.protobuf.Timestamp created_at = 10;
|
||||
}
|
||||
|
||||
message ListAuditLogsRequest {
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"prettier-plugin-svelte": "^3.4.0",
|
||||
"prettier-plugin-tailwindcss": "^0.6.13",
|
||||
"shiki": "^3.7.0",
|
||||
"svelte": "^5.34.9",
|
||||
"svelte": "^5.35.2",
|
||||
"svelte-check": "^4.2.2",
|
||||
"svelte-highlight": "^7.8.3",
|
||||
"svelte-sonner": "^1.0.5",
|
||||
@@ -43,12 +43,12 @@
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"tailwind-variants": "^1.0.0",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"tw-animate-css": "^1.3.4",
|
||||
"tw-animate-css": "^1.3.5",
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.35.1",
|
||||
"vite": "^6.3.5",
|
||||
"yaml": "^2.8.0",
|
||||
"zod": "^3.25.67"
|
||||
"zod": "^3.25.74"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
||||
383
web/pnpm-lock.yaml
generated
383
web/pnpm-lock.yaml
generated
@@ -32,16 +32,16 @@ importers:
|
||||
version: 3.8.2
|
||||
'@lucide/svelte':
|
||||
specifier: ^0.515.0
|
||||
version: 0.515.0(svelte@5.34.9)
|
||||
version: 0.515.0(svelte@5.35.2)
|
||||
'@sveltejs/adapter-static':
|
||||
specifier: ^3.0.8
|
||||
version: 3.0.8(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))
|
||||
version: 3.0.8(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))
|
||||
'@sveltejs/kit':
|
||||
specifier: ^2.22.2
|
||||
version: 2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
version: 2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
'@sveltejs/vite-plugin-svelte':
|
||||
specifier: ^5.1.0
|
||||
version: 5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
version: 5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
'@tailwindcss/vite':
|
||||
specifier: ^4.1.11
|
||||
version: 4.1.11(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
@@ -53,7 +53,7 @@ importers:
|
||||
version: 22.16.0
|
||||
bits-ui:
|
||||
specifier: 2.8.10
|
||||
version: 2.8.10(@internationalized/date@3.8.2)(svelte@5.34.9)
|
||||
version: 2.8.10(@internationalized/date@3.8.2)(svelte@5.35.2)
|
||||
clsx:
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1
|
||||
@@ -65,43 +65,43 @@ importers:
|
||||
version: 10.1.5(eslint@9.30.1(jiti@2.4.2))
|
||||
eslint-plugin-svelte:
|
||||
specifier: ^3.10.1
|
||||
version: 3.10.1(eslint@9.30.1(jiti@2.4.2))(svelte@5.34.9)
|
||||
version: 3.10.1(eslint@9.30.1(jiti@2.4.2))(svelte@5.35.2)
|
||||
formsnap:
|
||||
specifier: ^2.0.1
|
||||
version: 2.0.1(svelte@5.34.9)(sveltekit-superforms@2.27.1(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.34.9)(typescript@5.8.3))
|
||||
version: 2.0.1(svelte@5.35.2)(sveltekit-superforms@2.27.1(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.35.2)(typescript@5.8.3))
|
||||
globals:
|
||||
specifier: ^16.3.0
|
||||
version: 16.3.0
|
||||
mode-watcher:
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0(svelte@5.34.9)
|
||||
version: 1.1.0(svelte@5.35.2)
|
||||
prettier:
|
||||
specifier: ^3.6.2
|
||||
version: 3.6.2
|
||||
prettier-plugin-svelte:
|
||||
specifier: ^3.4.0
|
||||
version: 3.4.0(prettier@3.6.2)(svelte@5.34.9)
|
||||
version: 3.4.0(prettier@3.6.2)(svelte@5.35.2)
|
||||
prettier-plugin-tailwindcss:
|
||||
specifier: ^0.6.13
|
||||
version: 0.6.13(prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.34.9))(prettier@3.6.2)
|
||||
version: 0.6.13(prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.35.2))(prettier@3.6.2)
|
||||
shiki:
|
||||
specifier: ^3.7.0
|
||||
version: 3.7.0
|
||||
svelte:
|
||||
specifier: ^5.34.9
|
||||
version: 5.34.9
|
||||
specifier: ^5.35.2
|
||||
version: 5.35.2
|
||||
svelte-check:
|
||||
specifier: ^4.2.2
|
||||
version: 4.2.2(picomatch@4.0.2)(svelte@5.34.9)(typescript@5.8.3)
|
||||
version: 4.2.2(picomatch@4.0.2)(svelte@5.35.2)(typescript@5.8.3)
|
||||
svelte-highlight:
|
||||
specifier: ^7.8.3
|
||||
version: 7.8.3
|
||||
svelte-sonner:
|
||||
specifier: ^1.0.5
|
||||
version: 1.0.5(svelte@5.34.9)
|
||||
version: 1.0.5(svelte@5.35.2)
|
||||
sveltekit-superforms:
|
||||
specifier: ^2.27.1
|
||||
version: 2.27.1(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.34.9)(typescript@5.8.3)
|
||||
version: 2.27.1(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.35.2)(typescript@5.8.3)
|
||||
tailwind-merge:
|
||||
specifier: ^3.3.1
|
||||
version: 3.3.1
|
||||
@@ -112,8 +112,8 @@ importers:
|
||||
specifier: ^4.1.11
|
||||
version: 4.1.11
|
||||
tw-animate-css:
|
||||
specifier: ^1.3.4
|
||||
version: 1.3.4
|
||||
specifier: ^1.3.5
|
||||
version: 1.3.5
|
||||
typescript:
|
||||
specifier: ^5.8.3
|
||||
version: 5.8.3
|
||||
@@ -127,8 +127,8 @@ importers:
|
||||
specifier: ^2.8.0
|
||||
version: 2.8.0
|
||||
zod:
|
||||
specifier: ^3.25.67
|
||||
version: 3.25.67
|
||||
specifier: ^3.25.74
|
||||
version: 3.25.74
|
||||
|
||||
packages:
|
||||
|
||||
@@ -434,107 +434,106 @@ packages:
|
||||
'@polka/url@1.0.0-next.29':
|
||||
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
|
||||
|
||||
'@poppinss/macroable@1.0.4':
|
||||
resolution: {integrity: sha512-ct43jurbe7lsUX5eIrj4ijO3j/6zIPp7CDnFWXDs7UPAbw1Pu1iH3oAmFdP4jcskKJBURH5M9oTtyeiUXyHX8Q==}
|
||||
engines: {node: '>=18.16.0'}
|
||||
'@poppinss/macroable@1.0.5':
|
||||
resolution: {integrity: sha512-6u61y1HHd090MEk1Av0/1btDmm2Hh/+XoJj+HgFYRh9koUPI822ybJbwLHuqjLNCiY+o1gRykg2igEqOf/VBZw==}
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.44.1':
|
||||
resolution: {integrity: sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==}
|
||||
'@rollup/rollup-android-arm-eabi@4.44.2':
|
||||
resolution: {integrity: sha512-g0dF8P1e2QYPOj1gu7s/3LVP6kze9A7m6x0BZ9iTdXK8N5c2V7cpBKHV3/9A4Zd8xxavdhK0t4PnqjkqVmUc9Q==}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-android-arm64@4.44.1':
|
||||
resolution: {integrity: sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==}
|
||||
'@rollup/rollup-android-arm64@4.44.2':
|
||||
resolution: {integrity: sha512-Yt5MKrOosSbSaAK5Y4J+vSiID57sOvpBNBR6K7xAaQvk3MkcNVV0f9fE20T+41WYN8hDn6SGFlFrKudtx4EoxA==}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.44.1':
|
||||
resolution: {integrity: sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==}
|
||||
'@rollup/rollup-darwin-arm64@4.44.2':
|
||||
resolution: {integrity: sha512-EsnFot9ZieM35YNA26nhbLTJBHD0jTwWpPwmRVDzjylQT6gkar+zenfb8mHxWpRrbn+WytRRjE0WKsfaxBkVUA==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.44.1':
|
||||
resolution: {integrity: sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==}
|
||||
'@rollup/rollup-darwin-x64@4.44.2':
|
||||
resolution: {integrity: sha512-dv/t1t1RkCvJdWWxQ2lWOO+b7cMsVw5YFaS04oHpZRWehI1h0fV1gF4wgGCTyQHHjJDfbNpwOi6PXEafRBBezw==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.44.1':
|
||||
resolution: {integrity: sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==}
|
||||
'@rollup/rollup-freebsd-arm64@4.44.2':
|
||||
resolution: {integrity: sha512-W4tt4BLorKND4qeHElxDoim0+BsprFTwb+vriVQnFFtT/P6v/xO5I99xvYnVzKWrK6j7Hb0yp3x7V5LUbaeOMg==}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.44.1':
|
||||
resolution: {integrity: sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==}
|
||||
'@rollup/rollup-freebsd-x64@4.44.2':
|
||||
resolution: {integrity: sha512-tdT1PHopokkuBVyHjvYehnIe20fxibxFCEhQP/96MDSOcyjM/shlTkZZLOufV3qO6/FQOSiJTBebhVc12JyPTA==}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.44.1':
|
||||
resolution: {integrity: sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==}
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.44.2':
|
||||
resolution: {integrity: sha512-+xmiDGGaSfIIOXMzkhJ++Oa0Gwvl9oXUeIiwarsdRXSe27HUIvjbSIpPxvnNsRebsNdUo7uAiQVgBD1hVriwSQ==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.44.1':
|
||||
resolution: {integrity: sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==}
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.44.2':
|
||||
resolution: {integrity: sha512-bDHvhzOfORk3wt8yxIra8N4k/N0MnKInCW5OGZaeDYa/hMrdPaJzo7CSkjKZqX4JFUWjUGm88lI6QJLCM7lDrA==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.44.1':
|
||||
resolution: {integrity: sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==}
|
||||
'@rollup/rollup-linux-arm64-gnu@4.44.2':
|
||||
resolution: {integrity: sha512-NMsDEsDiYghTbeZWEGnNi4F0hSbGnsuOG+VnNvxkKg0IGDvFh7UVpM/14mnMwxRxUf9AdAVJgHPvKXf6FpMB7A==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.44.1':
|
||||
resolution: {integrity: sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==}
|
||||
'@rollup/rollup-linux-arm64-musl@4.44.2':
|
||||
resolution: {integrity: sha512-lb5bxXnxXglVq+7imxykIp5xMq+idehfl+wOgiiix0191av84OqbjUED+PRC5OA8eFJYj5xAGcpAZ0pF2MnW+A==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-loongarch64-gnu@4.44.1':
|
||||
resolution: {integrity: sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==}
|
||||
'@rollup/rollup-linux-loongarch64-gnu@4.44.2':
|
||||
resolution: {integrity: sha512-Yl5Rdpf9pIc4GW1PmkUGHdMtbx0fBLE1//SxDmuf3X0dUC57+zMepow2LK0V21661cjXdTn8hO2tXDdAWAqE5g==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-powerpc64le-gnu@4.44.1':
|
||||
resolution: {integrity: sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==}
|
||||
'@rollup/rollup-linux-powerpc64le-gnu@4.44.2':
|
||||
resolution: {integrity: sha512-03vUDH+w55s680YYryyr78jsO1RWU9ocRMaeV2vMniJJW/6HhoTBwyyiiTPVHNWLnhsnwcQ0oH3S9JSBEKuyqw==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.44.1':
|
||||
resolution: {integrity: sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==}
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.44.2':
|
||||
resolution: {integrity: sha512-iYtAqBg5eEMG4dEfVlkqo05xMOk6y/JXIToRca2bAWuqjrJYJlx/I7+Z+4hSrsWU8GdJDFPL4ktV3dy4yBSrzg==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.44.1':
|
||||
resolution: {integrity: sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==}
|
||||
'@rollup/rollup-linux-riscv64-musl@4.44.2':
|
||||
resolution: {integrity: sha512-e6vEbgaaqz2yEHqtkPXa28fFuBGmUJ0N2dOJK8YUfijejInt9gfCSA7YDdJ4nYlv67JfP3+PSWFX4IVw/xRIPg==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.44.1':
|
||||
resolution: {integrity: sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==}
|
||||
'@rollup/rollup-linux-s390x-gnu@4.44.2':
|
||||
resolution: {integrity: sha512-evFOtkmVdY3udE+0QKrV5wBx7bKI0iHz5yEVx5WqDJkxp9YQefy4Mpx3RajIVcM6o7jxTvVd/qpC1IXUhGc1Mw==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.44.1':
|
||||
resolution: {integrity: sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==}
|
||||
'@rollup/rollup-linux-x64-gnu@4.44.2':
|
||||
resolution: {integrity: sha512-/bXb0bEsWMyEkIsUL2Yt5nFB5naLAwyOWMEviQfQY1x3l5WsLKgvZf66TM7UTfED6erckUVUJQ/jJ1FSpm3pRQ==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.44.1':
|
||||
resolution: {integrity: sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==}
|
||||
'@rollup/rollup-linux-x64-musl@4.44.2':
|
||||
resolution: {integrity: sha512-3D3OB1vSSBXmkGEZR27uiMRNiwN08/RVAcBKwhUYPaiZ8bcvdeEwWPvbnXvvXHY+A/7xluzcN+kaiOFNiOZwWg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.44.1':
|
||||
resolution: {integrity: sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==}
|
||||
'@rollup/rollup-win32-arm64-msvc@4.44.2':
|
||||
resolution: {integrity: sha512-VfU0fsMK+rwdK8mwODqYeM2hDrF2WiHaSmCBrS7gColkQft95/8tphyzv2EupVxn3iE0FI78wzffoULH1G+dkw==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.44.1':
|
||||
resolution: {integrity: sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==}
|
||||
'@rollup/rollup-win32-ia32-msvc@4.44.2':
|
||||
resolution: {integrity: sha512-+qMUrkbUurpE6DVRjiJCNGZBGo9xM4Y0FXU5cjgudWqIBWbcLkjE3XprJUsOFgC6xjBClwVa9k6O3A7K3vxb5Q==}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.44.1':
|
||||
resolution: {integrity: sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug==}
|
||||
'@rollup/rollup-win32-x64-msvc@4.44.2':
|
||||
resolution: {integrity: sha512-3+QZROYfJ25PDcxFF66UEk8jGWigHJeecZILvkPkyQN7oc5BvFo4YEXFkOs154j3FTMp9mn9Ky8RCOwastduEA==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
@@ -974,8 +973,8 @@ packages:
|
||||
dlv@1.1.3:
|
||||
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
|
||||
|
||||
effect@3.16.10:
|
||||
resolution: {integrity: sha512-F0hDCOLax7i3SOy5wQnJZTzKP9aGg8OQNUJ2s8YoL5fVcCgRCgE+Ky+Hfz5qC7LgVVOWDDbRpCh5MPB20wRI8Q==}
|
||||
effect@3.16.12:
|
||||
resolution: {integrity: sha512-N39iBk0K71F9nb442TLbTkjl24FLUzuvx2i1I2RsEAQsdAdUTuUoW0vlfUXgkMTUOnYqKnWcFfqw4hK4Pw27hg==}
|
||||
|
||||
enhanced-resolve@5.18.2:
|
||||
resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==}
|
||||
@@ -1045,8 +1044,8 @@ packages:
|
||||
resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
|
||||
engines: {node: '>=0.10'}
|
||||
|
||||
esrap@1.4.9:
|
||||
resolution: {integrity: sha512-3OMlcd0a03UGuZpPeUC1HxR3nA23l+HEyCiZw3b3FumJIN9KphoGzDJKMXI1S72jVS1dsenDyQC0kJlO1U9E1g==}
|
||||
esrap@2.1.0:
|
||||
resolution: {integrity: sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==}
|
||||
|
||||
esrecurse@4.3.0:
|
||||
resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
|
||||
@@ -1577,8 +1576,8 @@ packages:
|
||||
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
|
||||
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
|
||||
|
||||
rollup@4.44.1:
|
||||
resolution: {integrity: sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==}
|
||||
rollup@4.44.2:
|
||||
resolution: {integrity: sha512-PVoapzTwSEcelaWGth3uR66u7ZRo6qhPHc0f2uRO9fX6XDVNrIiGYS0Pj9+R8yIIYSD/mCx2b16Ws9itljKSPg==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
@@ -1707,8 +1706,8 @@ packages:
|
||||
peerDependencies:
|
||||
svelte: ^5.30.2
|
||||
|
||||
svelte@5.34.9:
|
||||
resolution: {integrity: sha512-sld35zFpooaSRSj4qw8Vl/cyyK0/sLQq9qhJ7BGZo/Kd0ggYtEnvNYLlzhhoqYsYQzA0hJqkzt3RBO/8KoTZOg==}
|
||||
svelte@5.35.2:
|
||||
resolution: {integrity: sha512-uW/rRXYrhZ7Dh4UQNZ0t+oVGL1dEM+95GavCO8afAk1IY2cPq9BcZv9C3um5aLIya2y8lIeLPxLII9ASGg9Dzw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
sveltekit-superforms@2.27.1:
|
||||
@@ -1783,8 +1782,8 @@ packages:
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
tw-animate-css@1.3.4:
|
||||
resolution: {integrity: sha512-dd1Ht6/YQHcNbq0znIT6dG8uhO7Ce+VIIhZUhjsryXsMPJQz3bZg7Q2eNzLwipb25bRZslGb2myio5mScd1TFg==}
|
||||
tw-animate-css@1.3.5:
|
||||
resolution: {integrity: sha512-t3u+0YNoloIhj1mMXs779P6MO9q3p3mvGn4k1n3nJPqJw/glZcuijG2qTSN4z4mgNRfW5ZC3aXJFLwDtiipZXA==}
|
||||
|
||||
type-check@0.4.0:
|
||||
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
||||
@@ -1896,8 +1895,8 @@ packages:
|
||||
yaml:
|
||||
optional: true
|
||||
|
||||
vitefu@1.0.7:
|
||||
resolution: {integrity: sha512-eRWXLBbJjW3X5z5P5IHcSm2yYbYRPb2kQuc+oqsbAl99WB5kVsPbiiox+cymo8twTzifA6itvhr2CmjnaZZp0Q==}
|
||||
vitefu@1.1.1:
|
||||
resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==}
|
||||
peerDependencies:
|
||||
vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0
|
||||
peerDependenciesMeta:
|
||||
@@ -1941,8 +1940,8 @@ packages:
|
||||
peerDependencies:
|
||||
zod: ^3.24.1
|
||||
|
||||
zod@3.25.67:
|
||||
resolution: {integrity: sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==}
|
||||
zod@3.25.74:
|
||||
resolution: {integrity: sha512-J8poo92VuhKjNknViHRAIuuN6li/EwFbAC8OedzI8uxpEPGiXHGQu9wemIAioIpqgfB4SySaJhdk0mH5Y4ICBg==}
|
||||
|
||||
zwitch@2.0.4:
|
||||
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
|
||||
@@ -2167,9 +2166,9 @@ snapshots:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.5.4
|
||||
|
||||
'@lucide/svelte@0.515.0(svelte@5.34.9)':
|
||||
'@lucide/svelte@0.515.0(svelte@5.35.2)':
|
||||
dependencies:
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
|
||||
'@nodelib/fs.scandir@2.1.5':
|
||||
dependencies:
|
||||
@@ -2185,67 +2184,67 @@ snapshots:
|
||||
|
||||
'@polka/url@1.0.0-next.29': {}
|
||||
|
||||
'@poppinss/macroable@1.0.4':
|
||||
'@poppinss/macroable@1.0.5':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.44.1':
|
||||
'@rollup/rollup-android-arm-eabi@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm64@4.44.1':
|
||||
'@rollup/rollup-android-arm64@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.44.1':
|
||||
'@rollup/rollup-darwin-arm64@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.44.1':
|
||||
'@rollup/rollup-darwin-x64@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.44.1':
|
||||
'@rollup/rollup-freebsd-arm64@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.44.1':
|
||||
'@rollup/rollup-freebsd-x64@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.44.1':
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.44.1':
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.44.1':
|
||||
'@rollup/rollup-linux-arm64-gnu@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.44.1':
|
||||
'@rollup/rollup-linux-arm64-musl@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-loongarch64-gnu@4.44.1':
|
||||
'@rollup/rollup-linux-loongarch64-gnu@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-powerpc64le-gnu@4.44.1':
|
||||
'@rollup/rollup-linux-powerpc64le-gnu@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.44.1':
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.44.1':
|
||||
'@rollup/rollup-linux-riscv64-musl@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.44.1':
|
||||
'@rollup/rollup-linux-s390x-gnu@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.44.1':
|
||||
'@rollup/rollup-linux-x64-gnu@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.44.1':
|
||||
'@rollup/rollup-linux-x64-musl@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.44.1':
|
||||
'@rollup/rollup-win32-arm64-msvc@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.44.1':
|
||||
'@rollup/rollup-win32-ia32-msvc@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.44.1':
|
||||
'@rollup/rollup-win32-x64-msvc@4.44.2':
|
||||
optional: true
|
||||
|
||||
'@shikijs/core@3.7.0':
|
||||
@@ -2302,14 +2301,14 @@ snapshots:
|
||||
dependencies:
|
||||
acorn: 8.15.0
|
||||
|
||||
'@sveltejs/adapter-static@3.0.8(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))':
|
||||
'@sveltejs/adapter-static@3.0.8(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))':
|
||||
dependencies:
|
||||
'@sveltejs/kit': 2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
'@sveltejs/kit': 2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
|
||||
'@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))':
|
||||
'@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))':
|
||||
dependencies:
|
||||
'@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0)
|
||||
'@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
'@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
'@types/cookie': 0.6.0
|
||||
acorn: 8.15.0
|
||||
cookie: 0.6.0
|
||||
@@ -2321,29 +2320,29 @@ snapshots:
|
||||
sade: 1.8.1
|
||||
set-cookie-parser: 2.7.1
|
||||
sirv: 3.0.1
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
vite: 6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
vitefu: 1.0.7(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
vitefu: 1.1.1(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
|
||||
'@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))':
|
||||
'@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))':
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
'@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
debug: 4.4.1
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
vite: 6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))':
|
||||
'@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))':
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
'@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
debug: 4.4.1
|
||||
deepmerge: 4.3.1
|
||||
kleur: 4.1.5
|
||||
magic-string: 0.30.17
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
vite: 6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
vitefu: 1.0.7(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
vitefu: 1.1.1(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -2569,7 +2568,7 @@ snapshots:
|
||||
|
||||
'@vinejs/vine@3.0.1':
|
||||
dependencies:
|
||||
'@poppinss/macroable': 1.0.4
|
||||
'@poppinss/macroable': 1.0.5
|
||||
'@types/validator': 13.15.2
|
||||
'@vinejs/compiler': 3.0.0
|
||||
camelcase: 8.0.0
|
||||
@@ -2610,15 +2609,15 @@ snapshots:
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
bits-ui@2.8.10(@internationalized/date@3.8.2)(svelte@5.34.9):
|
||||
bits-ui@2.8.10(@internationalized/date@3.8.2)(svelte@5.35.2):
|
||||
dependencies:
|
||||
'@floating-ui/core': 1.7.2
|
||||
'@floating-ui/dom': 1.7.2
|
||||
'@internationalized/date': 3.8.2
|
||||
esm-env: 1.2.2
|
||||
runed: 0.29.1(svelte@5.34.9)
|
||||
svelte: 5.34.9
|
||||
svelte-toolbelt: 0.9.3(svelte@5.34.9)
|
||||
runed: 0.29.1(svelte@5.35.2)
|
||||
svelte: 5.35.2
|
||||
svelte-toolbelt: 0.9.3(svelte@5.35.2)
|
||||
tabbable: 6.2.0
|
||||
|
||||
brace-expansion@1.1.12:
|
||||
@@ -2712,7 +2711,7 @@ snapshots:
|
||||
dlv@1.1.3:
|
||||
optional: true
|
||||
|
||||
effect@3.16.10:
|
||||
effect@3.16.12:
|
||||
dependencies:
|
||||
'@standard-schema/spec': 1.0.0
|
||||
fast-check: 3.23.2
|
||||
@@ -2764,7 +2763,7 @@ snapshots:
|
||||
dependencies:
|
||||
eslint: 9.30.1(jiti@2.4.2)
|
||||
|
||||
eslint-plugin-svelte@3.10.1(eslint@9.30.1(jiti@2.4.2))(svelte@5.34.9):
|
||||
eslint-plugin-svelte@3.10.1(eslint@9.30.1(jiti@2.4.2))(svelte@5.35.2):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2))
|
||||
'@jridgewell/sourcemap-codec': 1.5.4
|
||||
@@ -2776,9 +2775,9 @@ snapshots:
|
||||
postcss-load-config: 3.1.4(postcss@8.5.6)
|
||||
postcss-safe-parser: 7.0.1(postcss@8.5.6)
|
||||
semver: 7.7.2
|
||||
svelte-eslint-parser: 1.2.0(svelte@5.34.9)
|
||||
svelte-eslint-parser: 1.2.0(svelte@5.35.2)
|
||||
optionalDependencies:
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
transitivePeerDependencies:
|
||||
- ts-node
|
||||
|
||||
@@ -2845,7 +2844,7 @@ snapshots:
|
||||
dependencies:
|
||||
estraverse: 5.3.0
|
||||
|
||||
esrap@1.4.9:
|
||||
esrap@2.1.0:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.4
|
||||
|
||||
@@ -2904,11 +2903,11 @@ snapshots:
|
||||
|
||||
flatted@3.3.3: {}
|
||||
|
||||
formsnap@2.0.1(svelte@5.34.9)(sveltekit-superforms@2.27.1(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.34.9)(typescript@5.8.3)):
|
||||
formsnap@2.0.1(svelte@5.35.2)(sveltekit-superforms@2.27.1(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.35.2)(typescript@5.8.3)):
|
||||
dependencies:
|
||||
svelte: 5.34.9
|
||||
svelte-toolbelt: 0.5.0(svelte@5.34.9)
|
||||
sveltekit-superforms: 2.27.1(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.34.9)(typescript@5.8.3)
|
||||
svelte: 5.35.2
|
||||
svelte-toolbelt: 0.5.0(svelte@5.35.2)
|
||||
sveltekit-superforms: 2.27.1(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.35.2)(typescript@5.8.3)
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
@@ -3136,11 +3135,11 @@ snapshots:
|
||||
|
||||
mkdirp@3.0.1: {}
|
||||
|
||||
mode-watcher@1.1.0(svelte@5.34.9):
|
||||
mode-watcher@1.1.0(svelte@5.35.2):
|
||||
dependencies:
|
||||
runed: 0.25.0(svelte@5.34.9)
|
||||
svelte: 5.34.9
|
||||
svelte-toolbelt: 0.7.1(svelte@5.34.9)
|
||||
runed: 0.25.0(svelte@5.35.2)
|
||||
svelte: 5.35.2
|
||||
svelte-toolbelt: 0.7.1(svelte@5.35.2)
|
||||
|
||||
mri@1.2.0: {}
|
||||
|
||||
@@ -3222,16 +3221,16 @@ snapshots:
|
||||
|
||||
prelude-ls@1.2.1: {}
|
||||
|
||||
prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.34.9):
|
||||
prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.35.2):
|
||||
dependencies:
|
||||
prettier: 3.6.2
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
|
||||
prettier-plugin-tailwindcss@0.6.13(prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.34.9))(prettier@3.6.2):
|
||||
prettier-plugin-tailwindcss@0.6.13(prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.35.2))(prettier@3.6.2):
|
||||
dependencies:
|
||||
prettier: 3.6.2
|
||||
optionalDependencies:
|
||||
prettier-plugin-svelte: 3.4.0(prettier@3.6.2)(svelte@5.34.9)
|
||||
prettier-plugin-svelte: 3.4.0(prettier@3.6.2)(svelte@5.35.2)
|
||||
|
||||
prettier@3.6.2: {}
|
||||
|
||||
@@ -3265,55 +3264,55 @@ snapshots:
|
||||
|
||||
reusify@1.1.0: {}
|
||||
|
||||
rollup@4.44.1:
|
||||
rollup@4.44.2:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
optionalDependencies:
|
||||
'@rollup/rollup-android-arm-eabi': 4.44.1
|
||||
'@rollup/rollup-android-arm64': 4.44.1
|
||||
'@rollup/rollup-darwin-arm64': 4.44.1
|
||||
'@rollup/rollup-darwin-x64': 4.44.1
|
||||
'@rollup/rollup-freebsd-arm64': 4.44.1
|
||||
'@rollup/rollup-freebsd-x64': 4.44.1
|
||||
'@rollup/rollup-linux-arm-gnueabihf': 4.44.1
|
||||
'@rollup/rollup-linux-arm-musleabihf': 4.44.1
|
||||
'@rollup/rollup-linux-arm64-gnu': 4.44.1
|
||||
'@rollup/rollup-linux-arm64-musl': 4.44.1
|
||||
'@rollup/rollup-linux-loongarch64-gnu': 4.44.1
|
||||
'@rollup/rollup-linux-powerpc64le-gnu': 4.44.1
|
||||
'@rollup/rollup-linux-riscv64-gnu': 4.44.1
|
||||
'@rollup/rollup-linux-riscv64-musl': 4.44.1
|
||||
'@rollup/rollup-linux-s390x-gnu': 4.44.1
|
||||
'@rollup/rollup-linux-x64-gnu': 4.44.1
|
||||
'@rollup/rollup-linux-x64-musl': 4.44.1
|
||||
'@rollup/rollup-win32-arm64-msvc': 4.44.1
|
||||
'@rollup/rollup-win32-ia32-msvc': 4.44.1
|
||||
'@rollup/rollup-win32-x64-msvc': 4.44.1
|
||||
'@rollup/rollup-android-arm-eabi': 4.44.2
|
||||
'@rollup/rollup-android-arm64': 4.44.2
|
||||
'@rollup/rollup-darwin-arm64': 4.44.2
|
||||
'@rollup/rollup-darwin-x64': 4.44.2
|
||||
'@rollup/rollup-freebsd-arm64': 4.44.2
|
||||
'@rollup/rollup-freebsd-x64': 4.44.2
|
||||
'@rollup/rollup-linux-arm-gnueabihf': 4.44.2
|
||||
'@rollup/rollup-linux-arm-musleabihf': 4.44.2
|
||||
'@rollup/rollup-linux-arm64-gnu': 4.44.2
|
||||
'@rollup/rollup-linux-arm64-musl': 4.44.2
|
||||
'@rollup/rollup-linux-loongarch64-gnu': 4.44.2
|
||||
'@rollup/rollup-linux-powerpc64le-gnu': 4.44.2
|
||||
'@rollup/rollup-linux-riscv64-gnu': 4.44.2
|
||||
'@rollup/rollup-linux-riscv64-musl': 4.44.2
|
||||
'@rollup/rollup-linux-s390x-gnu': 4.44.2
|
||||
'@rollup/rollup-linux-x64-gnu': 4.44.2
|
||||
'@rollup/rollup-linux-x64-musl': 4.44.2
|
||||
'@rollup/rollup-win32-arm64-msvc': 4.44.2
|
||||
'@rollup/rollup-win32-ia32-msvc': 4.44.2
|
||||
'@rollup/rollup-win32-x64-msvc': 4.44.2
|
||||
fsevents: 2.3.3
|
||||
|
||||
run-parallel@1.2.0:
|
||||
dependencies:
|
||||
queue-microtask: 1.2.3
|
||||
|
||||
runed@0.23.4(svelte@5.34.9):
|
||||
runed@0.23.4(svelte@5.35.2):
|
||||
dependencies:
|
||||
esm-env: 1.2.2
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
|
||||
runed@0.25.0(svelte@5.34.9):
|
||||
runed@0.25.0(svelte@5.35.2):
|
||||
dependencies:
|
||||
esm-env: 1.2.2
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
|
||||
runed@0.28.0(svelte@5.34.9):
|
||||
runed@0.28.0(svelte@5.35.2):
|
||||
dependencies:
|
||||
esm-env: 1.2.2
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
|
||||
runed@0.29.1(svelte@5.34.9):
|
||||
runed@0.29.1(svelte@5.35.2):
|
||||
dependencies:
|
||||
esm-env: 1.2.2
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
|
||||
sade@1.8.1:
|
||||
dependencies:
|
||||
@@ -3377,19 +3376,19 @@ snapshots:
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
|
||||
svelte-check@4.2.2(picomatch@4.0.2)(svelte@5.34.9)(typescript@5.8.3):
|
||||
svelte-check@4.2.2(picomatch@4.0.2)(svelte@5.35.2)(typescript@5.8.3):
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.29
|
||||
chokidar: 4.0.3
|
||||
fdir: 6.4.6(picomatch@4.0.2)
|
||||
picocolors: 1.1.1
|
||||
sade: 1.8.1
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
typescript: 5.8.3
|
||||
transitivePeerDependencies:
|
||||
- picomatch
|
||||
|
||||
svelte-eslint-parser@1.2.0(svelte@5.34.9):
|
||||
svelte-eslint-parser@1.2.0(svelte@5.35.2):
|
||||
dependencies:
|
||||
eslint-scope: 8.4.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
@@ -3398,38 +3397,38 @@ snapshots:
|
||||
postcss-scss: 4.0.9(postcss@8.5.6)
|
||||
postcss-selector-parser: 7.1.0
|
||||
optionalDependencies:
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
|
||||
svelte-highlight@7.8.3:
|
||||
dependencies:
|
||||
highlight.js: 11.11.1
|
||||
|
||||
svelte-sonner@1.0.5(svelte@5.34.9):
|
||||
svelte-sonner@1.0.5(svelte@5.35.2):
|
||||
dependencies:
|
||||
runed: 0.28.0(svelte@5.34.9)
|
||||
svelte: 5.34.9
|
||||
runed: 0.28.0(svelte@5.35.2)
|
||||
svelte: 5.35.2
|
||||
|
||||
svelte-toolbelt@0.5.0(svelte@5.34.9):
|
||||
svelte-toolbelt@0.5.0(svelte@5.35.2):
|
||||
dependencies:
|
||||
clsx: 2.1.1
|
||||
style-to-object: 1.0.9
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
|
||||
svelte-toolbelt@0.7.1(svelte@5.34.9):
|
||||
svelte-toolbelt@0.7.1(svelte@5.35.2):
|
||||
dependencies:
|
||||
clsx: 2.1.1
|
||||
runed: 0.23.4(svelte@5.34.9)
|
||||
runed: 0.23.4(svelte@5.35.2)
|
||||
style-to-object: 1.0.9
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
|
||||
svelte-toolbelt@0.9.3(svelte@5.34.9):
|
||||
svelte-toolbelt@0.9.3(svelte@5.35.2):
|
||||
dependencies:
|
||||
clsx: 2.1.1
|
||||
runed: 0.29.1(svelte@5.34.9)
|
||||
runed: 0.29.1(svelte@5.35.2)
|
||||
style-to-object: 1.0.9
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
|
||||
svelte@5.34.9:
|
||||
svelte@5.35.2:
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.3.0
|
||||
'@jridgewell/sourcemap-codec': 1.5.4
|
||||
@@ -3440,18 +3439,18 @@ snapshots:
|
||||
axobject-query: 4.1.0
|
||||
clsx: 2.1.1
|
||||
esm-env: 1.2.2
|
||||
esrap: 1.4.9
|
||||
esrap: 2.1.0
|
||||
is-reference: 3.0.3
|
||||
locate-character: 3.0.0
|
||||
magic-string: 0.30.17
|
||||
zimmerframe: 1.1.2
|
||||
|
||||
sveltekit-superforms@2.27.1(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.34.9)(typescript@5.8.3):
|
||||
sveltekit-superforms@2.27.1(@sveltejs/kit@2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.35.2)(typescript@5.8.3):
|
||||
dependencies:
|
||||
'@sveltejs/kit': 2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.9)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
'@sveltejs/kit': 2.22.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.2)(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))
|
||||
devalue: 5.1.1
|
||||
memoize-weak: 1.0.2
|
||||
svelte: 5.34.9
|
||||
svelte: 5.35.2
|
||||
ts-deepmerge: 7.0.3
|
||||
optionalDependencies:
|
||||
'@exodus/schemasafe': 1.3.0
|
||||
@@ -3461,14 +3460,14 @@ snapshots:
|
||||
'@vinejs/vine': 3.0.1
|
||||
arktype: 2.1.20
|
||||
class-validator: 0.14.2
|
||||
effect: 3.16.10
|
||||
effect: 3.16.12
|
||||
joi: 17.13.3
|
||||
json-schema-to-ts: 3.1.1
|
||||
superstruct: 2.0.2
|
||||
valibot: 1.1.0(typescript@5.8.3)
|
||||
yup: 1.6.1
|
||||
zod: 3.25.67
|
||||
zod-to-json-schema: 3.24.6(zod@3.25.67)
|
||||
zod: 3.25.74
|
||||
zod-to-json-schema: 3.24.6(zod@3.25.74)
|
||||
transitivePeerDependencies:
|
||||
- '@types/json-schema'
|
||||
- esbuild
|
||||
@@ -3531,7 +3530,7 @@ snapshots:
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
tw-animate-css@1.3.4: {}
|
||||
tw-animate-css@1.3.5: {}
|
||||
|
||||
type-check@0.4.0:
|
||||
dependencies:
|
||||
@@ -3612,7 +3611,7 @@ snapshots:
|
||||
fdir: 6.4.6(picomatch@4.0.2)
|
||||
picomatch: 4.0.2
|
||||
postcss: 8.5.6
|
||||
rollup: 4.44.1
|
||||
rollup: 4.44.2
|
||||
tinyglobby: 0.2.14
|
||||
optionalDependencies:
|
||||
'@types/node': 22.16.0
|
||||
@@ -3621,7 +3620,7 @@ snapshots:
|
||||
lightningcss: 1.30.1
|
||||
yaml: 2.8.0
|
||||
|
||||
vitefu@1.0.7(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)):
|
||||
vitefu@1.1.1(vite@6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)):
|
||||
optionalDependencies:
|
||||
vite: 6.3.5(@types/node@22.16.0)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)
|
||||
|
||||
@@ -3649,11 +3648,11 @@ snapshots:
|
||||
|
||||
zimmerframe@1.1.2: {}
|
||||
|
||||
zod-to-json-schema@3.24.6(zod@3.25.67):
|
||||
zod-to-json-schema@3.24.6(zod@3.25.74):
|
||||
dependencies:
|
||||
zod: 3.25.67
|
||||
zod: 3.25.74
|
||||
optional: true
|
||||
|
||||
zod@3.25.67: {}
|
||||
zod@3.25.74: {}
|
||||
|
||||
zwitch@2.0.4: {}
|
||||
|
||||
82
web/src/lib/components/modals/AuditLogModal.svelte
Normal file
82
web/src/lib/components/modals/AuditLogModal.svelte
Normal file
@@ -0,0 +1,82 @@
|
||||
<script lang="ts">
|
||||
import * as Dialog from '$lib/components/ui/dialog/index.js';
|
||||
import { auditLogClient } from '$lib/api';
|
||||
import { timestampDate, type Timestamp } from '@bufbuild/protobuf/wkt';
|
||||
import Separator from '../ui/separator/separator.svelte';
|
||||
|
||||
interface Props {
|
||||
open?: boolean;
|
||||
}
|
||||
let { open = $bindable(false) }: Props = $props();
|
||||
|
||||
function timeAgo(date: Timestamp) {
|
||||
const dateTime = new Date(timestampDate(date));
|
||||
const seconds = Math.floor((new Date().getTime() - dateTime.getTime()) / 1000);
|
||||
|
||||
if (seconds < 60) return `${seconds} second${seconds !== 1 ? 's' : ''} ago`;
|
||||
|
||||
const intervals = [
|
||||
{ label: 'year', seconds: 31536000 },
|
||||
{ label: 'month', seconds: 2592000 },
|
||||
{ label: 'day', seconds: 86400 },
|
||||
{ label: 'hour', seconds: 3600 },
|
||||
{ label: 'minute', seconds: 60 }
|
||||
];
|
||||
|
||||
for (const interval of intervals) {
|
||||
const count = Math.floor(seconds / interval.seconds);
|
||||
if (count >= 1) {
|
||||
return `${count} ${interval.label}${count !== 1 ? 's' : ''} ago`;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog.Root bind:open>
|
||||
<Dialog.Content
|
||||
class="max-h-[90vh] w-fit max-w-[90vw] overflow-y-auto px-4 py-2 sm:min-w-[40rem]"
|
||||
>
|
||||
<Dialog.Header class="flex justify-between gap-2 py-4">
|
||||
<Dialog.Title>Audit Logs</Dialog.Title>
|
||||
</Dialog.Header>
|
||||
<div class="space-y-3 text-sm">
|
||||
{#await auditLogClient.listAuditLogs({ limit: 1000n, offset: 0n }) then result}
|
||||
{#each result.auditLogs || [] as log (log.id)}
|
||||
<div class="flex items-center justify-start gap-3">
|
||||
{#if log.agentId}
|
||||
<div class="mt-2 h-2 w-2 rounded-full bg-blue-500"></div>
|
||||
{:else if log.userId}
|
||||
<div class="mt-2 h-2 w-2 rounded-full bg-green-500"></div>
|
||||
{:else}
|
||||
<div class="mt-2 h-2 w-2 rounded-full bg-orange-500"></div>
|
||||
{/if}
|
||||
<div>
|
||||
<p class="text-sm">{log.details}</p>
|
||||
|
||||
<div class="text-muted-foreground flex items-center gap-2 text-xs">
|
||||
{#if log.createdAt}
|
||||
<span class="text-muted-foreground text-xs">
|
||||
{timeAgo(log.createdAt)}
|
||||
</span>
|
||||
{/if}
|
||||
{#if log.agentId}
|
||||
<span class="rounded bg-blue-100 px-1.5 py-0.5 text-blue-700" title={log.agentId}>
|
||||
Agent: {log.agentName || `...${log.agentId.slice(-8)}`}
|
||||
</span>
|
||||
{:else if log.userId}
|
||||
<span
|
||||
class="rounded bg-green-100 px-1.5 py-0.5 text-green-700"
|
||||
title={log.userId}
|
||||
>
|
||||
User: {log.userName || `...${log.userId.slice(-8)}`}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Separator />
|
||||
{/each}
|
||||
{/await}
|
||||
</div>
|
||||
</Dialog.Content>
|
||||
</Dialog.Root>
|
||||
@@ -9,16 +9,14 @@
|
||||
import { Label } from '$lib/components/ui/label';
|
||||
import * as Select from '$lib/components/ui/select/index.js';
|
||||
import * as Tabs from '$lib/components/ui/tabs/index.js';
|
||||
import * as Tooltip from '$lib/components/ui/tooltip/index.js';
|
||||
import { RouterType, type Router } from '$lib/gen/mantrae/v1/router_pb';
|
||||
import { ServiceType, type Service } from '$lib/gen/mantrae/v1/service_pb';
|
||||
import { pageIndex, pageSize } from '$lib/stores/common';
|
||||
import { profile } from '$lib/stores/profile';
|
||||
import { routerTypes, unmarshalConfig } from '$lib/types';
|
||||
import { ConnectError } from '@connectrpc/connect';
|
||||
import { Bot, CircleCheck, Globe } from '@lucide/svelte';
|
||||
import { Bot } from '@lucide/svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
||||
import type {
|
||||
Service as HTTPService,
|
||||
TCPService,
|
||||
@@ -40,14 +38,20 @@
|
||||
|
||||
let { data = $bindable(), item = $bindable(), open = $bindable(false) }: Props = $props();
|
||||
let service = $state({} as Service);
|
||||
let hasLoadedService = $state(false);
|
||||
|
||||
// Reset state when modal closes
|
||||
$effect(() => {
|
||||
if (!open) {
|
||||
service = {} as Service;
|
||||
hasLoadedService = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Only fetch service when modal opens with existing router (once)
|
||||
$effect(() => {
|
||||
if (item.id && open) {
|
||||
if (item.id && open && !hasLoadedService) {
|
||||
hasLoadedService = true;
|
||||
serviceClient
|
||||
.getServiceByRouter({
|
||||
name: item.name,
|
||||
@@ -55,6 +59,9 @@
|
||||
})
|
||||
.then((data) => {
|
||||
service = data.service ?? ({} as Service);
|
||||
})
|
||||
.catch(() => {
|
||||
service = {} as Service;
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -143,38 +150,13 @@
|
||||
try {
|
||||
await routerClient.deleteRouter({ id: item.id, type: item.type });
|
||||
toast.success('Router deleted successfully');
|
||||
|
||||
// Refresh data
|
||||
let response = await routerClient.listRouters({
|
||||
profileId: profile.id,
|
||||
limit: BigInt(pageSize.value ?? 10),
|
||||
offset: BigInt(pageIndex.value ?? 0)
|
||||
});
|
||||
data = response.routers;
|
||||
data = data.filter((r) => r.id !== item.id);
|
||||
} catch (err) {
|
||||
const e = ConnectError.from(err);
|
||||
toast.error('Failed to delete router', { description: e.message });
|
||||
}
|
||||
open = false;
|
||||
};
|
||||
|
||||
let dnsAnchor = $state({} as HTMLElement);
|
||||
let selectDNSOpen = $state(false);
|
||||
|
||||
async function handleDNSProviderChange(value: string[]) {
|
||||
if (value.length === 0) item.dnsProviders = [];
|
||||
const result = await dnsClient.listDnsProviders({ limit: -1n, offset: 0n });
|
||||
item.dnsProviders = result.dnsProviders.filter((p) => value.includes(p.id.toString()));
|
||||
await routerClient.updateRouter({
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
config: item.config,
|
||||
enabled: item.enabled,
|
||||
type: item.type,
|
||||
dnsProviders: item.dnsProviders
|
||||
});
|
||||
toast.success(`Router ${item.name} updated successfully`);
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog.Root bind:open>
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
<PasswordInput bind:value={password} />
|
||||
{:else}
|
||||
<Label for="Password">Password</Label>
|
||||
<PasswordInput bind:value={password} required />
|
||||
<PasswordInput bind:value={item.password} required />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
pageIndex: pageIndex.value ?? 0,
|
||||
pageSize: pageSize.value ?? 10
|
||||
});
|
||||
let pageCount = $derived(Math.ceil(rowCount / pagination.pageSize));
|
||||
let sorting = $state<SortingState>([]);
|
||||
let columnFilters = $derived<ColumnFiltersState>([]);
|
||||
let columnVisibility = $state<VisibilityState>({});
|
||||
@@ -121,7 +122,12 @@
|
||||
...columns
|
||||
],
|
||||
manualPagination: true,
|
||||
rowCount: rowCount,
|
||||
get rowCount() {
|
||||
return rowCount;
|
||||
},
|
||||
get pageCount() {
|
||||
return pageCount;
|
||||
},
|
||||
filterFns: {
|
||||
fuzzy: (row, columnId, value, addMeta) => {
|
||||
const itemRank = rankItem(row.getValue(columnId), value);
|
||||
@@ -243,14 +249,14 @@
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div class="flex items-center justify-between gap-2 py-4">
|
||||
<div class="flex flex-col gap-2 py-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div class="relative flex items-center">
|
||||
<Search class="text-muted-foreground absolute left-3" size={16} />
|
||||
<Input
|
||||
placeholder="Search..."
|
||||
bind:value={globalFilter}
|
||||
oninput={() => table.setGlobalFilter(String(globalFilter))}
|
||||
class="w-[180px] pl-9 lg:w-[350px]"
|
||||
class="w-full pl-9 sm:w-[180px] lg:w-[350px]"
|
||||
/>
|
||||
<Delete
|
||||
class="text-muted-foreground absolute right-4"
|
||||
@@ -306,71 +312,67 @@
|
||||
{#if viewMode === 'table'}
|
||||
<!-- Table -->
|
||||
<div class="rounded-md border">
|
||||
{#key table.getRowModel().rowsById}
|
||||
<Table.Root>
|
||||
<Table.Header>
|
||||
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)}
|
||||
<Table.Row>
|
||||
{#each headerGroup.headers as header (header.id)}
|
||||
<Table.Head>
|
||||
{#if !header.isPlaceholder}
|
||||
<div class="flex items-center">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="-ml-3 h-8 data-[sortable=false]:cursor-default"
|
||||
data-sortable={header.column.getCanSort()}
|
||||
onclick={() => header.column.toggleSorting()}
|
||||
>
|
||||
<FlexRender
|
||||
content={header.column.columnDef.header}
|
||||
context={header.getContext()}
|
||||
/>
|
||||
{#if header.column.getCanSort()}
|
||||
{#if header.column.getIsSorted() === 'asc'}
|
||||
<ArrowDown />
|
||||
{:else if header.column.getIsSorted() === 'desc'}
|
||||
<ArrowUp />
|
||||
{/if}
|
||||
<Table.Root>
|
||||
<Table.Header>
|
||||
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)}
|
||||
<Table.Row>
|
||||
{#each headerGroup.headers as header (header.id)}
|
||||
<Table.Head>
|
||||
{#if !header.isPlaceholder}
|
||||
<div class="flex items-center">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="-ml-3 h-8 data-[sortable=false]:cursor-default"
|
||||
data-sortable={header.column.getCanSort()}
|
||||
onclick={() => header.column.toggleSorting()}
|
||||
>
|
||||
<FlexRender
|
||||
content={header.column.columnDef.header}
|
||||
context={header.getContext()}
|
||||
/>
|
||||
{#if header.column.getCanSort()}
|
||||
{#if header.column.getIsSorted() === 'asc'}
|
||||
<ArrowDown />
|
||||
{:else if header.column.getIsSorted() === 'desc'}
|
||||
<ArrowUp />
|
||||
{/if}
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
</Table.Head>
|
||||
{/each}
|
||||
</Table.Row>
|
||||
{/each}
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{#each table.getRowModel().rows as row (row.id)}
|
||||
<Table.Row
|
||||
data-state={row.getIsSelected() && 'selected'}
|
||||
class={computeRowClasses(row.original)}
|
||||
>
|
||||
{#each row.getVisibleCells() as cell (cell.id)}
|
||||
<Table.Cell>
|
||||
<FlexRender content={cell.column.columnDef.cell} context={cell.getContext()} />
|
||||
</Table.Cell>
|
||||
{/each}
|
||||
</Table.Row>
|
||||
{:else}
|
||||
<Table.Row>
|
||||
<Table.Cell colspan={columns.length} class="h-24 text-center">
|
||||
No results.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
{/each}
|
||||
</Table.Body>
|
||||
<Table.Footer>
|
||||
<Table.Row class="border-t">
|
||||
<Table.Cell colspan={columns.length}>Total</Table.Cell>
|
||||
<Table.Cell class="mr-4 text-right">
|
||||
{table.getPaginationRowModel().rows.length}
|
||||
</Table.Cell>
|
||||
{/if}
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
</Table.Head>
|
||||
{/each}
|
||||
</Table.Row>
|
||||
</Table.Footer>
|
||||
</Table.Root>
|
||||
{/key}
|
||||
{/each}
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{#each table.getRowModel().rows as row (row.id)}
|
||||
<Table.Row
|
||||
data-state={row.getIsSelected() && 'selected'}
|
||||
class={computeRowClasses(row.original)}
|
||||
>
|
||||
{#each row.getVisibleCells() as cell (cell.id)}
|
||||
<Table.Cell>
|
||||
<FlexRender content={cell.column.columnDef.cell} context={cell.getContext()} />
|
||||
</Table.Cell>
|
||||
{/each}
|
||||
</Table.Row>
|
||||
{:else}
|
||||
<Table.Row>
|
||||
<Table.Cell colspan={columns.length} class="h-24 text-center">No results.</Table.Cell>
|
||||
</Table.Row>
|
||||
{/each}
|
||||
</Table.Body>
|
||||
<Table.Footer>
|
||||
<Table.Row class="border-t">
|
||||
<Table.Cell colspan={columns.length}>Total</Table.Cell>
|
||||
<Table.Cell class="mr-4 text-right">
|
||||
{table.getPaginationRowModel().rows.length}
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Footer>
|
||||
</Table.Root>
|
||||
</div>
|
||||
{:else}
|
||||
<!-- Grid View -->
|
||||
@@ -512,15 +514,16 @@
|
||||
{/if}
|
||||
|
||||
<!-- Pagination -->
|
||||
<div class="flex items-center justify-between py-4">
|
||||
<div>
|
||||
<div class="flex flex-col gap-4 py-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<!-- Page size selector -->
|
||||
<div class="flex justify-center sm:justify-start">
|
||||
<Select.Root
|
||||
type="single"
|
||||
allowDeselect={false}
|
||||
value={pagination.pageSize.toString()}
|
||||
onValueChange={(value) => table.setPageSize(Number(value))}
|
||||
>
|
||||
<Select.Trigger class="w-[180px]">
|
||||
<Select.Trigger class="w-full sm:w-[180px]">
|
||||
{pagination.pageSize}
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
@@ -530,7 +533,9 @@
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
</div>
|
||||
<div class="flex items-center justify-end gap-2">
|
||||
|
||||
<!-- Pagination controls -->
|
||||
<div class="flex flex-wrap items-center justify-center gap-2 text-sm sm:justify-end">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Root from './tabs.svelte';
|
||||
import Content from './tabs-content.svelte';
|
||||
import List from './tabs-list.svelte';
|
||||
import Trigger from './tabs-trigger.svelte';
|
||||
import Root from "./tabs.svelte";
|
||||
import Content from "./tabs-content.svelte";
|
||||
import List from "./tabs-list.svelte";
|
||||
import Trigger from "./tabs-trigger.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
@@ -12,5 +12,5 @@ export {
|
||||
Root as Tabs,
|
||||
Content as TabsContent,
|
||||
List as TabsList,
|
||||
Trigger as TabsTrigger
|
||||
Trigger as TabsTrigger,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { Tabs as TabsPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils.js';
|
||||
import { Tabs as TabsPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
@@ -12,6 +12,6 @@
|
||||
<TabsPrimitive.Content
|
||||
bind:ref
|
||||
data-slot="tabs-content"
|
||||
class={cn('flex-1 outline-none', className)}
|
||||
class={cn("flex-1 outline-none", className)}
|
||||
{...restProps}
|
||||
/>
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { Tabs as TabsPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils.js';
|
||||
import { Tabs as TabsPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
let { ref = $bindable(null), class: className, ...restProps }: TabsPrimitive.ListProps = $props();
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
...restProps
|
||||
}: TabsPrimitive.ListProps = $props();
|
||||
</script>
|
||||
|
||||
<TabsPrimitive.List
|
||||
bind:ref
|
||||
data-slot="tabs-list"
|
||||
class={cn(
|
||||
'bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]',
|
||||
"bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
|
||||
className
|
||||
)}
|
||||
{...restProps}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { Tabs as TabsPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils.js';
|
||||
import { Tabs as TabsPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
@@ -13,7 +13,7 @@
|
||||
bind:ref
|
||||
data-slot="tabs-trigger"
|
||||
class={cn(
|
||||
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-2 py-1 text-sm font-medium transition-[color,box-shadow] focus-visible:outline-1 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
className
|
||||
)}
|
||||
{...restProps}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { Tabs as TabsPrimitive } from 'bits-ui';
|
||||
import { cn } from '$lib/utils.js';
|
||||
import { Tabs as TabsPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
value = $bindable(''),
|
||||
value = $bindable(""),
|
||||
class: className,
|
||||
...restProps
|
||||
}: TabsPrimitive.RootProps = $props();
|
||||
@@ -14,6 +14,6 @@
|
||||
bind:ref
|
||||
bind:value
|
||||
data-slot="tabs"
|
||||
class={cn('flex flex-col gap-2', className)}
|
||||
class={cn("flex flex-col gap-2", className)}
|
||||
{...restProps}
|
||||
/>
|
||||
|
||||
@@ -13,7 +13,7 @@ import type { Message } from "@bufbuild/protobuf";
|
||||
* Describes the file mantrae/v1/auditlog.proto.
|
||||
*/
|
||||
export const file_mantrae_v1_auditlog: GenFile = /*@__PURE__*/
|
||||
fileDesc("ChltYW50cmFlL3YxL2F1ZGl0bG9nLnByb3RvEgptYW50cmFlLnYxIp0BCghBdWRpdExvZxIKCgJpZBgBIAEoAxISCgpwcm9maWxlX2lkGAIgASgDEg8KB3VzZXJfaWQYAyABKAkSEAoIYWdlbnRfaWQYBCABKAkSDQoFZXZlbnQYBSABKAkSDwoHZGV0YWlscxgGIAEoCRIuCgpjcmVhdGVkX2F0GAcgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCK1AQoUTGlzdEF1ZGl0TG9nc1JlcXVlc3QSagoFbGltaXQYASABKANCVrpIU7oBUAoLbGltaXQudmFsaWQSKWxpbWl0IG11c3QgYmUgZWl0aGVyIC0xIG9yIGdyZWF0ZXIgdGhhbiAwGhZ0aGlzID09IC0xIHx8IHRoaXMgPiAwSACIAQESHAoGb2Zmc2V0GAIgASgDQge6SAQiAigASAGIAQFCCAoGX2xpbWl0QgkKB19vZmZzZXQiVgoVTGlzdEF1ZGl0TG9nc1Jlc3BvbnNlEigKCmF1ZGl0X2xvZ3MYASADKAsyFC5tYW50cmFlLnYxLkF1ZGl0TG9nEhMKC3RvdGFsX2NvdW50GAIgASgDMmwKD0F1ZGl0TG9nU2VydmljZRJZCg1MaXN0QXVkaXRMb2dzEiAubWFudHJhZS52MS5MaXN0QXVkaXRMb2dzUmVxdWVzdBohLm1hbnRyYWUudjEuTGlzdEF1ZGl0TG9nc1Jlc3BvbnNlIgOQAgFCpwEKDmNvbS5tYW50cmFlLnYxQg1BdWRpdGxvZ1Byb3RvUAFaPWdpdGh1Yi5jb20vbWl6dWNoaWxhYnMvbWFudHJhZS9wcm90by9nZW4vbWFudHJhZS92MTttYW50cmFldjGiAgNNWFiqAgpNYW50cmFlLlYxygIKTWFudHJhZVxWMeICFk1hbnRyYWVcVjFcR1BCTWV0YWRhdGHqAgtNYW50cmFlOjpWMWIGcHJvdG8z", [file_buf_validate_validate, file_google_protobuf_timestamp]);
|
||||
fileDesc("ChltYW50cmFlL3YxL2F1ZGl0bG9nLnByb3RvEgptYW50cmFlLnYxItoBCghBdWRpdExvZxIKCgJpZBgBIAEoAxISCgpwcm9maWxlX2lkGAIgASgDEhQKDHByb2ZpbGVfbmFtZRgDIAEoCRIPCgd1c2VyX2lkGAQgASgJEhEKCXVzZXJfbmFtZRgFIAEoCRIQCghhZ2VudF9pZBgGIAEoCRISCgphZ2VudF9uYW1lGAcgASgJEg0KBWV2ZW50GAggASgJEg8KB2RldGFpbHMYCSABKAkSLgoKY3JlYXRlZF9hdBgKIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAitQEKFExpc3RBdWRpdExvZ3NSZXF1ZXN0EmoKBWxpbWl0GAEgASgDQla6SFO6AVAKC2xpbWl0LnZhbGlkEilsaW1pdCBtdXN0IGJlIGVpdGhlciAtMSBvciBncmVhdGVyIHRoYW4gMBoWdGhpcyA9PSAtMSB8fCB0aGlzID4gMEgAiAEBEhwKBm9mZnNldBgCIAEoA0IHukgEIgIoAEgBiAEBQggKBl9saW1pdEIJCgdfb2Zmc2V0IlYKFUxpc3RBdWRpdExvZ3NSZXNwb25zZRIoCgphdWRpdF9sb2dzGAEgAygLMhQubWFudHJhZS52MS5BdWRpdExvZxITCgt0b3RhbF9jb3VudBgCIAEoAzJsCg9BdWRpdExvZ1NlcnZpY2USWQoNTGlzdEF1ZGl0TG9ncxIgLm1hbnRyYWUudjEuTGlzdEF1ZGl0TG9nc1JlcXVlc3QaIS5tYW50cmFlLnYxLkxpc3RBdWRpdExvZ3NSZXNwb25zZSIDkAIBQqcBCg5jb20ubWFudHJhZS52MUINQXVkaXRsb2dQcm90b1ABWj1naXRodWIuY29tL21penVjaGlsYWJzL21hbnRyYWUvcHJvdG8vZ2VuL21hbnRyYWUvdjE7bWFudHJhZXYxogIDTVhYqgIKTWFudHJhZS5WMcoCCk1hbnRyYWVcVjHiAhZNYW50cmFlXFYxXEdQQk1ldGFkYXRh6gILTWFudHJhZTo6VjFiBnByb3RvMw", [file_buf_validate_validate, file_google_protobuf_timestamp]);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.AuditLog
|
||||
@@ -30,27 +30,42 @@ export type AuditLog = Message<"mantrae.v1.AuditLog"> & {
|
||||
profileId: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: string user_id = 3;
|
||||
* @generated from field: string profile_name = 3;
|
||||
*/
|
||||
profileName: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string user_id = 4;
|
||||
*/
|
||||
userId: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string agent_id = 4;
|
||||
* @generated from field: string user_name = 5;
|
||||
*/
|
||||
userName: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string agent_id = 6;
|
||||
*/
|
||||
agentId: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string event = 5;
|
||||
* @generated from field: string agent_name = 7;
|
||||
*/
|
||||
agentName: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string event = 8;
|
||||
*/
|
||||
event: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string details = 6;
|
||||
* @generated from field: string details = 9;
|
||||
*/
|
||||
details: string;
|
||||
|
||||
/**
|
||||
* @generated from field: google.protobuf.Timestamp created_at = 7;
|
||||
* @generated from field: google.protobuf.Timestamp created_at = 10;
|
||||
*/
|
||||
createdAt?: Timestamp;
|
||||
};
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
TrendingUp,
|
||||
Wifi,
|
||||
Database,
|
||||
Pen
|
||||
Pen,
|
||||
List,
|
||||
Eye
|
||||
} from '@lucide/svelte';
|
||||
import { profile } from '$lib/stores/profile';
|
||||
import {
|
||||
@@ -42,6 +44,7 @@
|
||||
import ProfileModal from '$lib/components/modals/ProfileModal.svelte';
|
||||
import ConfigModal from '$lib/components/modals/ConfigModal.svelte';
|
||||
import type { Profile } from '$lib/gen/mantrae/v1/profile_pb';
|
||||
import AuditLogModal from '$lib/components/modals/AuditLogModal.svelte';
|
||||
|
||||
let totalAgents = $derived.by(async () => {
|
||||
const response = await agentClient.listAgents({
|
||||
@@ -100,10 +103,12 @@
|
||||
let modalProfile = $state({} as Profile);
|
||||
let modalProfileOpen = $state(false);
|
||||
let modalConfigOpen = $state(false);
|
||||
let modalAuditLogOpen = $state(false);
|
||||
</script>
|
||||
|
||||
<ProfileModal bind:item={modalProfile} bind:open={modalProfileOpen} />
|
||||
<ConfigModal bind:open={modalConfigOpen} />
|
||||
<AuditLogModal bind:open={modalAuditLogOpen} />
|
||||
|
||||
<div class="container mx-auto space-y-6 p-6">
|
||||
<!-- Header -->
|
||||
@@ -471,11 +476,15 @@
|
||||
|
||||
<!-- Recent Activity -->
|
||||
<Card.Root>
|
||||
<Card.Header>
|
||||
<Card.Header class="flex items-center justify-between">
|
||||
<Card.Title class="flex items-center gap-2">
|
||||
<Clock class="h-5 w-5" />
|
||||
Recent Activity
|
||||
</Card.Title>
|
||||
<Button variant="ghost" size="sm" onclick={() => (modalAuditLogOpen = true)}>
|
||||
<Eye />
|
||||
Show more
|
||||
</Button>
|
||||
</Card.Header>
|
||||
<Card.Content class="space-y-3">
|
||||
<div class="space-y-3 text-sm">
|
||||
@@ -499,12 +508,18 @@
|
||||
</span>
|
||||
{/if}
|
||||
{#if log.agentId}
|
||||
<span class="rounded bg-blue-100 px-1.5 py-0.5 text-blue-700">
|
||||
Agent: {log.agentId}
|
||||
<span
|
||||
class="rounded bg-blue-100 px-1.5 py-0.5 text-blue-700"
|
||||
title={log.agentId}
|
||||
>
|
||||
Agent: {log.agentName || `...${log.agentId.slice(-8)}`}
|
||||
</span>
|
||||
{:else if log.userId}
|
||||
<span class="rounded bg-green-100 px-1.5 py-0.5 text-green-700">
|
||||
User: {log.userId}
|
||||
<span
|
||||
class="rounded bg-green-100 px-1.5 py-0.5 text-green-700"
|
||||
title={log.userId}
|
||||
>
|
||||
User: {log.userName || `...${log.userId.slice(-8)}`}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
import type { Agent } from '$lib/gen/mantrae/v1/agent_pb';
|
||||
import { DateFormat, pageIndex, pageSize } from '$lib/stores/common';
|
||||
import { profile } from '$lib/stores/profile';
|
||||
import { timestampDate, type Timestamp } from '@bufbuild/protobuf/wkt';
|
||||
import { timestampDate } from '@bufbuild/protobuf/wkt';
|
||||
import { ConnectError } from '@connectrpc/connect';
|
||||
import { Bot, KeyRound, Pencil, Trash } from '@lucide/svelte';
|
||||
import type { ColumnDef, PaginationState } from '@tanstack/table-core';
|
||||
@@ -42,9 +42,8 @@
|
||||
accessorKey: 'activeIp',
|
||||
enableSorting: true,
|
||||
cell: ({ row }) => {
|
||||
let ip = row.getValue('activeIp') as string;
|
||||
return renderComponent(ColumnBadge, {
|
||||
label: ip || 'Unknown',
|
||||
label: row.original.activeIp || 'Unknown',
|
||||
class: 'hover:cursor-pointer'
|
||||
});
|
||||
}
|
||||
@@ -55,14 +54,10 @@
|
||||
enableSorting: true,
|
||||
enableGlobalFilter: false,
|
||||
cell: ({ row }) => {
|
||||
if (!row.original.hostname) {
|
||||
return renderComponent(ColumnBadge, {
|
||||
label: 'Never',
|
||||
class: 'hover:cursor-pointer'
|
||||
});
|
||||
if (row.original.updatedAt === undefined) {
|
||||
return renderComponent(ColumnBadge, { label: 'Never' });
|
||||
}
|
||||
const date = row.getValue('updatedAt') as Timestamp;
|
||||
return DateFormat.format(timestampDate(date));
|
||||
return DateFormat.format(timestampDate(row.original.updatedAt));
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
{
|
||||
header: 'Rules',
|
||||
accessorKey: 'config.rule',
|
||||
id: 'rules',
|
||||
enableSorting: true,
|
||||
cell: ({ row }) => {
|
||||
return renderComponent(ColumnRule, {
|
||||
@@ -142,6 +143,7 @@
|
||||
{
|
||||
header: 'TLS',
|
||||
accessorKey: 'config.tls',
|
||||
id: 'tls',
|
||||
enableSorting: true,
|
||||
enableGlobalFilter: false,
|
||||
filterFn: (row, columnId, filterValue) => {
|
||||
@@ -310,14 +312,18 @@
|
||||
rowCount = Number(response.totalCount);
|
||||
}
|
||||
|
||||
const checkMobile = () => {
|
||||
let isMobile = window.matchMedia('(max-width: 768px)').matches;
|
||||
if (isMobile) viewMode = 'grid';
|
||||
};
|
||||
onMount(() => {
|
||||
refreshData(pageSize.value ?? 10, pageIndex.value ?? 0);
|
||||
window.addEventListener('resize', checkMobile);
|
||||
return () => window.removeEventListener('resize', checkMobile);
|
||||
|
||||
// Set up resize handler
|
||||
const handleResize = () => {
|
||||
const isMobile = window.matchMedia('(max-width: 768px)').matches;
|
||||
if (isMobile) viewMode = 'grid';
|
||||
};
|
||||
|
||||
handleResize(); // Check initial state
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
import type { BulkAction } from '$lib/components/tables/types';
|
||||
import { timestampDate, type Timestamp } from '@bufbuild/protobuf/wkt';
|
||||
import { user } from '$lib/stores/user';
|
||||
import ColumnBadge from '$lib/components/tables/ColumnBadge.svelte';
|
||||
|
||||
let item = $state({} as User);
|
||||
let open = $state(false);
|
||||
@@ -61,8 +62,10 @@
|
||||
enableSorting: true,
|
||||
enableGlobalFilter: false,
|
||||
cell: ({ row }) => {
|
||||
const date = row.getValue('lastLogin') as Timestamp;
|
||||
return DateFormat.format(timestampDate(date));
|
||||
if (row.original.lastLogin === undefined) {
|
||||
return renderComponent(ColumnBadge, { label: 'Never' });
|
||||
}
|
||||
return DateFormat.format(timestampDate(row.original.lastLogin));
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user