mirror of
https://github.com/Unkn0wnCat/matrix-veles.git
synced 2025-04-28 09:46:51 +02:00
webui: Add basis for Hashing Controls
This commit is contained in:
parent
a9bdf17a5c
commit
03cc6a60a7
29 changed files with 2292 additions and 98 deletions
|
@ -39,6 +39,7 @@ type Config struct {
|
|||
type ResolverRoot interface {
|
||||
Comment() CommentResolver
|
||||
Entry() EntryResolver
|
||||
HashCheckerConfig() HashCheckerConfigResolver
|
||||
List() ListResolver
|
||||
Mutation() MutationResolver
|
||||
Query() QueryResolver
|
||||
|
@ -90,7 +91,7 @@ type ComplexityRoot struct {
|
|||
HashCheckerConfig struct {
|
||||
ChatNotice func(childComplexity int) int
|
||||
HashCheckMode func(childComplexity int) int
|
||||
SubscribedLists func(childComplexity int) int
|
||||
SubscribedLists func(childComplexity int, first *int, after *string) int
|
||||
}
|
||||
|
||||
List struct {
|
||||
|
@ -198,6 +199,9 @@ type EntryResolver interface {
|
|||
AddedBy(ctx context.Context, obj *model.Entry) (*model.User, error)
|
||||
Comments(ctx context.Context, obj *model.Entry, first *int, after *string) (*model.CommentConnection, error)
|
||||
}
|
||||
type HashCheckerConfigResolver interface {
|
||||
SubscribedLists(ctx context.Context, obj *model.HashCheckerConfig, first *int, after *string) (*model.ListConnection, error)
|
||||
}
|
||||
type ListResolver interface {
|
||||
Creator(ctx context.Context, obj *model.List) (*model.User, error)
|
||||
Comments(ctx context.Context, obj *model.List, first *int, after *string) (*model.CommentConnection, error)
|
||||
|
@ -402,7 +406,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||
break
|
||||
}
|
||||
|
||||
return e.complexity.HashCheckerConfig.SubscribedLists(childComplexity), true
|
||||
args, err := ec.field_HashCheckerConfig_subscribedLists_args(context.TODO(), rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.HashCheckerConfig.SubscribedLists(childComplexity, args["first"].(*int), args["after"].(*string)), true
|
||||
|
||||
case "List.comments":
|
||||
if e.complexity.List.Comments == nil {
|
||||
|
@ -1081,7 +1090,7 @@ enum HashCheckerMode {
|
|||
type HashCheckerConfig {
|
||||
chatNotice: Boolean!
|
||||
hashCheckMode: HashCheckerMode!
|
||||
subscribedLists: [ID!]
|
||||
subscribedLists(first: Int, after: String): ListConnection!
|
||||
}
|
||||
|
||||
type Room {
|
||||
|
@ -1457,6 +1466,30 @@ func (ec *executionContext) field_Entry_partOf_args(ctx context.Context, rawArgs
|
|||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_HashCheckerConfig_subscribedLists_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
var arg0 *int
|
||||
if tmp, ok := rawArgs["first"]; ok {
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("first"))
|
||||
arg0, err = ec.unmarshalOInt2ᚖint(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
args["first"] = arg0
|
||||
var arg1 *string
|
||||
if tmp, ok := rawArgs["after"]; ok {
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("after"))
|
||||
arg1, err = ec.unmarshalOString2ᚖstring(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
args["after"] = arg1
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_List_comments_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
|
@ -3037,30 +3070,50 @@ func (ec *executionContext) _HashCheckerConfig_subscribedLists(ctx context.Conte
|
|||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.SubscribedLists, nil
|
||||
return ec.resolvers.HashCheckerConfig().SubscribedLists(rctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*string))
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.([]string)
|
||||
res := resTmp.(*model.ListConnection)
|
||||
fc.Result = res
|
||||
return ec.marshalOID2ᚕstringᚄ(ctx, field.Selections, res)
|
||||
return ec.marshalNListConnection2ᚖgithubᚗcomᚋUnkn0wnCatᚋmatrixᚑvelesᚋgraphᚋmodelᚐListConnection(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_HashCheckerConfig_subscribedLists(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "HashCheckerConfig",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
IsMethod: true,
|
||||
IsResolver: true,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type ID does not have child fields")
|
||||
switch field.Name {
|
||||
case "pageInfo":
|
||||
return ec.fieldContext_ListConnection_pageInfo(ctx, field)
|
||||
case "edges":
|
||||
return ec.fieldContext_ListConnection_edges(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type ListConnection", field.Name)
|
||||
},
|
||||
}
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = ec.Recover(ctx, r)
|
||||
ec.Error(ctx, err)
|
||||
}
|
||||
}()
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
if fc.Args, err = ec.field_HashCheckerConfig_subscribedLists_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
|
@ -10224,19 +10277,35 @@ func (ec *executionContext) _HashCheckerConfig(ctx context.Context, sel ast.Sele
|
|||
out.Values[i] = ec._HashCheckerConfig_chatNotice(ctx, field, obj)
|
||||
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
}
|
||||
case "hashCheckMode":
|
||||
|
||||
out.Values[i] = ec._HashCheckerConfig_hashCheckMode(ctx, field, obj)
|
||||
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
}
|
||||
case "subscribedLists":
|
||||
field := field
|
||||
|
||||
out.Values[i] = ec._HashCheckerConfig_subscribedLists(ctx, field, obj)
|
||||
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
}
|
||||
}()
|
||||
res = ec._HashCheckerConfig_subscribedLists(ctx, field, obj)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
out.Concurrently(i, func() graphql.Marshaler {
|
||||
return innerFunc(ctx)
|
||||
|
||||
})
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
|
@ -11713,6 +11782,20 @@ func (ec *executionContext) marshalNList2ᚖgithubᚗcomᚋUnkn0wnCatᚋmatrix
|
|||
return ec._List(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNListConnection2githubᚗcomᚋUnkn0wnCatᚋmatrixᚑvelesᚋgraphᚋmodelᚐListConnection(ctx context.Context, sel ast.SelectionSet, v model.ListConnection) graphql.Marshaler {
|
||||
return ec._ListConnection(ctx, sel, &v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNListConnection2ᚖgithubᚗcomᚋUnkn0wnCatᚋmatrixᚑvelesᚋgraphᚋmodelᚐListConnection(ctx context.Context, sel ast.SelectionSet, v *model.ListConnection) graphql.Marshaler {
|
||||
if v == nil {
|
||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
return ec._ListConnection(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNListEdge2ᚕᚖgithubᚗcomᚋUnkn0wnCatᚋmatrixᚑvelesᚋgraphᚋmodelᚐListEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.ListEdge) graphql.Marshaler {
|
||||
ret := make(graphql.Array, len(v))
|
||||
var wg sync.WaitGroup
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package model
|
||||
|
||||
import "github.com/Unkn0wnCat/matrix-veles/internal/config"
|
||||
import (
|
||||
"github.com/Unkn0wnCat/matrix-veles/internal/config"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type Room struct {
|
||||
ID string `json:"id"`
|
||||
|
@ -16,16 +19,10 @@ type Room struct {
|
|||
type HashCheckerConfig struct {
|
||||
ChatNotice bool `json:"chatNotice"`
|
||||
HashCheckMode HashCheckerMode `json:"hashCheckMode"`
|
||||
SubscribedLists []string `json:"subscribedLists"`
|
||||
SubscribedLists []*primitive.ObjectID
|
||||
}
|
||||
|
||||
func MakeRoom(room *config.RoomConfig) *Room {
|
||||
var subscribed []string
|
||||
|
||||
for _, subId := range room.HashChecker.SubscribedLists {
|
||||
subscribed = append(subscribed, subId.Hex())
|
||||
}
|
||||
|
||||
return &Room{
|
||||
ID: room.ID.Hex(),
|
||||
Name: room.Name,
|
||||
|
@ -37,7 +34,7 @@ func MakeRoom(room *config.RoomConfig) *Room {
|
|||
HashCheckerConfig: &HashCheckerConfig{
|
||||
ChatNotice: room.HashChecker.NoticeToChat,
|
||||
HashCheckMode: AllHashCheckerMode[room.HashChecker.HashCheckMode],
|
||||
SubscribedLists: subscribed,
|
||||
SubscribedLists: room.HashChecker.SubscribedLists,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ enum HashCheckerMode {
|
|||
type HashCheckerConfig {
|
||||
chatNotice: Boolean!
|
||||
hashCheckMode: HashCheckerMode!
|
||||
subscribedLists: [ID!]
|
||||
subscribedLists(first: Int, after: String): ListConnection!
|
||||
}
|
||||
|
||||
type Room {
|
||||
|
|
|
@ -136,6 +136,83 @@ func (r *entryResolver) Comments(ctx context.Context, obj *model.Entry, first *i
|
|||
return ResolveComments(comments, first, after)
|
||||
}
|
||||
|
||||
// SubscribedLists is the resolver for the subscribedLists field.
|
||||
func (r *hashCheckerConfigResolver) SubscribedLists(ctx context.Context, obj *model.HashCheckerConfig, first *int, after *string) (*model.ListConnection, error) {
|
||||
ids := obj.SubscribedLists
|
||||
|
||||
if len(ids) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
startIndex := 0
|
||||
|
||||
if after != nil {
|
||||
afterInt := new(big.Int)
|
||||
afterInt.SetString(*after, 16)
|
||||
|
||||
idInt := new(big.Int)
|
||||
|
||||
set := false
|
||||
|
||||
for i, id := range obj.SubscribedLists {
|
||||
idInt.SetString(id.Hex(), 16)
|
||||
|
||||
if idInt.Cmp(afterInt) > 0 {
|
||||
startIndex = i
|
||||
set = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !set {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
if startIndex >= len(ids) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
ids = ids[startIndex:]
|
||||
|
||||
length := 25
|
||||
|
||||
if first != nil {
|
||||
length = *first
|
||||
}
|
||||
|
||||
cut := false
|
||||
|
||||
if len(ids) > length {
|
||||
cut = true
|
||||
ids = ids[:length]
|
||||
}
|
||||
|
||||
var edges []*model.ListEdge
|
||||
|
||||
for _, id := range ids {
|
||||
dbList, err := db.GetListByID(*id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
edges = append(edges, &model.ListEdge{
|
||||
Node: model.MakeList(dbList),
|
||||
Cursor: dbList.ID.Hex(),
|
||||
})
|
||||
}
|
||||
|
||||
return &model.ListConnection{
|
||||
PageInfo: &model.PageInfo{
|
||||
HasPreviousPage: startIndex > 0,
|
||||
HasNextPage: cut,
|
||||
StartCursor: edges[0].Cursor,
|
||||
EndCursor: edges[len(edges)-1].Cursor,
|
||||
},
|
||||
Edges: edges,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Creator is the resolver for the creator field.
|
||||
func (r *listResolver) Creator(ctx context.Context, obj *model.List) (*model.User, error) {
|
||||
user, err := db.GetUserByID(obj.CreatorID)
|
||||
|
@ -1359,6 +1436,11 @@ func (r *Resolver) Comment() generated.CommentResolver { return &commentResolver
|
|||
// Entry returns generated.EntryResolver implementation.
|
||||
func (r *Resolver) Entry() generated.EntryResolver { return &entryResolver{r} }
|
||||
|
||||
// HashCheckerConfig returns generated.HashCheckerConfigResolver implementation.
|
||||
func (r *Resolver) HashCheckerConfig() generated.HashCheckerConfigResolver {
|
||||
return &hashCheckerConfigResolver{r}
|
||||
}
|
||||
|
||||
// List returns generated.ListResolver implementation.
|
||||
func (r *Resolver) List() generated.ListResolver { return &listResolver{r} }
|
||||
|
||||
|
@ -1370,6 +1452,7 @@ func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
|
|||
|
||||
type commentResolver struct{ *Resolver }
|
||||
type entryResolver struct{ *Resolver }
|
||||
type hashCheckerConfigResolver struct{ *Resolver }
|
||||
type listResolver struct{ *Resolver }
|
||||
type mutationResolver struct{ *Resolver }
|
||||
type queryResolver struct{ *Resolver }
|
||||
|
|
|
@ -40,7 +40,7 @@ enum HashCheckerMode {
|
|||
type HashCheckerConfig {
|
||||
chatNotice: Boolean!
|
||||
hashCheckMode: HashCheckerMode!
|
||||
subscribedLists: [ID!]
|
||||
subscribedLists(first: Int, after: String): ListConnection!
|
||||
}
|
||||
|
||||
type Room {
|
||||
|
|
|
@ -18,6 +18,14 @@ import Rooms from "./components/panel/rooms/Rooms";
|
|||
import RoomsQueryGraphql, {RoomsQuery} from "./components/panel/rooms/__generated__/RoomsQuery.graphql";
|
||||
import RoomDetailQueryGraphql, {RoomDetailQuery} from "./components/panel/rooms/__generated__/RoomDetailQuery.graphql";
|
||||
import RoomDetail from "./components/panel/rooms/RoomDetail";
|
||||
import ListsQueryGraphql, {ListsQuery} from "./components/panel/hashing/lists/__generated__/ListsQuery.graphql";
|
||||
import ListDetailQueryGraphql, {ListDetailQuery} from "./components/panel/hashing/lists/__generated__/ListDetailQuery.graphql";
|
||||
import Lists from "./components/panel/hashing/lists/Lists";
|
||||
import ListDetail from "./components/panel/hashing/lists/ListDetail";
|
||||
import EntriesQueryGraphql, {EntriesQuery} from "./components/panel/hashing/entries/__generated__/EntriesQuery.graphql";
|
||||
import EntryDetailQueryGraphql, {EntryDetailQuery} from "./components/panel/hashing/entries/__generated__/EntryDetailQuery.graphql";
|
||||
import Entries from "./components/panel/hashing/entries/Entries";
|
||||
import EntryDetail from "./components/panel/hashing/entries/EntryDetail";
|
||||
|
||||
function App() {
|
||||
const dispatch = useAppDispatch()
|
||||
|
@ -37,6 +45,22 @@ function App() {
|
|||
RoomDetailQueryGraphql
|
||||
)
|
||||
|
||||
const [listsInitialState, loadListsQuery, disposeListsQuery] = useQueryLoader<ListsQuery>(
|
||||
ListsQueryGraphql
|
||||
)
|
||||
|
||||
const [listDetailInitialState, loadListDetailQuery, disposeListDetailQuery] = useQueryLoader<ListDetailQuery>(
|
||||
ListDetailQueryGraphql
|
||||
)
|
||||
|
||||
const [entriesInitialState, loadEntriesQuery, disposeEntriesQuery] = useQueryLoader<EntriesQuery>(
|
||||
EntriesQueryGraphql
|
||||
)
|
||||
|
||||
const [entryDetailInitialState, loadEntryDetailQuery, disposeEntryDetailQuery] = useQueryLoader<EntryDetailQuery>(
|
||||
EntryDetailQueryGraphql
|
||||
)
|
||||
|
||||
// This needs to be here to prevent a weird bug
|
||||
useTranslation()
|
||||
|
||||
|
@ -50,13 +74,17 @@ function App() {
|
|||
if(auth.jwt !== null) {
|
||||
loadQuery({})
|
||||
loadRoomsQuery({})
|
||||
loadListsQuery({})
|
||||
loadEntriesQuery({})
|
||||
return
|
||||
}
|
||||
|
||||
disposeQuery()
|
||||
disposeRoomsQuery()
|
||||
disposeListsQuery()
|
||||
disposeEntriesQuery()
|
||||
environment.getStore().notify(undefined, true)
|
||||
}, [auth, disposeQuery, disposeRoomsQuery, environment, loadQuery, loadRoomsQuery])
|
||||
}, [auth, disposeQuery, disposeRoomsQuery, environment, loadQuery, loadRoomsQuery, loadListsQuery, disposeListsQuery, loadEntriesQuery, disposeEntriesQuery])
|
||||
|
||||
|
||||
return (
|
||||
|
@ -70,11 +98,11 @@ function App() {
|
|||
<Route path={"rooms"} element={<RequireAuth>{roomsInitialState && <Rooms initialQueryRef={roomsInitialState}/>}</RequireAuth>}>
|
||||
<Route path={":id"} element={<RequireAuth><RoomDetail initialQueryRef={roomDetailInitialState} fetch={loadRoomDetailQuery} dispose={disposeRoomDetailQuery}/></RequireAuth>} />
|
||||
</Route>
|
||||
<Route path={"hashing/lists"} element={<RequireAuth><h1>lists</h1></RequireAuth>}>
|
||||
<Route path={":id"} element={<h1>list detail</h1>} />
|
||||
<Route path={"hashing/lists"} element={<RequireAuth>{listsInitialState && <Lists initialQueryRef={listsInitialState}/>}</RequireAuth>}>
|
||||
<Route path={":id"} element={<RequireAuth><ListDetail initialQueryRef={listDetailInitialState} fetch={loadListDetailQuery} dispose={disposeListDetailQuery}/></RequireAuth>} />
|
||||
</Route>
|
||||
<Route path={"hashing/entries"} element={<RequireAuth><h1>entries</h1></RequireAuth>}>
|
||||
<Route path={":id"} element={<h1>entry detail</h1>} />
|
||||
<Route path={"hashing/entries"} element={<RequireAuth>{entriesInitialState && <Entries initialQueryRef={entriesInitialState}/>}</RequireAuth>}>
|
||||
<Route path={":id"} element={<RequireAuth><EntryDetail initialQueryRef={entryDetailInitialState} fetch={loadEntryDetailQuery} dispose={disposeEntryDetailQuery}/></RequireAuth>} />
|
||||
</Route>
|
||||
</Route>
|
||||
</Routes>
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
@import "../../../../globals";
|
||||
|
||||
$slideOverBreakpoint: 1000px;
|
||||
|
||||
.roomsContainer {
|
||||
display: flex;
|
||||
height: calc(100% + 2*var(--veles-layout-padding));
|
||||
margin: var(--veles-layout-padding-inverse);
|
||||
width: calc(100% + 2*var(--veles-layout-padding));
|
||||
overflow: hidden;
|
||||
|
||||
.roomsOverview {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
width: 100px;
|
||||
padding: var(--veles-layout-padding);
|
||||
transition: margin-right .25s;
|
||||
|
||||
&.leaveSpace {
|
||||
margin-right: 400px;
|
||||
|
||||
@media(max-width: $slideOverBreakpoint) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slideOver {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -400px;
|
||||
height: 100%;
|
||||
width: 400px;
|
||||
border-left: thin solid var(--veles-color-border);
|
||||
transition: right .25s, border-left .25s, width .25s;
|
||||
|
||||
@media(max-width: $slideOverBreakpoint) {
|
||||
width: 100%;
|
||||
border-left: 0 solid var(--veles-color-border);
|
||||
margin-right: 0;
|
||||
right: -100%;
|
||||
}
|
||||
|
||||
background-color: var(--veles-color-background);
|
||||
|
||||
&.active {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.slideOverContent {
|
||||
padding: var(--veles-layout-padding);
|
||||
}
|
||||
|
||||
.slideOverHeader {
|
||||
display: flex;
|
||||
border-bottom: thin solid var(--veles-color-border);
|
||||
align-items: center;
|
||||
|
||||
>* {
|
||||
padding: var(--veles-layout-padding-slim) var(--veles-layout-padding);
|
||||
}
|
||||
|
||||
> span {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
> button {
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
61
webui/src/components/panel/hashing/entries/Entries.tsx
Normal file
61
webui/src/components/panel/hashing/entries/Entries.tsx
Normal file
|
@ -0,0 +1,61 @@
|
|||
import React, {useState} from "react";
|
||||
import {useNavigate, useOutlet} from "react-router-dom";
|
||||
|
||||
import styles from "./Entries.module.scss";
|
||||
import {Trans, useTranslation} from "react-i18next";
|
||||
import EntriesTable from "./EntriesTable";
|
||||
import {PreloadedQuery, usePreloadedQuery} from "react-relay/hooks";
|
||||
import {graphql} from "babel-plugin-relay/macro";
|
||||
import {EntriesQuery} from "./__generated__/EntriesQuery.graphql";
|
||||
import {X} from "lucide-react";
|
||||
import {LoaderSuspense} from "../../../common/Loader";
|
||||
|
||||
type Props = {
|
||||
initialQueryRef: PreloadedQuery<EntriesQuery>,
|
||||
}
|
||||
|
||||
const Entries = ({initialQueryRef}: Props) => {
|
||||
const outlet = useOutlet()
|
||||
const navigate = useNavigate()
|
||||
const {t} = useTranslation()
|
||||
|
||||
const data = usePreloadedQuery(
|
||||
graphql`
|
||||
query EntriesQuery($first: String, $count: Int) {
|
||||
...EntriesTableFragment
|
||||
}
|
||||
`,
|
||||
initialQueryRef
|
||||
)
|
||||
|
||||
const defaultTitle = t("entries.details", "Details")
|
||||
|
||||
const [title, setTitle] = useState(defaultTitle)
|
||||
|
||||
|
||||
return <div className={styles.roomsContainer}>
|
||||
<div className={styles.roomsOverview + (outlet ? " "+styles.leaveSpace : "")}>
|
||||
<h1><Trans i18nKey={"entries.title"}>Entry Management</Trans></h1>
|
||||
|
||||
<EntriesTable initialQueryRef={data}/>
|
||||
</div>
|
||||
|
||||
<div className={styles.slideOver + (outlet ? " "+styles.active : "")}>
|
||||
<EntriesSlideOverTitleContext.Provider value={setTitle}>
|
||||
<div className={styles.slideOverHeader}>
|
||||
<span>{title}</span>
|
||||
<button onClick={() => navigate("/hashing/entries")}><X/></button>
|
||||
</div>
|
||||
<div className={styles.slideOverContent}>
|
||||
<LoaderSuspense>
|
||||
{outlet}
|
||||
</LoaderSuspense>
|
||||
</div>
|
||||
</EntriesSlideOverTitleContext.Provider>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
export const EntriesSlideOverTitleContext = React.createContext<React.Dispatch<React.SetStateAction<string>>|null>(null)
|
||||
|
||||
export default Entries
|
|
@ -0,0 +1,5 @@
|
|||
@import "../../../../globals";
|
||||
|
||||
.roomsTableWrapper {
|
||||
@include tableWrapper;
|
||||
}
|
50
webui/src/components/panel/hashing/entries/EntriesTable.tsx
Normal file
50
webui/src/components/panel/hashing/entries/EntriesTable.tsx
Normal file
|
@ -0,0 +1,50 @@
|
|||
import React from "react";
|
||||
import {usePaginationFragment} from "react-relay/hooks";
|
||||
import {graphql} from "babel-plugin-relay/macro";
|
||||
import {EntriesTableFragment$key} from "./__generated__/EntriesTableFragment.graphql";
|
||||
import styles from "./EntriesTable.module.scss";
|
||||
import {useNavigate} from "react-router-dom";
|
||||
import {Trans} from "react-i18next";
|
||||
|
||||
type Props = {
|
||||
initialQueryRef: EntriesTableFragment$key,
|
||||
}
|
||||
|
||||
const EntriesTable = ({initialQueryRef}: Props) => {
|
||||
const {data} = usePaginationFragment(graphql`
|
||||
fragment EntriesTableFragment on Query @refetchable(queryName: "EntriesTableFragment") {
|
||||
entries(after: $first, first: $count) @connection(key: "EntriesTableFragment_entries") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
tags
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`, initialQueryRef)
|
||||
|
||||
const navigate = useNavigate()
|
||||
|
||||
return <div className={styles.roomsTableWrapper}>
|
||||
<table className={styles.roomsTable}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><Trans i18nKey={"entries.id"}>Entry ID</Trans></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
data.entries?.edges.map((edge) => {
|
||||
return <tr onClick={() => {navigate("/hashing/entries/"+edge.node.id)}} key={edge.node.id}>
|
||||
<td>{edge.node.id}</td>
|
||||
</tr>;
|
||||
})
|
||||
}
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
|
||||
export default EntriesTable
|
|
@ -0,0 +1,47 @@
|
|||
@import "../../../../globals";
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
gap: var(--veles-layout-padding)
|
||||
}
|
||||
|
||||
.label {
|
||||
display: block;
|
||||
padding: var(--veles-layout-padding-slim);
|
||||
}
|
||||
|
||||
.powerLevelInput {
|
||||
@include inputGroup;
|
||||
|
||||
input {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.hashCheckModeChooser {
|
||||
@include input;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.listTable {
|
||||
@include tableWrapper;
|
||||
padding: var(--veles-layout-padding);
|
||||
}
|
||||
|
||||
.settingsGroup {
|
||||
display: block;
|
||||
margin: var(--veles-layout-padding) var(--veles-layout-padding-inverse);
|
||||
|
||||
border-top: thin solid var(--veles-color-border);
|
||||
border-bottom: thin solid var(--veles-color-border);
|
||||
|
||||
.settingsGroupTitle {
|
||||
display: block;
|
||||
border-bottom: thin solid var(--veles-color-border);
|
||||
padding: var(--veles-layout-padding-slim) var(--veles-layout-padding);
|
||||
}
|
||||
|
||||
.settingsGroupContent {
|
||||
padding: var(--veles-layout-padding);
|
||||
}
|
||||
}
|
171
webui/src/components/panel/hashing/entries/EntryDetail.tsx
Normal file
171
webui/src/components/panel/hashing/entries/EntryDetail.tsx
Normal file
|
@ -0,0 +1,171 @@
|
|||
import React, {useContext, useEffect} from "react";
|
||||
import {PreloadedQuery, usePreloadedQuery} from "react-relay/hooks";
|
||||
import {graphql} from "babel-plugin-relay/macro";
|
||||
import {EntryDetailQuery, EntryDetailQuery$variables} from "./__generated__/EntryDetailQuery.graphql";
|
||||
import {DisposeFn} from "relay-runtime";
|
||||
import {useParams} from "react-router-dom";
|
||||
import {EntriesSlideOverTitleContext} from "./Entries";
|
||||
|
||||
//import styles from "./EntryDetail.module.scss";
|
||||
|
||||
type Props = {
|
||||
initialQueryRef: PreloadedQuery<EntryDetailQuery> | null | undefined,
|
||||
fetch: (variables: EntryDetailQuery$variables) => void
|
||||
dispose: DisposeFn
|
||||
}
|
||||
|
||||
type PropsFinal = {
|
||||
initialQueryRef: PreloadedQuery<EntryDetailQuery>,
|
||||
}
|
||||
|
||||
const RoomDetailInner = ({initialQueryRef}: PropsFinal) => {
|
||||
/*const {t} = useTranslation()
|
||||
const navigate = useNavigate()*/
|
||||
|
||||
|
||||
const data = usePreloadedQuery(
|
||||
graphql`
|
||||
query EntryDetailQuery($id: ID) {
|
||||
entry(id:$id) {
|
||||
id
|
||||
tags
|
||||
}
|
||||
}
|
||||
`,
|
||||
initialQueryRef
|
||||
)
|
||||
|
||||
const titleSetContext = useContext(EntriesSlideOverTitleContext)
|
||||
|
||||
titleSetContext && data.entry?.id && titleSetContext(data.entry.id);
|
||||
|
||||
return <>
|
||||
<pre>{JSON.stringify(data, null, 2)}</pre>
|
||||
</>
|
||||
|
||||
/*return <>
|
||||
<ToggleButton name={"activeSwitch"} label={t("panel:rooms.detail.activate.label", {defaultValue: "Activate Room"})} labelSrOnly={false} onChange={(ev) => {
|
||||
reconfigureRoom({
|
||||
variables: {
|
||||
reconfigureInput: {
|
||||
id: data.room?.id!,
|
||||
deactivate: !ev.currentTarget.checked
|
||||
}
|
||||
}
|
||||
})
|
||||
}} disabled={reconfiguringRoom || ((data.room || false) && !data.room.active && !data.room.deactivated)} checked={data.room?.active}/>
|
||||
|
||||
<ToggleButton name={"debugSwitch"} label={t("panel:rooms.detail.debug.label", {defaultValue: "Debug-Mode"})} labelSrOnly={false} onChange={(ev) => {
|
||||
reconfigureRoom({
|
||||
variables: {
|
||||
reconfigureInput: {
|
||||
id: data.room?.id!,
|
||||
debug: ev.currentTarget.checked
|
||||
}
|
||||
}
|
||||
})
|
||||
}} disabled={reconfiguringRoom || (!data.room)} checked={data.room?.debug}/>
|
||||
|
||||
<label htmlFor={"adminPowerLevelInput"} className={styles.label}><Trans i18nKey={"panel:rooms.detail.adminPowerLevel.label"}>Admin-Power Level</Trans></label>
|
||||
<div className={styles.powerLevelInput}>
|
||||
<input type={"number"} min={"50"} max={"100"} step={"1"} value={newAdminPowerLevel || data.room?.adminPowerLevel} onChange={(ev) => {
|
||||
if(Number.parseInt(ev.currentTarget.value) === data.room?.adminPowerLevel) {
|
||||
setNewAdminPowerLevel(null)
|
||||
return
|
||||
}
|
||||
|
||||
setNewAdminPowerLevel(Number.parseInt(ev.currentTarget.value))
|
||||
}} id={"adminPowerLevelInput"} />
|
||||
<button disabled={reconfiguringRoom || (!newAdminPowerLevel)} onClick={() => {
|
||||
if(!newAdminPowerLevel) {
|
||||
return
|
||||
}
|
||||
|
||||
reconfigureRoom({
|
||||
variables: {
|
||||
reconfigureInput: {
|
||||
id: data.room?.id!,
|
||||
adminPowerLevel: newAdminPowerLevel
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
setNewAdminPowerLevel(null)
|
||||
}}><Trans i18nKey={"panel:rooms.detail.set.label"}>Set</Trans></button>
|
||||
</div>
|
||||
|
||||
<div className={styles.settingsGroup}>
|
||||
<span className={styles.settingsGroupTitle}><Trans i18nKey={"panel:rooms.detail.hashChecker.label"}>Hash-Checker</Trans></span>
|
||||
<div className={styles.settingsGroupContent}>
|
||||
<ToggleButton name={"chatNoticeSwitch"} label={t("panel:rooms.detail.hashChecker.notice.label", {defaultValue: "Send Notice to Chat"})} labelSrOnly={false} onChange={(ev) => {
|
||||
reconfigureRoom({
|
||||
variables: {
|
||||
reconfigureInput: {
|
||||
id: data.room?.id!,
|
||||
hashChecker: {
|
||||
chatNotice: ev.currentTarget.checked
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}} disabled={reconfiguringRoom || (!data.room)} checked={data.room?.hashCheckerConfig.chatNotice}/>
|
||||
|
||||
<label htmlFor={"hashCheckModeChooser"} className={styles.label}><Trans i18nKey={"panel:rooms.detail.hashChecker.hashCheckMode.label"}>Behaviour on Match</Trans></label>
|
||||
<select value={data.room?.hashCheckerConfig.hashCheckMode} disabled={reconfiguringRoom || (!data.room)} onChange={(ev) => {
|
||||
reconfigureRoom({
|
||||
variables: {
|
||||
reconfigureInput: {
|
||||
id: data.room?.id!,
|
||||
hashChecker: {
|
||||
hashCheckMode: ev.currentTarget.value as HashCheckerMode
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}} className={styles.hashCheckModeChooser} id={"hashCheckModeChooser"}>
|
||||
<option value="NOTICE"><Trans i18nKey={"panel:rooms.detail.hashChecker.hashCheckMode.NOTICE.label"}>Only send a Notice</Trans></option>
|
||||
<option value="DELETE"><Trans i18nKey={"panel:rooms.detail.hashChecker.hashCheckMode.DELETE.label"}>Delete the Message</Trans></option>
|
||||
<option value="MUTE"><Trans i18nKey={"panel:rooms.detail.hashChecker.hashCheckMode.MUTE.label"}>Mute User & Delete</Trans></option>
|
||||
<option value="BAN"><Trans i18nKey={"panel:rooms.detail.hashChecker.hashCheckMode.BAN.label"}>Ban User & Delete</Trans></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className={styles.listTable}>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><Trans i18nKey={"lists.name"}>Name</Trans></th>
|
||||
<th><Trans i18nKey={"lists.id"}>List ID</Trans></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
data.room?.hashCheckerConfig.subscribedLists.edges.map((edge) => {
|
||||
return <tr onClick={() => {navigate("/hashing/lists/"+edge.node.id)}} key={edge.node.id}>
|
||||
<td>{edge.node.name}</td>
|
||||
<td>{edge.node.id}</td>
|
||||
</tr>;
|
||||
})
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</>*/
|
||||
}
|
||||
|
||||
const EntryDetail = ({initialQueryRef, fetch, dispose}: Props) => {
|
||||
const {id} = useParams()
|
||||
|
||||
useEffect(() => {
|
||||
fetch({id})
|
||||
|
||||
return () => {
|
||||
dispose();
|
||||
}
|
||||
}, [id, dispose, fetch])
|
||||
|
||||
return initialQueryRef ? <RoomDetailInner initialQueryRef={initialQueryRef} /> : null
|
||||
}
|
||||
|
||||
export default EntryDetail;
|
186
webui/src/components/panel/hashing/entries/__generated__/EntriesQuery.graphql.ts
generated
Normal file
186
webui/src/components/panel/hashing/entries/__generated__/EntriesQuery.graphql.ts
generated
Normal file
|
@ -0,0 +1,186 @@
|
|||
/**
|
||||
* @generated SignedSource<<0d6e62e3c8c5ff07cb1c9f683624d372>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest, Query } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type EntriesQuery$variables = {
|
||||
first?: string | null;
|
||||
count?: number | null;
|
||||
};
|
||||
export type EntriesQuery$data = {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"EntriesTableFragment">;
|
||||
};
|
||||
export type EntriesQuery = {
|
||||
variables: EntriesQuery$variables;
|
||||
response: EntriesQuery$data;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "count"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "first"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "after",
|
||||
"variableName": "first"
|
||||
},
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "first",
|
||||
"variableName": "count"
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "EntriesQuery",
|
||||
"selections": [
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "EntriesTableFragment"
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "EntriesQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "EntryConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "entries",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "EntryEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Entry",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "tags",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "EntriesTableFragment_entries",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "entries"
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "cb7fcbe76a323cc0ce2ae532aa6fa861",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "EntriesQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query EntriesQuery(\n $first: String\n $count: Int\n) {\n ...EntriesTableFragment\n}\n\nfragment EntriesTableFragment on Query {\n entries(after: $first, first: $count) {\n edges {\n node {\n id\n tags\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "06398f7547759ada0c2066a0d13cf04c";
|
||||
|
||||
export default node;
|
163
webui/src/components/panel/hashing/entries/__generated__/EntriesTableFragment.graphql.ts
generated
Normal file
163
webui/src/components/panel/hashing/entries/__generated__/EntriesTableFragment.graphql.ts
generated
Normal file
|
@ -0,0 +1,163 @@
|
|||
/**
|
||||
* @generated SignedSource<<38a8e1d2b568b81072536ddacd114e6f>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment, RefetchableFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type EntriesTableFragment$data = {
|
||||
readonly entries: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly tags: ReadonlyArray<string> | null;
|
||||
};
|
||||
}>;
|
||||
} | null;
|
||||
readonly " $fragmentType": "EntriesTableFragment";
|
||||
};
|
||||
export type EntriesTableFragment$key = {
|
||||
readonly " $data"?: EntriesTableFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"EntriesTableFragment">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = [
|
||||
"entries"
|
||||
];
|
||||
return {
|
||||
"argumentDefinitions": [
|
||||
{
|
||||
"kind": "RootArgument",
|
||||
"name": "count"
|
||||
},
|
||||
{
|
||||
"kind": "RootArgument",
|
||||
"name": "first"
|
||||
}
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": "count",
|
||||
"cursor": "first",
|
||||
"direction": "forward",
|
||||
"path": (v0/*: any*/)
|
||||
}
|
||||
],
|
||||
"refetch": {
|
||||
"connection": {
|
||||
"forward": {
|
||||
"count": "count",
|
||||
"cursor": "first"
|
||||
},
|
||||
"backward": null,
|
||||
"path": (v0/*: any*/)
|
||||
},
|
||||
"fragmentPathInResult": [],
|
||||
"operation": require('./EntriesTableFragment.graphql')
|
||||
}
|
||||
},
|
||||
"name": "EntriesTableFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "entries",
|
||||
"args": null,
|
||||
"concreteType": "EntryConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__EntriesTableFragment_entries_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "EntryEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Entry",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "tags",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "999faf383df2d42007f73da008f4c910";
|
||||
|
||||
export default node;
|
97
webui/src/components/panel/hashing/entries/__generated__/EntryDetailQuery.graphql.ts
generated
Normal file
97
webui/src/components/panel/hashing/entries/__generated__/EntryDetailQuery.graphql.ts
generated
Normal file
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
* @generated SignedSource<<5a8663de6323dd94e27c8d5b53db80eb>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest, Query } from 'relay-runtime';
|
||||
export type EntryDetailQuery$variables = {
|
||||
id?: string | null;
|
||||
};
|
||||
export type EntryDetailQuery$data = {
|
||||
readonly entry: {
|
||||
readonly id: string;
|
||||
readonly tags: ReadonlyArray<string> | null;
|
||||
} | null;
|
||||
};
|
||||
export type EntryDetailQuery = {
|
||||
variables: EntryDetailQuery$variables;
|
||||
response: EntryDetailQuery$data;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "id"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "id"
|
||||
}
|
||||
],
|
||||
"concreteType": "Entry",
|
||||
"kind": "LinkedField",
|
||||
"name": "entry",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "tags",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "EntryDetailQuery",
|
||||
"selections": (v1/*: any*/),
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "EntryDetailQuery",
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "1f01a8cbc9fbd149cc3511fbfb5a0929",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "EntryDetailQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query EntryDetailQuery(\n $id: ID\n) {\n entry(id: $id) {\n id\n tags\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "2121d3309f0f6813613afae4a045e275";
|
||||
|
||||
export default node;
|
|
@ -0,0 +1,47 @@
|
|||
@import "../../../../globals";
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
gap: var(--veles-layout-padding)
|
||||
}
|
||||
|
||||
.label {
|
||||
display: block;
|
||||
padding: var(--veles-layout-padding-slim);
|
||||
}
|
||||
|
||||
.powerLevelInput {
|
||||
@include inputGroup;
|
||||
|
||||
input {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.hashCheckModeChooser {
|
||||
@include input;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.listTable {
|
||||
@include tableWrapper;
|
||||
padding: var(--veles-layout-padding);
|
||||
}
|
||||
|
||||
.settingsGroup {
|
||||
display: block;
|
||||
margin: var(--veles-layout-padding) var(--veles-layout-padding-inverse);
|
||||
|
||||
border-top: thin solid var(--veles-color-border);
|
||||
border-bottom: thin solid var(--veles-color-border);
|
||||
|
||||
.settingsGroupTitle {
|
||||
display: block;
|
||||
border-bottom: thin solid var(--veles-color-border);
|
||||
padding: var(--veles-layout-padding-slim) var(--veles-layout-padding);
|
||||
}
|
||||
|
||||
.settingsGroupContent {
|
||||
padding: var(--veles-layout-padding);
|
||||
}
|
||||
}
|
186
webui/src/components/panel/hashing/lists/ListDetail.tsx
Normal file
186
webui/src/components/panel/hashing/lists/ListDetail.tsx
Normal file
|
@ -0,0 +1,186 @@
|
|||
import React, {useContext, useEffect} from "react";
|
||||
import {PreloadedQuery, usePreloadedQuery} from "react-relay/hooks";
|
||||
import {graphql} from "babel-plugin-relay/macro";
|
||||
import {ListDetailQuery, ListDetailQuery$variables} from "./__generated__/ListDetailQuery.graphql";
|
||||
import {DisposeFn} from "relay-runtime";
|
||||
import {useParams} from "react-router-dom";
|
||||
import {ListsSlideOverTitleContext} from "./Lists";
|
||||
|
||||
//import styles from "./ListDetail.module.scss";
|
||||
|
||||
type Props = {
|
||||
initialQueryRef: PreloadedQuery<ListDetailQuery> | null | undefined,
|
||||
fetch: (variables: ListDetailQuery$variables) => void
|
||||
dispose: DisposeFn
|
||||
}
|
||||
|
||||
type PropsFinal = {
|
||||
initialQueryRef: PreloadedQuery<ListDetailQuery>,
|
||||
}
|
||||
|
||||
const RoomDetailInner = ({initialQueryRef}: PropsFinal) => {
|
||||
/*const {t} = useTranslation()
|
||||
const navigate = useNavigate()*/
|
||||
|
||||
|
||||
const data = usePreloadedQuery(
|
||||
graphql`
|
||||
query ListDetailQuery($id: ID) {
|
||||
list(id:$id) {
|
||||
id
|
||||
name
|
||||
tags
|
||||
creator {
|
||||
id
|
||||
username
|
||||
matrixLinks
|
||||
}
|
||||
maintainers(first: 100) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
username
|
||||
matrixLinks
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
initialQueryRef
|
||||
)
|
||||
|
||||
const titleSetContext = useContext(ListsSlideOverTitleContext)
|
||||
|
||||
titleSetContext && data.list?.name && titleSetContext(data.list.name);
|
||||
|
||||
return <>
|
||||
<pre>{JSON.stringify(data, null, 2)}</pre>
|
||||
</>
|
||||
|
||||
/*return <>
|
||||
<ToggleButton name={"activeSwitch"} label={t("panel:rooms.detail.activate.label", {defaultValue: "Activate Room"})} labelSrOnly={false} onChange={(ev) => {
|
||||
reconfigureRoom({
|
||||
variables: {
|
||||
reconfigureInput: {
|
||||
id: data.room?.id!,
|
||||
deactivate: !ev.currentTarget.checked
|
||||
}
|
||||
}
|
||||
})
|
||||
}} disabled={reconfiguringRoom || ((data.room || false) && !data.room.active && !data.room.deactivated)} checked={data.room?.active}/>
|
||||
|
||||
<ToggleButton name={"debugSwitch"} label={t("panel:rooms.detail.debug.label", {defaultValue: "Debug-Mode"})} labelSrOnly={false} onChange={(ev) => {
|
||||
reconfigureRoom({
|
||||
variables: {
|
||||
reconfigureInput: {
|
||||
id: data.room?.id!,
|
||||
debug: ev.currentTarget.checked
|
||||
}
|
||||
}
|
||||
})
|
||||
}} disabled={reconfiguringRoom || (!data.room)} checked={data.room?.debug}/>
|
||||
|
||||
<label htmlFor={"adminPowerLevelInput"} className={styles.label}><Trans i18nKey={"panel:rooms.detail.adminPowerLevel.label"}>Admin-Power Level</Trans></label>
|
||||
<div className={styles.powerLevelInput}>
|
||||
<input type={"number"} min={"50"} max={"100"} step={"1"} value={newAdminPowerLevel || data.room?.adminPowerLevel} onChange={(ev) => {
|
||||
if(Number.parseInt(ev.currentTarget.value) === data.room?.adminPowerLevel) {
|
||||
setNewAdminPowerLevel(null)
|
||||
return
|
||||
}
|
||||
|
||||
setNewAdminPowerLevel(Number.parseInt(ev.currentTarget.value))
|
||||
}} id={"adminPowerLevelInput"} />
|
||||
<button disabled={reconfiguringRoom || (!newAdminPowerLevel)} onClick={() => {
|
||||
if(!newAdminPowerLevel) {
|
||||
return
|
||||
}
|
||||
|
||||
reconfigureRoom({
|
||||
variables: {
|
||||
reconfigureInput: {
|
||||
id: data.room?.id!,
|
||||
adminPowerLevel: newAdminPowerLevel
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
setNewAdminPowerLevel(null)
|
||||
}}><Trans i18nKey={"panel:rooms.detail.set.label"}>Set</Trans></button>
|
||||
</div>
|
||||
|
||||
<div className={styles.settingsGroup}>
|
||||
<span className={styles.settingsGroupTitle}><Trans i18nKey={"panel:rooms.detail.hashChecker.label"}>Hash-Checker</Trans></span>
|
||||
<div className={styles.settingsGroupContent}>
|
||||
<ToggleButton name={"chatNoticeSwitch"} label={t("panel:rooms.detail.hashChecker.notice.label", {defaultValue: "Send Notice to Chat"})} labelSrOnly={false} onChange={(ev) => {
|
||||
reconfigureRoom({
|
||||
variables: {
|
||||
reconfigureInput: {
|
||||
id: data.room?.id!,
|
||||
hashChecker: {
|
||||
chatNotice: ev.currentTarget.checked
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}} disabled={reconfiguringRoom || (!data.room)} checked={data.room?.hashCheckerConfig.chatNotice}/>
|
||||
|
||||
<label htmlFor={"hashCheckModeChooser"} className={styles.label}><Trans i18nKey={"panel:rooms.detail.hashChecker.hashCheckMode.label"}>Behaviour on Match</Trans></label>
|
||||
<select value={data.room?.hashCheckerConfig.hashCheckMode} disabled={reconfiguringRoom || (!data.room)} onChange={(ev) => {
|
||||
reconfigureRoom({
|
||||
variables: {
|
||||
reconfigureInput: {
|
||||
id: data.room?.id!,
|
||||
hashChecker: {
|
||||
hashCheckMode: ev.currentTarget.value as HashCheckerMode
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}} className={styles.hashCheckModeChooser} id={"hashCheckModeChooser"}>
|
||||
<option value="NOTICE"><Trans i18nKey={"panel:rooms.detail.hashChecker.hashCheckMode.NOTICE.label"}>Only send a Notice</Trans></option>
|
||||
<option value="DELETE"><Trans i18nKey={"panel:rooms.detail.hashChecker.hashCheckMode.DELETE.label"}>Delete the Message</Trans></option>
|
||||
<option value="MUTE"><Trans i18nKey={"panel:rooms.detail.hashChecker.hashCheckMode.MUTE.label"}>Mute User & Delete</Trans></option>
|
||||
<option value="BAN"><Trans i18nKey={"panel:rooms.detail.hashChecker.hashCheckMode.BAN.label"}>Ban User & Delete</Trans></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className={styles.listTable}>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><Trans i18nKey={"lists.name"}>Name</Trans></th>
|
||||
<th><Trans i18nKey={"lists.id"}>List ID</Trans></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
data.room?.hashCheckerConfig.subscribedLists.edges.map((edge) => {
|
||||
return <tr onClick={() => {navigate("/hashing/lists/"+edge.node.id)}} key={edge.node.id}>
|
||||
<td>{edge.node.name}</td>
|
||||
<td>{edge.node.id}</td>
|
||||
</tr>;
|
||||
})
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</>*/
|
||||
}
|
||||
|
||||
const ListDetail = ({initialQueryRef, fetch, dispose}: Props) => {
|
||||
const {id} = useParams()
|
||||
|
||||
useEffect(() => {
|
||||
fetch({id})
|
||||
|
||||
return () => {
|
||||
dispose();
|
||||
}
|
||||
}, [id, dispose, fetch])
|
||||
|
||||
return initialQueryRef ? <RoomDetailInner initialQueryRef={initialQueryRef} /> : null
|
||||
}
|
||||
|
||||
export default ListDetail;
|
77
webui/src/components/panel/hashing/lists/Lists.module.scss
Normal file
77
webui/src/components/panel/hashing/lists/Lists.module.scss
Normal file
|
@ -0,0 +1,77 @@
|
|||
@import "../../../../globals";
|
||||
|
||||
$slideOverBreakpoint: 1000px;
|
||||
|
||||
.roomsContainer {
|
||||
display: flex;
|
||||
height: calc(100% + 2*var(--veles-layout-padding));
|
||||
margin: var(--veles-layout-padding-inverse);
|
||||
width: calc(100% + 2*var(--veles-layout-padding));
|
||||
overflow: hidden;
|
||||
|
||||
.roomsOverview {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
width: 100px;
|
||||
padding: var(--veles-layout-padding);
|
||||
transition: margin-right .25s;
|
||||
|
||||
&.leaveSpace {
|
||||
margin-right: 400px;
|
||||
|
||||
@media(max-width: $slideOverBreakpoint) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slideOver {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -400px;
|
||||
height: 100%;
|
||||
width: 400px;
|
||||
border-left: thin solid var(--veles-color-border);
|
||||
transition: right .25s, border-left .25s, width .25s;
|
||||
|
||||
@media(max-width: $slideOverBreakpoint) {
|
||||
width: 100%;
|
||||
border-left: 0 solid var(--veles-color-border);
|
||||
margin-right: 0;
|
||||
right: -100%;
|
||||
}
|
||||
|
||||
background-color: var(--veles-color-background);
|
||||
|
||||
&.active {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.slideOverContent {
|
||||
padding: var(--veles-layout-padding);
|
||||
}
|
||||
|
||||
.slideOverHeader {
|
||||
display: flex;
|
||||
border-bottom: thin solid var(--veles-color-border);
|
||||
align-items: center;
|
||||
|
||||
>* {
|
||||
padding: var(--veles-layout-padding-slim) var(--veles-layout-padding);
|
||||
}
|
||||
|
||||
> span {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
> button {
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
61
webui/src/components/panel/hashing/lists/Lists.tsx
Normal file
61
webui/src/components/panel/hashing/lists/Lists.tsx
Normal file
|
@ -0,0 +1,61 @@
|
|||
import React, {useState} from "react";
|
||||
import {useNavigate, useOutlet} from "react-router-dom";
|
||||
|
||||
import styles from "./Lists.module.scss";
|
||||
import {Trans, useTranslation} from "react-i18next";
|
||||
import ListsTable from "./ListsTable";
|
||||
import {PreloadedQuery, usePreloadedQuery} from "react-relay/hooks";
|
||||
import {graphql} from "babel-plugin-relay/macro";
|
||||
import {ListsQuery} from "./__generated__/ListsQuery.graphql";
|
||||
import {X} from "lucide-react";
|
||||
import {LoaderSuspense} from "../../../common/Loader";
|
||||
|
||||
type Props = {
|
||||
initialQueryRef: PreloadedQuery<ListsQuery>,
|
||||
}
|
||||
|
||||
const Lists = ({initialQueryRef}: Props) => {
|
||||
const outlet = useOutlet()
|
||||
const navigate = useNavigate()
|
||||
const {t} = useTranslation()
|
||||
|
||||
const data = usePreloadedQuery(
|
||||
graphql`
|
||||
query ListsQuery($first: String, $count: Int) {
|
||||
...ListsTableFragment
|
||||
}
|
||||
`,
|
||||
initialQueryRef
|
||||
)
|
||||
|
||||
const defaultTitle = t("lists.details", "Details")
|
||||
|
||||
const [title, setTitle] = useState(defaultTitle)
|
||||
|
||||
|
||||
return <div className={styles.roomsContainer}>
|
||||
<div className={styles.roomsOverview + (outlet ? " "+styles.leaveSpace : "")}>
|
||||
<h1><Trans i18nKey={"lists.title"}>Available Lists</Trans></h1>
|
||||
|
||||
<ListsTable initialQueryRef={data}/>
|
||||
</div>
|
||||
|
||||
<div className={styles.slideOver + (outlet ? " "+styles.active : "")}>
|
||||
<ListsSlideOverTitleContext.Provider value={setTitle}>
|
||||
<div className={styles.slideOverHeader}>
|
||||
<span>{title}</span>
|
||||
<button onClick={() => navigate("/hashing/lists")}><X/></button>
|
||||
</div>
|
||||
<div className={styles.slideOverContent}>
|
||||
<LoaderSuspense>
|
||||
{outlet}
|
||||
</LoaderSuspense>
|
||||
</div>
|
||||
</ListsSlideOverTitleContext.Provider>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
export const ListsSlideOverTitleContext = React.createContext<React.Dispatch<React.SetStateAction<string>>|null>(null)
|
||||
|
||||
export default Lists
|
|
@ -0,0 +1,5 @@
|
|||
@import "../../../../globals";
|
||||
|
||||
.roomsTableWrapper {
|
||||
@include tableWrapper;
|
||||
}
|
60
webui/src/components/panel/hashing/lists/ListsTable.tsx
Normal file
60
webui/src/components/panel/hashing/lists/ListsTable.tsx
Normal file
|
@ -0,0 +1,60 @@
|
|||
import React from "react";
|
||||
import {usePaginationFragment} from "react-relay/hooks";
|
||||
import {graphql} from "babel-plugin-relay/macro";
|
||||
import {ListsTableFragment$key} from "./__generated__/ListsTableFragment.graphql";
|
||||
import styles from "./ListsTable.module.scss";
|
||||
import {useNavigate} from "react-router-dom";
|
||||
import {Trans} from "react-i18next";
|
||||
|
||||
type Props = {
|
||||
initialQueryRef: ListsTableFragment$key,
|
||||
}
|
||||
|
||||
const ListsTable = ({initialQueryRef}: Props) => {
|
||||
const {data} = usePaginationFragment(graphql`
|
||||
fragment ListsTableFragment on Query @refetchable(queryName: "ListsTableFragment") {
|
||||
lists(after: $first, first: $count) @connection(key: "ListsTableFragment_lists") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
tags
|
||||
creator {
|
||||
id
|
||||
username
|
||||
matrixLinks
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`, initialQueryRef)
|
||||
|
||||
const navigate = useNavigate()
|
||||
|
||||
return <div className={styles.roomsTableWrapper}>
|
||||
<table className={styles.roomsTable}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><Trans i18nKey={"lists.name"}>Name</Trans></th>
|
||||
<th><Trans i18nKey={"lists.id"}>List ID</Trans></th>
|
||||
<th><Trans i18nKey={"lists.creator"}>List Creator</Trans></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
data.lists?.edges.map((edge) => {
|
||||
return <tr onClick={() => {navigate("/hashing/lists/"+edge.node.id)}} key={edge.node.id}>
|
||||
<td>{edge.node.name}</td>
|
||||
<td>{edge.node.id}</td>
|
||||
<td>{edge.node.creator.username}</td>
|
||||
</tr>;
|
||||
})
|
||||
}
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
|
||||
export default ListsTable
|
185
webui/src/components/panel/hashing/lists/__generated__/ListDetailQuery.graphql.ts
generated
Normal file
185
webui/src/components/panel/hashing/lists/__generated__/ListDetailQuery.graphql.ts
generated
Normal file
|
@ -0,0 +1,185 @@
|
|||
/**
|
||||
* @generated SignedSource<<387ef79509f6e2371f71fa3d72d073fd>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest, Query } from 'relay-runtime';
|
||||
export type ListDetailQuery$variables = {
|
||||
id?: string | null;
|
||||
};
|
||||
export type ListDetailQuery$data = {
|
||||
readonly list: {
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly tags: ReadonlyArray<string> | null;
|
||||
readonly creator: {
|
||||
readonly id: string;
|
||||
readonly username: string;
|
||||
readonly matrixLinks: ReadonlyArray<string> | null;
|
||||
};
|
||||
readonly maintainers: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly username: string;
|
||||
readonly matrixLinks: ReadonlyArray<string> | null;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
} | null;
|
||||
};
|
||||
export type ListDetailQuery = {
|
||||
variables: ListDetailQuery$variables;
|
||||
response: ListDetailQuery$data;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "id"
|
||||
}
|
||||
],
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v2 = [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "username",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "matrixLinks",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
v3 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "id"
|
||||
}
|
||||
],
|
||||
"concreteType": "List",
|
||||
"kind": "LinkedField",
|
||||
"name": "list",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "tags",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "User",
|
||||
"kind": "LinkedField",
|
||||
"name": "creator",
|
||||
"plural": false,
|
||||
"selections": (v2/*: any*/),
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
],
|
||||
"concreteType": "UserConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "maintainers",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "UserEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "User",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": (v2/*: any*/),
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "maintainers(first:100)"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "ListDetailQuery",
|
||||
"selections": (v3/*: any*/),
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "ListDetailQuery",
|
||||
"selections": (v3/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "25b9482991b61f15c2856c99875b239e",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ListDetailQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query ListDetailQuery(\n $id: ID\n) {\n list(id: $id) {\n id\n name\n tags\n creator {\n id\n username\n matrixLinks\n }\n maintainers(first: 100) {\n edges {\n node {\n id\n username\n matrixLinks\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "7cef889868efd30077c76c270e95474e";
|
||||
|
||||
export default node;
|
220
webui/src/components/panel/hashing/lists/__generated__/ListsQuery.graphql.ts
generated
Normal file
220
webui/src/components/panel/hashing/lists/__generated__/ListsQuery.graphql.ts
generated
Normal file
|
@ -0,0 +1,220 @@
|
|||
/**
|
||||
* @generated SignedSource<<5aab59ac780b7eaef3dee3a8745fbc28>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest, Query } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type ListsQuery$variables = {
|
||||
first?: string | null;
|
||||
count?: number | null;
|
||||
};
|
||||
export type ListsQuery$data = {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"ListsTableFragment">;
|
||||
};
|
||||
export type ListsQuery = {
|
||||
variables: ListsQuery$variables;
|
||||
response: ListsQuery$data;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "count"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "first"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "after",
|
||||
"variableName": "first"
|
||||
},
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "first",
|
||||
"variableName": "count"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "ListsQuery",
|
||||
"selections": [
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "ListsTableFragment"
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "ListsQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "ListConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "lists",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ListEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "List",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "tags",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "User",
|
||||
"kind": "LinkedField",
|
||||
"name": "creator",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "username",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "matrixLinks",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "ListsTableFragment_lists",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "lists"
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "97b29f2758a0594dc8e7260db058e120",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ListsQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query ListsQuery(\n $first: String\n $count: Int\n) {\n ...ListsTableFragment\n}\n\nfragment ListsTableFragment on Query {\n lists(after: $first, first: $count) {\n edges {\n node {\n id\n name\n tags\n creator {\n id\n username\n matrixLinks\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "af7a7db395ee385cea027ca6d8320a42";
|
||||
|
||||
export default node;
|
203
webui/src/components/panel/hashing/lists/__generated__/ListsTableFragment.graphql.ts
generated
Normal file
203
webui/src/components/panel/hashing/lists/__generated__/ListsTableFragment.graphql.ts
generated
Normal file
|
@ -0,0 +1,203 @@
|
|||
/**
|
||||
* @generated SignedSource<<9406112d41db017f2dbc6315c2cd7064>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment, RefetchableFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type ListsTableFragment$data = {
|
||||
readonly lists: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly tags: ReadonlyArray<string> | null;
|
||||
readonly creator: {
|
||||
readonly id: string;
|
||||
readonly username: string;
|
||||
readonly matrixLinks: ReadonlyArray<string> | null;
|
||||
};
|
||||
};
|
||||
}>;
|
||||
} | null;
|
||||
readonly " $fragmentType": "ListsTableFragment";
|
||||
};
|
||||
export type ListsTableFragment$key = {
|
||||
readonly " $data"?: ListsTableFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"ListsTableFragment">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = [
|
||||
"lists"
|
||||
],
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"argumentDefinitions": [
|
||||
{
|
||||
"kind": "RootArgument",
|
||||
"name": "count"
|
||||
},
|
||||
{
|
||||
"kind": "RootArgument",
|
||||
"name": "first"
|
||||
}
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": "count",
|
||||
"cursor": "first",
|
||||
"direction": "forward",
|
||||
"path": (v0/*: any*/)
|
||||
}
|
||||
],
|
||||
"refetch": {
|
||||
"connection": {
|
||||
"forward": {
|
||||
"count": "count",
|
||||
"cursor": "first"
|
||||
},
|
||||
"backward": null,
|
||||
"path": (v0/*: any*/)
|
||||
},
|
||||
"fragmentPathInResult": [],
|
||||
"operation": require('./ListsTableFragment.graphql')
|
||||
}
|
||||
},
|
||||
"name": "ListsTableFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "lists",
|
||||
"args": null,
|
||||
"concreteType": "ListConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__ListsTableFragment_lists_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ListEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "List",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "tags",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "User",
|
||||
"kind": "LinkedField",
|
||||
"name": "creator",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "username",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "matrixLinks",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "8b14551a242c87b90d76b77b05535cb2";
|
||||
|
||||
export default node;
|
|
@ -3,7 +3,7 @@ import {PreloadedQuery, usePreloadedQuery} from "react-relay/hooks";
|
|||
import {graphql} from "babel-plugin-relay/macro";
|
||||
import {RoomDetailQuery, RoomDetailQuery$variables} from "./__generated__/RoomDetailQuery.graphql";
|
||||
import {DisposeFn} from "relay-runtime";
|
||||
import {useParams} from "react-router-dom";
|
||||
import {useNavigate, useParams} from "react-router-dom";
|
||||
import {RoomsSlideOverTitleContext} from "./Rooms";
|
||||
import ToggleButton from "../../form_components/ToggleButton";
|
||||
|
||||
|
@ -26,6 +26,7 @@ const RoomDetailInner = ({initialQueryRef}: PropsFinal) => {
|
|||
const [reconfigureRoom, reconfiguringRoom] = useReconfigureRoomMutation();
|
||||
const [newAdminPowerLevel, setNewAdminPowerLevel] = useState<number|null>(null)
|
||||
const {t} = useTranslation()
|
||||
const navigate = useNavigate()
|
||||
|
||||
|
||||
const data = usePreloadedQuery(
|
||||
|
@ -42,7 +43,14 @@ const RoomDetailInner = ({initialQueryRef}: PropsFinal) => {
|
|||
hashCheckerConfig {
|
||||
chatNotice
|
||||
hashCheckMode
|
||||
subscribedLists
|
||||
subscribedLists(first: 100) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -150,26 +158,18 @@ const RoomDetailInner = ({initialQueryRef}: PropsFinal) => {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{/*
|
||||
data.rooms?.edges.map((edge) => {
|
||||
return <tr onClick={() => {navigate("/rooms/"+edge.node.id)}} key={edge.node.id}>
|
||||
<td>
|
||||
{edge.node.debug && <span className={styles.badge + " " + styles.blue}><Trans i18nKey={"rooms.debug"}>Debug</Trans></span>}
|
||||
{!edge.node.active && <span className={styles.badge + " " + styles.red}><Trans i18nKey={"rooms.inactive"}>Inactive</Trans></span>}
|
||||
{edge.node.active && <span className={styles.badge + " " + styles.green}><Trans i18nKey={"rooms.active"}>Active</Trans></span>}
|
||||
</td>
|
||||
{
|
||||
data.room?.hashCheckerConfig.subscribedLists.edges.map((edge) => {
|
||||
return <tr onClick={() => {navigate("/hashing/lists/"+edge.node.id)}} key={edge.node.id}>
|
||||
<td>{edge.node.name}</td>
|
||||
<td>{edge.node.roomId}</td>
|
||||
<td>{edge.node.id}</td>
|
||||
</tr>;
|
||||
})
|
||||
*/}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<pre style={{opacity: .25}}>{JSON.stringify(data, null, 2)}</pre>
|
||||
</>
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @generated SignedSource<<58fc708823f0e42ade18c16f92c3b0d2>>
|
||||
* @generated SignedSource<<1663469824a6a66c6959a37976f2a05e>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
@ -25,7 +25,14 @@ export type RoomDetailQuery$data = {
|
|||
readonly hashCheckerConfig: {
|
||||
readonly chatNotice: boolean;
|
||||
readonly hashCheckMode: HashCheckerMode;
|
||||
readonly subscribedLists: ReadonlyArray<string> | null;
|
||||
readonly subscribedLists: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
};
|
||||
} | null;
|
||||
};
|
||||
|
@ -42,7 +49,21 @@ var v0 = [
|
|||
"name": "id"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
|
@ -57,13 +78,7 @@ v1 = [
|
|||
"name": "room",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
|
@ -92,13 +107,7 @@ v1 = [
|
|||
"name": "debug",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
|
@ -130,10 +139,44 @@ v1 = [
|
|||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
],
|
||||
"concreteType": "ListConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "subscribedLists",
|
||||
"storageKey": null
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ListEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "List",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "subscribedLists(first:100)"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
|
@ -148,7 +191,7 @@ return {
|
|||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "RoomDetailQuery",
|
||||
"selections": (v1/*: any*/),
|
||||
"selections": (v3/*: any*/),
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
|
@ -157,19 +200,19 @@ return {
|
|||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "RoomDetailQuery",
|
||||
"selections": (v1/*: any*/)
|
||||
"selections": (v3/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "397376ecc93b3b405d66d01b7fd4de21",
|
||||
"cacheID": "12bcb055f358f8be4fc522afa4daf9e3",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "RoomDetailQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query RoomDetailQuery(\n $id: ID\n) {\n room(id: $id) {\n id\n active\n deactivated\n adminPowerLevel\n debug\n name\n roomId\n hashCheckerConfig {\n chatNotice\n hashCheckMode\n subscribedLists\n }\n }\n}\n"
|
||||
"text": "query RoomDetailQuery(\n $id: ID\n) {\n room(id: $id) {\n id\n active\n deactivated\n adminPowerLevel\n debug\n name\n roomId\n hashCheckerConfig {\n chatNotice\n hashCheckMode\n subscribedLists(first: 100) {\n edges {\n node {\n id\n name\n }\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "338b222f1e379335edc6847c401f52f5";
|
||||
(node as any).hash = "c5785d54de6de8e5986d7119f5dd7527";
|
||||
|
||||
export default node;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import './index.scss';
|
||||
import App from './App';
|
||||
import {store} from './app/store';
|
||||
|
@ -13,9 +12,11 @@ import {
|
|||
import "./i18n";
|
||||
import RelayEnvironment from "./RelayEnvironment";
|
||||
import {LoaderSuspense} from "./components/common/Loader";
|
||||
import {createRoot} from "react-dom/client";
|
||||
|
||||
const root = createRoot(document.getElementById('root')!);
|
||||
|
||||
ReactDOM.render(
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<Provider store={store}>
|
||||
<RelayEnvironmentProvider environment={RelayEnvironment({store})}>
|
||||
|
@ -26,8 +27,7 @@ ReactDOM.render(
|
|||
</LoaderSuspense>
|
||||
</RelayEnvironmentProvider>
|
||||
</Provider>
|
||||
</React.StrictMode>,
|
||||
document.getElementById('root')
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
|
|
|
@ -23,7 +23,15 @@ const mutation = graphql`
|
|||
hashCheckerConfig {
|
||||
chatNotice
|
||||
hashCheckMode
|
||||
subscribedLists
|
||||
subscribedLists(first: 100) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
tags
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @generated SignedSource<<c6a0a35dc80ab80f3fc8e42c6fe8a0f6>>
|
||||
* @generated SignedSource<<dc9c36fa6948f6592ee63829e7c07251>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
@ -36,7 +36,15 @@ export type ReconfigureRoomMutation$data = {
|
|||
readonly hashCheckerConfig: {
|
||||
readonly chatNotice: boolean;
|
||||
readonly hashCheckMode: HashCheckerMode;
|
||||
readonly subscribedLists: ReadonlyArray<string> | null;
|
||||
readonly subscribedLists: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly tags: ReadonlyArray<string> | null;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -53,7 +61,21 @@ var v0 = [
|
|||
"name": "reconfigureInput"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
|
@ -68,13 +90,7 @@ v1 = [
|
|||
"name": "reconfigureRoom",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
|
@ -89,13 +105,7 @@ v1 = [
|
|||
"name": "deactivated",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
|
@ -141,10 +151,51 @@ v1 = [
|
|||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
],
|
||||
"concreteType": "ListConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "subscribedLists",
|
||||
"storageKey": null
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ListEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "List",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "tags",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "subscribedLists(first:100)"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
|
@ -159,7 +210,7 @@ return {
|
|||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "ReconfigureRoomMutation",
|
||||
"selections": (v1/*: any*/),
|
||||
"selections": (v3/*: any*/),
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
|
@ -168,19 +219,19 @@ return {
|
|||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "ReconfigureRoomMutation",
|
||||
"selections": (v1/*: any*/)
|
||||
"selections": (v3/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "4186d7d18c6230e79d890ca0043dc104",
|
||||
"cacheID": "0961d774133f607eb0b0145371e73f32",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ReconfigureRoomMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation ReconfigureRoomMutation(\n $reconfigureInput: RoomConfigUpdate!\n) {\n reconfigureRoom(input: $reconfigureInput) {\n id\n active\n deactivated\n name\n roomId\n debug\n adminPowerLevel\n hashCheckerConfig {\n chatNotice\n hashCheckMode\n subscribedLists\n }\n }\n}\n"
|
||||
"text": "mutation ReconfigureRoomMutation(\n $reconfigureInput: RoomConfigUpdate!\n) {\n reconfigureRoom(input: $reconfigureInput) {\n id\n active\n deactivated\n name\n roomId\n debug\n adminPowerLevel\n hashCheckerConfig {\n chatNotice\n hashCheckMode\n subscribedLists(first: 100) {\n edges {\n node {\n id\n name\n tags\n }\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "e4ccf905922a56c92f44336d58c96a53";
|
||||
(node as any).hash = "9041b8d9fb6c1da957feb5f33ec8ac1b";
|
||||
|
||||
export default node;
|
||||
|
|
Loading…
Add table
Reference in a new issue