mirror of
https://github.com/wassname/Open-Assistant.git
synced 2026-07-04 17:20:19 +08:00
Merge branch 'main' into typesafe_i18n
This commit is contained in:
@@ -95,8 +95,8 @@ def query_frontend_user_messages(
|
||||
def query_frontend_user_messages_cursor(
|
||||
auth_method: str,
|
||||
username: str,
|
||||
lt: Optional[str] = None,
|
||||
gt: Optional[str] = None,
|
||||
before: Optional[str] = None,
|
||||
after: Optional[str] = None,
|
||||
only_roots: Optional[bool] = False,
|
||||
include_deleted: Optional[bool] = False,
|
||||
max_count: Optional[int] = Query(10, gt=0, le=1000),
|
||||
@@ -105,8 +105,8 @@ def query_frontend_user_messages_cursor(
|
||||
db: Session = Depends(deps.get_db),
|
||||
):
|
||||
return get_messages_cursor(
|
||||
lt=lt,
|
||||
gt=gt,
|
||||
before=before,
|
||||
after=after,
|
||||
auth_method=auth_method,
|
||||
username=username,
|
||||
only_roots=only_roots,
|
||||
|
||||
@@ -50,8 +50,8 @@ def query_messages(
|
||||
|
||||
@router.get("/cursor", response_model=protocol.MessagePage)
|
||||
def get_messages_cursor(
|
||||
lt: Optional[str] = None,
|
||||
gt: Optional[str] = None,
|
||||
before: Optional[str] = None,
|
||||
after: Optional[str] = None,
|
||||
user_id: Optional[UUID] = None,
|
||||
auth_method: Optional[str] = None,
|
||||
username: Optional[str] = None,
|
||||
@@ -63,6 +63,8 @@ def get_messages_cursor(
|
||||
api_client: ApiClient = Depends(deps.get_api_client),
|
||||
db: Session = Depends(deps.get_db),
|
||||
):
|
||||
assert max_count is not None
|
||||
|
||||
def split_cursor(x: str | None) -> tuple[datetime, UUID]:
|
||||
if not x:
|
||||
return None, None
|
||||
@@ -74,11 +76,21 @@ def get_messages_cursor(
|
||||
except ValueError:
|
||||
raise OasstError("Invalid cursor value", OasstErrorCode.INVALID_CURSOR_VALUE)
|
||||
|
||||
lte_created_date, lt_id = split_cursor(lt)
|
||||
gte_created_date, gt_id = split_cursor(gt)
|
||||
if desc:
|
||||
gte_created_date, gt_id = split_cursor(before)
|
||||
lte_created_date, lt_id = split_cursor(after)
|
||||
query_desc = not (before is not None and not after)
|
||||
else:
|
||||
lte_created_date, lt_id = split_cursor(before)
|
||||
gte_created_date, gt_id = split_cursor(after)
|
||||
query_desc = before is not None and not after
|
||||
|
||||
print(f"{desc=} {query_desc=} {gte_created_date=} {lte_created_date=}")
|
||||
|
||||
qry_max_count = max_count + 1 if before is None or after is None else max_count
|
||||
|
||||
pr = PromptRepository(db, api_client)
|
||||
messages = pr.query_messages_ordered_by_created_date(
|
||||
items = pr.query_messages_ordered_by_created_date(
|
||||
user_id=user_id,
|
||||
auth_method=auth_method,
|
||||
username=username,
|
||||
@@ -89,22 +101,30 @@ def get_messages_cursor(
|
||||
lt_id=lt_id,
|
||||
only_roots=only_roots,
|
||||
deleted=None if include_deleted else False,
|
||||
desc=desc,
|
||||
limit=max_count,
|
||||
desc=query_desc,
|
||||
limit=qry_max_count,
|
||||
)
|
||||
|
||||
items = utils.prepare_message_list(messages)
|
||||
num_rows = len(items)
|
||||
if qry_max_count > max_count and num_rows == qry_max_count:
|
||||
assert not (before and after)
|
||||
items = items[:-1]
|
||||
|
||||
if desc != query_desc:
|
||||
items.reverse()
|
||||
|
||||
items = utils.prepare_message_list(items)
|
||||
n, p = None, None
|
||||
if len(items) > 0:
|
||||
if len(items) == max_count or gte_created_date:
|
||||
if (num_rows > max_count and before) or after:
|
||||
p = str(items[0].id) + "$" + items[0].created_date.isoformat()
|
||||
if len(items) == max_count or lte_created_date:
|
||||
if num_rows > max_count or before:
|
||||
n = str(items[-1].id) + "$" + items[-1].created_date.isoformat()
|
||||
else:
|
||||
if gte_created_date:
|
||||
p = gte_created_date.isoformat()
|
||||
if lte_created_date:
|
||||
n = lte_created_date.isoformat()
|
||||
if after:
|
||||
p = lte_created_date.isoformat() if desc else gte_created_date.isoformat()
|
||||
if before:
|
||||
n = gte_created_date.isoformat() if desc else lte_created_date.isoformat()
|
||||
|
||||
order = "desc" if desc else "asc"
|
||||
return protocol.MessagePage(prev=p, next=n, sort_key="created_date", order=order, items=items)
|
||||
|
||||
@@ -78,8 +78,8 @@ def get_users_ordered_by_display_name(
|
||||
|
||||
@router.get("/cursor", response_model=protocol.FrontEndUserPage)
|
||||
def get_users_cursor(
|
||||
lt: Optional[str] = None,
|
||||
gt: Optional[str] = None,
|
||||
before: Optional[str] = None,
|
||||
after: Optional[str] = None,
|
||||
sort_key: Optional[str] = Query("username", max_length=32),
|
||||
max_count: Optional[int] = Query(100, gt=0, le=10000),
|
||||
api_client_id: Optional[UUID] = None,
|
||||
@@ -99,8 +99,8 @@ def get_users_cursor(
|
||||
return x, None
|
||||
|
||||
items: list[protocol.FrontEndUser]
|
||||
qry_max_count = max_count + 1 if lt is None or gt is None else max_count
|
||||
desc = lt and not gt
|
||||
qry_max_count = max_count + 1 if before is None or after is None else max_count
|
||||
desc = before is not None and not after
|
||||
|
||||
def get_next_prev(num_rows: int, lt: str | None, gt: str | None, key_fn: Callable[[protocol.FrontEndUser], str]):
|
||||
p, n = None, None
|
||||
@@ -119,7 +119,7 @@ def get_users_cursor(
|
||||
def remove_extra_item(items: list[protocol.FrontEndUser], lt: str | None, gt: str | None):
|
||||
num_rows = len(items)
|
||||
if qry_max_count > max_count and num_rows == qry_max_count:
|
||||
assert not (lt and gt)
|
||||
assert not (lt is not None and gt is not None)
|
||||
items = items[:-1]
|
||||
if desc:
|
||||
items.reverse()
|
||||
@@ -127,8 +127,8 @@ def get_users_cursor(
|
||||
|
||||
n, p = None, None
|
||||
if sort_key == "username":
|
||||
lte_username, lt_id = split_cursor(lt)
|
||||
gte_username, gt_id = split_cursor(gt)
|
||||
lte_username, lt_id = split_cursor(before)
|
||||
gte_username, gt_id = split_cursor(after)
|
||||
items = get_users_ordered_by_username(
|
||||
api_client_id=api_client_id,
|
||||
gte_username=gte_username,
|
||||
@@ -146,8 +146,8 @@ def get_users_cursor(
|
||||
p, n = get_next_prev(num_rows, lte_username, gte_username, lambda x: x.id)
|
||||
|
||||
elif sort_key == "display_name":
|
||||
lte_display_name, lt_id = split_cursor(lt)
|
||||
gte_display_name, gt_id = split_cursor(gt)
|
||||
lte_display_name, lt_id = split_cursor(before)
|
||||
gte_display_name, gt_id = split_cursor(after)
|
||||
items = get_users_ordered_by_display_name(
|
||||
api_client_id=api_client_id,
|
||||
gte_display_name=gte_display_name,
|
||||
@@ -247,8 +247,8 @@ def query_user_messages(
|
||||
@router.get("/{user_id}/messages/cursor", response_model=protocol.MessagePage)
|
||||
def query_user_messages_cursor(
|
||||
user_id: Optional[UUID],
|
||||
lt: Optional[str] = None,
|
||||
gt: Optional[str] = None,
|
||||
before: Optional[str] = None,
|
||||
after: Optional[str] = None,
|
||||
only_roots: Optional[bool] = False,
|
||||
include_deleted: Optional[bool] = False,
|
||||
max_count: Optional[int] = Query(10, gt=0, le=1000),
|
||||
@@ -257,8 +257,8 @@ def query_user_messages_cursor(
|
||||
db: Session = Depends(deps.get_db),
|
||||
):
|
||||
return get_messages_cursor(
|
||||
lt=lt,
|
||||
gt=gt,
|
||||
before=before,
|
||||
after=after,
|
||||
user_id=user_id,
|
||||
only_roots=only_roots,
|
||||
include_deleted=include_deleted,
|
||||
|
||||
@@ -43,7 +43,7 @@ def get_one_dataset(conf, dataset_name):
|
||||
if dataset_name == "debate_sum":
|
||||
train, eval = train_val_dataset(train, val_split=0.2)
|
||||
else:
|
||||
val_name = "validation" if dataset_name not in ["billsum"] else "test"
|
||||
val_name = "validation" if dataset_name not in ["billsum", "tldr_news"] else "test"
|
||||
eval = SummarizationDataset(dataset_name, conf.cache_dir, val_name)
|
||||
elif "ted_trans" in dataset_name:
|
||||
language_pair = dataset_name.split("_")[-1]
|
||||
|
||||
@@ -3,7 +3,6 @@ from typing import Optional, Union
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
from custom_datasets.qa_datasets import QA_SPECIAL_TOKENS
|
||||
from torch.nn import functional as F
|
||||
from transformers.tokenization_utils_base import PaddingStrategy, PreTrainedTokenizerBase
|
||||
|
||||
@@ -23,15 +22,8 @@ class DialogueDataCollator:
|
||||
flatten_messages = []
|
||||
label_masks = []
|
||||
|
||||
for feature_one in features:
|
||||
assert len(feature_one) % 2 == 0, "Number of messages must be even"
|
||||
# TODO: we should push this to dataset __getitem__
|
||||
messages = [
|
||||
(QA_SPECIAL_TOKENS["Question"] if i % 2 == 0 else "")
|
||||
+ x
|
||||
+ (QA_SPECIAL_TOKENS["Answer"] if i % 2 == 0 else "")
|
||||
for i, x in enumerate(feature_one)
|
||||
]
|
||||
for messages in features:
|
||||
messages = list(messages)
|
||||
|
||||
# Add a way for the model to terminate generation
|
||||
# When we predict the start of a new expected question, we want to be able to stop generation
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
QA_SPECIAL_TOKENS = {"Question": "<human>", "Answer": "<bot>", "StartPrefix": "<prefix>", "EndPrefix": "</prefix>"}
|
||||
|
||||
|
||||
def format_pair(pair):
|
||||
return "{}{}{}".format(QA_SPECIAL_TOKENS["Question"], pair[0], QA_SPECIAL_TOKENS["Answer"]), pair[1]
|
||||
@@ -2,6 +2,7 @@ import json
|
||||
import os
|
||||
from urllib.request import urlopen
|
||||
|
||||
from custom_datasets.formatting import format_pair
|
||||
from torch.utils.data import Dataset
|
||||
|
||||
|
||||
@@ -49,8 +50,7 @@ class PromptGeneratedDataset(Dataset):
|
||||
return len(self.pairs)
|
||||
|
||||
def __getitem__(self, index):
|
||||
question, answer = self.pairs[index]
|
||||
return question, answer
|
||||
return format_pair(self.pairs[index])
|
||||
|
||||
|
||||
class InstructionTuning(Dataset):
|
||||
@@ -101,5 +101,4 @@ class InstructionTuning(Dataset):
|
||||
return len(self.pairs)
|
||||
|
||||
def __getitem__(self, index):
|
||||
question, answer = self.pairs[index]
|
||||
return question, answer
|
||||
return format_pair(self.pairs[index])
|
||||
|
||||
@@ -7,14 +7,13 @@ import re
|
||||
from urllib.request import urlopen
|
||||
|
||||
import numpy as np
|
||||
from custom_datasets.formatting import QA_SPECIAL_TOKENS, format_pair
|
||||
from datasets import load_dataset
|
||||
from torch.utils.data import Dataset
|
||||
|
||||
# @agoryuno contributed this
|
||||
re_reference_remove = re.compile(r"\[\d+(?:,\s*\d+)*?\]")
|
||||
|
||||
QA_SPECIAL_TOKENS = {"Question": "<human>", "Answer": "<bot>", "StartPrefix": "<prefix>", "EndPrefix": "</prefix>"}
|
||||
|
||||
|
||||
def index_squad_v2(example):
|
||||
if len(example["answers"]["text"]):
|
||||
@@ -78,7 +77,7 @@ class QADataset(Dataset):
|
||||
|
||||
def __getitem__(self, idx):
|
||||
data = self.dataset[idx]
|
||||
return self.index_fn(data)
|
||||
return format_pair(self.index_fn(data))
|
||||
|
||||
|
||||
class WebGPT(Dataset):
|
||||
@@ -111,7 +110,7 @@ class WebGPT(Dataset):
|
||||
def __getitem__(self, index):
|
||||
question = self.index2question[index]
|
||||
answer = self.questions[question]
|
||||
return [question, answer]
|
||||
return format_pair((question, answer))
|
||||
|
||||
|
||||
class SODA(Dataset):
|
||||
@@ -121,14 +120,14 @@ class SODA(Dataset):
|
||||
def process_soda_convo(self, data):
|
||||
pairs = []
|
||||
play_as = data["speakers"][1]
|
||||
prefix = "{}{}. {}{}".format(
|
||||
QA_SPECIAL_TOKENS["StartPrefix"],
|
||||
data["narrative"],
|
||||
"your name {}".format(play_as),
|
||||
QA_SPECIAL_TOKENS["EndPrefix"],
|
||||
)
|
||||
question, answer = "", ""
|
||||
prefix, postfix = "", ""
|
||||
dialogue_bg = "{}{} {}{}".format(
|
||||
QA_SPECIAL_TOKENS["StartPrefix"],
|
||||
data["narrative"],
|
||||
"your are {}".format(play_as),
|
||||
QA_SPECIAL_TOKENS["EndPrefix"],
|
||||
)
|
||||
previous_chat = []
|
||||
|
||||
for idx, convo in enumerate(data["dialogue"]):
|
||||
@@ -138,14 +137,20 @@ class SODA(Dataset):
|
||||
else:
|
||||
answer = convo
|
||||
postfix = data["speakers"][idx]
|
||||
|
||||
if len(question) and len(answer) and prefix != postfix and postfix == play_as:
|
||||
history = "<sep>".join(
|
||||
["{}{}{}".format(p[0], QA_SPECIAL_TOKENS["Answer"], p[1]) for p in previous_chat]
|
||||
[
|
||||
"{}{}{}{}".format(QA_SPECIAL_TOKENS["Question"], p[0], QA_SPECIAL_TOKENS["Answer"], p[1])
|
||||
for p in previous_chat
|
||||
]
|
||||
)
|
||||
if len(history):
|
||||
history += "<sep>"
|
||||
pairs.append((prefix + history + question, answer))
|
||||
prompt = QA_SPECIAL_TOKENS["Question"] + question + QA_SPECIAL_TOKENS["Answer"]
|
||||
pairs.append((dialogue_bg + history + prompt, answer))
|
||||
previous_chat.append((question, answer))
|
||||
|
||||
return pairs
|
||||
|
||||
def __init__(self, cache_dir, max_sample_size=10000, input_max_length=1024) -> None:
|
||||
@@ -166,8 +171,8 @@ class SODA(Dataset):
|
||||
return len(self.pairs)
|
||||
|
||||
def __getitem__(self, index):
|
||||
question, answer = self.pairs[index]
|
||||
return question, answer
|
||||
# special token added during preprocess
|
||||
return self.pairs[index]
|
||||
|
||||
|
||||
class SODADialogue(Dataset):
|
||||
@@ -218,7 +223,7 @@ class SODADialogue(Dataset):
|
||||
return len(self.pairs)
|
||||
|
||||
def __getitem__(self, index):
|
||||
return self.pairs[index]
|
||||
return format_pair(self.pairs[index])
|
||||
|
||||
|
||||
class JokeExplaination(Dataset):
|
||||
@@ -253,8 +258,7 @@ class JokeExplaination(Dataset):
|
||||
return len(self.pairs)
|
||||
|
||||
def __getitem__(self, index):
|
||||
question, answer = self.pairs[index]
|
||||
return question, answer
|
||||
return format_pair(self.pairs[index])
|
||||
|
||||
|
||||
# https://huggingface.co/datasets/aquamuse
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"""
|
||||
import random
|
||||
|
||||
from custom_datasets.formatting import format_pair
|
||||
from datasets import load_dataset
|
||||
from torch.utils.data import Dataset
|
||||
|
||||
@@ -54,11 +55,12 @@ def index_summary_merge(text, summary):
|
||||
|
||||
|
||||
class SummarizationDataset(Dataset):
|
||||
def __init__(self, dataset, cache_dir, split):
|
||||
def __init__(self, dataset, cache_dir, split, max_words=512):
|
||||
self.name = dataset
|
||||
self.dataset = load_dataset(*summarization_config_mapping[dataset], cache_dir=cache_dir, split=split)
|
||||
self.text_column, self.summary_column = summarization_name_mapping[dataset]
|
||||
self.preprocess_fn = index_summary_merge if dataset == "scitldr" else index_summary_default
|
||||
self.max_words = max_words
|
||||
|
||||
def __len__(self):
|
||||
return len(self.dataset)
|
||||
@@ -72,4 +74,5 @@ class SummarizationDataset(Dataset):
|
||||
else:
|
||||
prompt = random.choice(SUMMARIZATION_SPECIAL_TOKENS["Summary"])
|
||||
|
||||
return ("".join([SUMMARIZATION_SPECIAL_TOKENS["Text"], " ".join(text.split(" ")[:256]), prompt]), summary)
|
||||
context = "".join([SUMMARIZATION_SPECIAL_TOKENS["Text"], " ".join(text.split(" ")[: self.max_words]), prompt])
|
||||
return format_pair((context, summary))
|
||||
|
||||
@@ -4,12 +4,13 @@
|
||||
"""
|
||||
import random
|
||||
|
||||
from custom_datasets.formatting import QA_SPECIAL_TOKENS, format_pair
|
||||
from datasets import load_dataset
|
||||
from torch.utils.data import Dataset
|
||||
|
||||
|
||||
class ProsocialDialogueExplaination(Dataset):
|
||||
name = "prosocial_explain"
|
||||
name = "explain_prosocial"
|
||||
TEMPLATE = [
|
||||
# 0 : reply or sentence of interest, 1 : reason of caution
|
||||
("'{0}' Why is this sentence {1}", "This sentence is {1} because {0}"),
|
||||
@@ -36,7 +37,7 @@ class ProsocialDialogueExplaination(Dataset):
|
||||
return len(self.pairs)
|
||||
|
||||
def __getitem__(self, idx):
|
||||
return self.pairs[idx]
|
||||
return format_pair(self.pairs[idx])
|
||||
|
||||
|
||||
class ProsocialDialogue(Dataset):
|
||||
@@ -58,8 +59,9 @@ class ProsocialDialogue(Dataset):
|
||||
dataset = load_dataset("allenai/prosocial-dialog", cache_dir=cache_dir)[split]
|
||||
self.pairs = []
|
||||
for row in dataset:
|
||||
prompt = QA_SPECIAL_TOKENS["Question"] + row["context"] + QA_SPECIAL_TOKENS["Answer"]
|
||||
for answer in row["rots"]:
|
||||
self.pairs.append((self.PREFIX + row["context"], answer))
|
||||
self.pairs.append((self.PREFIX + prompt, answer))
|
||||
|
||||
def __len__(self):
|
||||
return len(self.pairs)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"""
|
||||
import random
|
||||
|
||||
from custom_datasets.formatting import format_pair
|
||||
from datasets import load_dataset
|
||||
from torch.utils.data import Dataset
|
||||
|
||||
@@ -82,7 +83,7 @@ class TranslationPair(Dataset):
|
||||
return len(self.pairs)
|
||||
|
||||
def __getitem__(self, index):
|
||||
return self.pairs[index]
|
||||
return format_pair(self.pairs[index])
|
||||
|
||||
|
||||
class WMT2019(TranslationPair):
|
||||
@@ -99,6 +100,8 @@ class WMT2019(TranslationPair):
|
||||
else: # translating in reverse direction
|
||||
source = random.choice(TRANSLATION_PROMPT[src]).format(row[tgt])
|
||||
self.pairs.append((source, row[src]))
|
||||
if len(self.pairs) > 100000:
|
||||
break
|
||||
|
||||
|
||||
class DiveMT(TranslationPair):
|
||||
|
||||
@@ -7,8 +7,8 @@ from custom_datasets.dialogue_collator import DialogueDataCollator
|
||||
def test_all_datasets():
|
||||
qa_base = QA_DATASETS
|
||||
summarize_base = SUMMARIZATION_DATASETS
|
||||
others = ["prompt_dialogue", "webgpt", "soda", "joke", "instruct_tuning"]
|
||||
translation = ["dive_mt", "wmt2019_zh-en", "wmt2019_ru-en", "wmt2019_de-en", "ted_trans_de-ja", "ted_trans_nl-en"]
|
||||
others = ["prompt_dialogue", "webgpt", "soda", "joke", "instruct_tuning", "explain_prosocial", "prosocial_dialogue"]
|
||||
translation = ["dive_mt", "wmt2019_zh-en", "wmt2019_ru-en", "ted_trans_de-ja", "ted_trans_nl-en"]
|
||||
|
||||
config = Namespace(cache_dir=".cache")
|
||||
for dataset_name in translation + others + summarize_base + qa_base:
|
||||
@@ -31,7 +31,6 @@ def test_collate_fn():
|
||||
qa_base = QA_DATASETS
|
||||
summarize_base = SUMMARIZATION_DATASETS
|
||||
others = ["prompt_dialogue", "webgpt", "soda", "joke", "gsm8k"]
|
||||
|
||||
trains, evals = [], []
|
||||
for dataset_name in others + qa_base + summarize_base:
|
||||
print(dataset_name)
|
||||
@@ -41,10 +40,10 @@ def test_collate_fn():
|
||||
|
||||
dataloader = DataLoader(ConcatDataset(trains), collate_fn=collate_fn, batch_size=128)
|
||||
for batch in dataloader:
|
||||
# print(batch.keys())
|
||||
# print(tokenizer.decode(batch['input_ids'][0]))
|
||||
# print('-----')
|
||||
# print(tokenizer.decode(batch['targets'][0][batch['label_masks'][0]]))
|
||||
print(batch.keys())
|
||||
print(tokenizer.decode(batch["input_ids"][0]))
|
||||
print("-----")
|
||||
print(tokenizer.decode(batch["targets"][0][batch["label_masks"][0]]))
|
||||
assert batch["targets"].shape[1] <= 512
|
||||
dataloader = DataLoader(ConcatDataset(evals), collate_fn=collate_fn, batch_size=128)
|
||||
for batch in dataloader:
|
||||
|
||||
@@ -25,6 +25,10 @@ def get_tokenizer(conf):
|
||||
tokenizer.add_special_tokens({"pad_token": tokenizer.eos_token, "sep_token": "<|extratoken_100|>"})
|
||||
elif "codegen" in conf.model_name:
|
||||
tokenizer.add_special_tokens({"pad_token": "<|endoftext|>", "sep_token": "<|endoftext|>"})
|
||||
elif "pythia" in conf.model_name:
|
||||
tokenizer.add_special_tokens(
|
||||
{"pad_token": "<|padding|>", "sep_token": "<|endoftext|>", "eos_token": "<|endoftext|>"}
|
||||
)
|
||||
|
||||
additional_special_tokens = (
|
||||
[]
|
||||
|
||||
Generated
+15
-15
@@ -33,6 +33,7 @@
|
||||
"focus-visible": "^5.2.0",
|
||||
"framer-motion": "^6.5.1",
|
||||
"install": "^0.13.0",
|
||||
"lucide-react": "^0.105.0",
|
||||
"next": "13.0.6",
|
||||
"next-auth": "^4.18.6",
|
||||
"next-i18next": "^13.0.3",
|
||||
@@ -45,7 +46,6 @@
|
||||
"react-feature-flags": "^1.0.0",
|
||||
"react-hook-form": "^7.42.1",
|
||||
"react-i18next": "^12.1.4",
|
||||
"react-icons": "^4.7.1",
|
||||
"react-table": "^7.8.0",
|
||||
"sharp": "^0.31.3",
|
||||
"swr": "^2.0.0",
|
||||
@@ -26726,6 +26726,14 @@
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/lucide-react": {
|
||||
"version": "0.105.0",
|
||||
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.105.0.tgz",
|
||||
"integrity": "sha512-iHaIkd4Wq6aNIVrFMXt3If8E/+2lnJd4WlCyntoJNIzZ8nWhdSSHWpsw7XM4rlw2319LZ2t4WLdnM8Z0ECDTOQ==",
|
||||
"peerDependencies": {
|
||||
"react": "^16.5.1 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lz-string": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz",
|
||||
@@ -32657,14 +32665,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-icons": {
|
||||
"version": "4.7.1",
|
||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.7.1.tgz",
|
||||
"integrity": "sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==",
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
@@ -57914,6 +57914,12 @@
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"lucide-react": {
|
||||
"version": "0.105.0",
|
||||
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.105.0.tgz",
|
||||
"integrity": "sha512-iHaIkd4Wq6aNIVrFMXt3If8E/+2lnJd4WlCyntoJNIzZ8nWhdSSHWpsw7XM4rlw2319LZ2t4WLdnM8Z0ECDTOQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"lz-string": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz",
|
||||
@@ -62143,12 +62149,6 @@
|
||||
"html-parse-stringify": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"react-icons": {
|
||||
"version": "4.7.1",
|
||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.7.1.tgz",
|
||||
"integrity": "sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==",
|
||||
"requires": {}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"focus-visible": "^5.2.0",
|
||||
"framer-motion": "^6.5.1",
|
||||
"install": "^0.13.0",
|
||||
"lucide-react": "^0.105.0",
|
||||
"next": "13.0.6",
|
||||
"next-auth": "^4.18.6",
|
||||
"next-i18next": "^13.0.3",
|
||||
@@ -62,7 +63,6 @@
|
||||
"react-feature-flags": "^1.0.0",
|
||||
"react-hook-form": "^7.42.1",
|
||||
"react-i18next": "^12.1.4",
|
||||
"react-icons": "^4.7.1",
|
||||
"react-table": "^7.8.0",
|
||||
"sharp": "^0.31.3",
|
||||
"swr": "^2.0.0",
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Box, Link, Text, useColorMode } from "@chakra-ui/react";
|
||||
import { Github } from "lucide-react";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { useId } from "react";
|
||||
import { FaDiscord, FaGithub } from "react-icons/fa";
|
||||
|
||||
import { Container } from "./Container";
|
||||
import { Discord } from "./Icons/Discord";
|
||||
|
||||
const CIRCLE_HEIGHT = 558;
|
||||
const CIRCLE_WIDTH = 558;
|
||||
@@ -70,7 +71,7 @@ export function CallToAction() {
|
||||
type="button"
|
||||
className="mb-2 ml-6 flex items-center rounded-md border border-transparent bg-blue-600 px-6 py-3 text-base font-medium text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
|
||||
>
|
||||
<FaDiscord size={25} />
|
||||
<Discord size={25} />
|
||||
<Text as="span" className="text-lg ml-3">
|
||||
{t("discord")}
|
||||
</Text>
|
||||
@@ -81,7 +82,7 @@ export function CallToAction() {
|
||||
type="button"
|
||||
className="mb-2 ml-6 flex items-center rounded-md border border-transparent bg-blue-600 px-6 py-3 text-base font-medium text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
|
||||
>
|
||||
<FaGithub size={25} />
|
||||
<Github size={25} />
|
||||
<Text as="span" className="text-lg ml-3">
|
||||
{t("github")}
|
||||
</Text>
|
||||
|
||||
@@ -25,8 +25,8 @@ import {
|
||||
useDisclosure,
|
||||
} from "@chakra-ui/react";
|
||||
import { ColumnDef, flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table";
|
||||
import { Filter } from "lucide-react";
|
||||
import { ChangeEvent, ReactNode } from "react";
|
||||
import { FaFilter } from "react-icons/fa";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
|
||||
export type DataTableColumnDef<T> = ColumnDef<T> & {
|
||||
@@ -148,7 +148,7 @@ const FilterModal = ({
|
||||
<Popover isOpen={isOpen} onOpen={onOpen} onClose={onClose}>
|
||||
<PopoverTrigger>
|
||||
<Button variant={"unstyled"} ml="2">
|
||||
<FaFilter></FaFilter>
|
||||
<Filter size="1em"></Filter>
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent w="fit-content">
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { Box, Text, useColorModeValue } from "@chakra-ui/react";
|
||||
import { AlertTriangle, LucideIcon } from "lucide-react";
|
||||
import NextLink from "next/link";
|
||||
import { FiAlertTriangle } from "react-icons/fi";
|
||||
import { IconType } from "react-icons/lib";
|
||||
|
||||
type EmptyStateProps = {
|
||||
text: string;
|
||||
icon: IconType;
|
||||
icon: LucideIcon;
|
||||
};
|
||||
|
||||
export const EmptyState = (props: EmptyStateProps) => {
|
||||
@@ -25,5 +24,5 @@ export const EmptyState = (props: EmptyStateProps) => {
|
||||
};
|
||||
|
||||
export const TaskEmptyState = () => {
|
||||
return <EmptyState text="Looks like no tasks were found." icon={FiAlertTriangle} />;
|
||||
return <EmptyState text="Looks like no tasks were found." icon={AlertTriangle} />;
|
||||
};
|
||||
|
||||
@@ -22,8 +22,8 @@ import {
|
||||
} from "@chakra-ui/react";
|
||||
import { QuestionMarkCircleIcon } from "@heroicons/react/20/solid";
|
||||
import clsx from "clsx";
|
||||
import { AlertCircle } from "lucide-react";
|
||||
import { useEffect, useReducer } from "react";
|
||||
import { FiAlertCircle } from "react-icons/fi";
|
||||
import { get, post } from "src/lib/api";
|
||||
import { colors } from "src/styles/Theme/colors";
|
||||
import { Message } from "src/types/Conversation";
|
||||
@@ -154,7 +154,7 @@ export const FlaggableElement = (props: FlaggableElementProps) => {
|
||||
<Box>
|
||||
<PopoverTrigger>
|
||||
<Box as="button" display="flex" alignItems="center" justifyContent="center" borderRadius="full" p="1">
|
||||
<FiAlertCircle size="20" className="text-red-400" aria-hidden="true" />
|
||||
<AlertCircle size="20" className="text-red-400" aria-hidden="true" />
|
||||
</Box>
|
||||
</PopoverTrigger>
|
||||
</Box>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Box, Button, Flex, Text } from "@chakra-ui/react";
|
||||
import { User } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { Flags } from "react-feature-flags";
|
||||
import { FaUser } from "react-icons/fa";
|
||||
import { LanguageSelector } from "src/components/LanguageSelector";
|
||||
|
||||
import { UserMenu } from "./UserMenu";
|
||||
@@ -17,7 +17,7 @@ function AccountButton() {
|
||||
return (
|
||||
<Link href="/auth/signin" aria-label="Home">
|
||||
<Flex alignItems="center">
|
||||
<Button variant="outline" leftIcon={<FaUser />}>
|
||||
<Button variant="outline" leftIcon={<User size={"20"} />}>
|
||||
Sign in
|
||||
</Button>
|
||||
</Flex>
|
||||
|
||||
@@ -11,11 +11,11 @@ import {
|
||||
Text,
|
||||
useColorModeValue,
|
||||
} from "@chakra-ui/react";
|
||||
import { AlertTriangle, Layout, LogOut, Settings, Shield } from "lucide-react";
|
||||
import NextLink from "next/link";
|
||||
import { signOut, useSession } from "next-auth/react";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import React, { ElementType, useCallback } from "react";
|
||||
import { FiAlertTriangle, FiLayout, FiLogOut, FiSettings, FiShield } from "react-icons/fi";
|
||||
|
||||
interface MenuOption {
|
||||
name: string;
|
||||
@@ -39,19 +39,19 @@ export function UserMenu() {
|
||||
{
|
||||
name: t("dashboard"),
|
||||
href: "/dashboard",
|
||||
icon: FiLayout,
|
||||
icon: Layout,
|
||||
isExternal: false,
|
||||
},
|
||||
{
|
||||
name: t("account_settings"),
|
||||
href: "/account",
|
||||
icon: FiSettings,
|
||||
icon: Settings,
|
||||
isExternal: false,
|
||||
},
|
||||
{
|
||||
name: t("report_a_bug"),
|
||||
href: "https://github.com/LAION-AI/Open-Assistant/issues/new/choose",
|
||||
icon: FiAlertTriangle,
|
||||
icon: AlertTriangle,
|
||||
isExternal: true,
|
||||
},
|
||||
];
|
||||
@@ -60,7 +60,7 @@ export function UserMenu() {
|
||||
options.unshift({
|
||||
name: t("admin_dashboard"),
|
||||
href: "/admin",
|
||||
icon: FiShield,
|
||||
icon: Shield,
|
||||
isExternal: false,
|
||||
});
|
||||
}
|
||||
@@ -93,7 +93,7 @@ export function UserMenu() {
|
||||
_hover={{ textDecoration: "none" }}
|
||||
>
|
||||
<MenuItem gap="3" borderRadius="md" p="4">
|
||||
<item.icon className="text-blue-500" aria-hidden="true" />
|
||||
<item.icon size="1em" className="text-blue-500" aria-hidden="true" />
|
||||
<Text>{item.name}</Text>
|
||||
</MenuItem>
|
||||
</Link>
|
||||
@@ -101,7 +101,7 @@ export function UserMenu() {
|
||||
</MenuGroup>
|
||||
<MenuDivider />
|
||||
<MenuItem gap="3" borderRadius="md" p="4" onClick={handleSignOut}>
|
||||
<FiLogOut className="text-blue-500" aria-hidden="true" />
|
||||
<LogOut size="1em" className="text-blue-500" aria-hidden="true" />
|
||||
<Text>{t("sign_out")}</Text>
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { LucideIcon } from "lucide-react";
|
||||
|
||||
export const Discord: LucideIcon = ({ size = 24, ...rest }) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 127.14 96.36"
|
||||
fill="currentColor"
|
||||
height={size}
|
||||
width={size}
|
||||
{...rest}
|
||||
>
|
||||
<path d="M107.7 8.07A105.15 105.15 0 0 0 81.47 0a72.06 72.06 0 0 0-3.36 6.83 97.68 97.68 0 0 0-29.11 0A72.37 72.37 0 0 0 45.64 0a105.89 105.89 0 0 0-26.25 8.09C2.79 32.65-1.71 56.6.54 80.21a105.73 105.73 0 0 0 32.17 16.15 77.7 77.7 0 0 0 6.89-11.11 68.42 68.42 0 0 1-10.85-5.18c.91-.66 1.8-1.34 2.66-2a75.57 75.57 0 0 0 64.32 0c.87.71 1.76 1.39 2.66 2a68.68 68.68 0 0 1-10.87 5.19 77 77 0 0 0 6.89 11.1 105.25 105.25 0 0 0 32.19-16.14c2.64-27.38-4.51-51.11-18.9-72.15ZM42.45 65.69C36.18 65.69 31 60 31 53s5-12.74 11.43-12.74S54 46 53.89 53s-5.05 12.69-11.44 12.69Zm42.24 0C78.41 65.69 73.25 60 73.25 53s5-12.74 11.44-12.74S96.23 46 96.12 53s-5.04 12.69-11.43 12.69Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -8,12 +8,13 @@ const LanguageSelector = () => {
|
||||
const router = useRouter();
|
||||
const { i18n } = useTranslation();
|
||||
|
||||
const { language: currentLanguage } = i18n;
|
||||
const languageNames = useMemo(() => {
|
||||
return new Intl.DisplayNames([currentLanguage], {
|
||||
type: "language",
|
||||
});
|
||||
}, [currentLanguage]);
|
||||
// Memo the set of locales and their display names.
|
||||
const localesAndNames = useMemo(() => {
|
||||
return router.locales.map((locale) => ({
|
||||
locale,
|
||||
name: new Intl.DisplayNames([locale], { type: "language" }).of(locale),
|
||||
}));
|
||||
}, [router.locales]);
|
||||
|
||||
const languageChanged = useCallback(
|
||||
async (option) => {
|
||||
@@ -25,12 +26,12 @@ const LanguageSelector = () => {
|
||||
[router]
|
||||
);
|
||||
|
||||
const locales = router.locales;
|
||||
const { language: currentLanguage } = i18n;
|
||||
return (
|
||||
<Select onChange={languageChanged} defaultValue={currentLanguage}>
|
||||
{locales.map((locale) => (
|
||||
{localesAndNames.map(({ locale, name }) => (
|
||||
<option key={locale} value={locale}>
|
||||
{languageNames.of(locale) ?? locale}
|
||||
{name}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// https://nextjs.org/docs/basic-features/layouts
|
||||
|
||||
import { Box, Grid } from "@chakra-ui/react";
|
||||
import { Activity, BarChart2, Layout, MessageSquare, Users } from "lucide-react";
|
||||
import type { NextPage } from "next";
|
||||
import { FiBarChart2, FiLayout, FiMessageSquare, FiUsers, FiActivity } from "react-icons/fi";
|
||||
import { Header } from "src/components/Header";
|
||||
|
||||
import { SlimFooter } from "./Dashboard/SlimFooter";
|
||||
@@ -38,19 +38,19 @@ export const getDashboardLayout = (page: React.ReactElement) => (
|
||||
label: "Dashboard",
|
||||
pathname: "/dashboard",
|
||||
desc: "Dashboard Home",
|
||||
icon: FiLayout,
|
||||
icon: Layout,
|
||||
},
|
||||
{
|
||||
label: "Messages",
|
||||
pathname: "/messages",
|
||||
desc: "Messages Dashboard",
|
||||
icon: FiMessageSquare,
|
||||
icon: MessageSquare,
|
||||
},
|
||||
{
|
||||
label: "Leaderboard",
|
||||
pathname: "/leaderboard",
|
||||
desc: "User Leaderboard",
|
||||
icon: FiBarChart2,
|
||||
icon: BarChart2,
|
||||
},
|
||||
]}
|
||||
>
|
||||
@@ -73,13 +73,13 @@ export const getAdminLayout = (page: React.ReactElement) => (
|
||||
label: "Users",
|
||||
pathname: "/admin",
|
||||
desc: "Users Dashboard",
|
||||
icon: FiUsers,
|
||||
icon: Users,
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
pathname: "/admin/status",
|
||||
desc: "Status Dashboard",
|
||||
icon: FiActivity,
|
||||
icon: Activity,
|
||||
},
|
||||
]}
|
||||
>
|
||||
|
||||
@@ -5,13 +5,19 @@ import { Message } from "src/types/Conversation";
|
||||
interface MessageTableProps {
|
||||
messages: Message[];
|
||||
enableLink?: boolean;
|
||||
highlightLastMessage?: boolean;
|
||||
}
|
||||
|
||||
export function MessageTable({ messages, enableLink }: MessageTableProps) {
|
||||
export function MessageTable({ messages, enableLink, highlightLastMessage }: MessageTableProps) {
|
||||
return (
|
||||
<Stack spacing="4">
|
||||
{messages.map((item) => (
|
||||
<MessageTableEntry enabled={enableLink} item={item} key={item.id + item.frontend_message_id} />
|
||||
{messages.map((item, idx) => (
|
||||
<MessageTableEntry
|
||||
enabled={enableLink}
|
||||
item={item}
|
||||
key={item.id + item.frontend_message_id}
|
||||
highlight={highlightLastMessage && idx === messages.length - 1}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { Avatar, Box, HStack, LinkBox, useBreakpoint, useBreakpointValue, useColorModeValue } from "@chakra-ui/react";
|
||||
import { Avatar, Box, HStack, useBreakpointValue, useColorModeValue } from "@chakra-ui/react";
|
||||
import { boolean } from "boolean";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { FlaggableElement } from "src/components/FlaggableElement";
|
||||
import { Message } from "src/types/Conversation";
|
||||
import { colors } from "styles/Theme/colors";
|
||||
|
||||
interface MessageTableEntryProps {
|
||||
item: Message;
|
||||
enabled?: boolean;
|
||||
highlight?: boolean;
|
||||
}
|
||||
|
||||
export function MessageTableEntry(props: MessageTableEntryProps) {
|
||||
@@ -37,6 +38,7 @@ export function MessageTableEntry(props: MessageTableEntryProps) {
|
||||
),
|
||||
[borderColor, inlineAvatar, item.is_assistant]
|
||||
);
|
||||
const highlightColor = useColorModeValue(colors.light.highlight, colors.dark.highlight);
|
||||
|
||||
return (
|
||||
<FlaggableElement message={item}>
|
||||
@@ -48,6 +50,8 @@ export function MessageTableEntry(props: MessageTableEntryProps) {
|
||||
p="4"
|
||||
borderRadius="md"
|
||||
bg={item.is_assistant ? backgroundColor : backgroundColor2}
|
||||
outline={props.highlight && "2px solid black"}
|
||||
outlineColor={highlightColor}
|
||||
onClick={props.enabled && goToMessage}
|
||||
_hover={props.enabled && { cursor: "pointer", opacity: 0.9 }}
|
||||
whiteSpace="pre-wrap"
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import { Box, Button, Text, Tooltip, useColorMode } from "@chakra-ui/react";
|
||||
import { LucideIcon, Sun } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { FiSun } from "react-icons/fi";
|
||||
import { IconType } from "react-icons/lib";
|
||||
import { colors } from "styles/Theme/colors";
|
||||
|
||||
export interface MenuButtonOption {
|
||||
label: string;
|
||||
pathname: string;
|
||||
desc: string;
|
||||
icon: IconType;
|
||||
icon: LucideIcon;
|
||||
}
|
||||
|
||||
export interface SideMenuProps {
|
||||
@@ -47,7 +46,7 @@ export function SideMenu(props: SideMenuProps) {
|
||||
bg={router.pathname === item.pathname ? "blue.500" : null}
|
||||
_hover={router.pathname === item.pathname ? { bg: "blue.600" } : null}
|
||||
>
|
||||
<item.icon className={router.pathname === item.pathname ? "text-blue-200" : null} />
|
||||
<item.icon size={"1em"} className={router.pathname === item.pathname ? "text-blue-200" : null} />
|
||||
<Text
|
||||
fontWeight="normal"
|
||||
color={router.pathname === item.pathname ? "white" : null}
|
||||
@@ -63,7 +62,7 @@ export function SideMenu(props: SideMenuProps) {
|
||||
<div>
|
||||
<Tooltip fontFamily="inter" label="Toggle Dark Mode" placement="right" className="hidden lg:hidden sm:block">
|
||||
<Button size="lg" width="full" justifyContent="center" onClick={toggleColorMode} gap="2">
|
||||
<FiSun />
|
||||
<Sun size={"1em"} />
|
||||
<Text fontWeight="normal" className="hidden lg:block">
|
||||
{colorMode === "light" ? "Dark Mode" : "Light Mode"}
|
||||
</Text>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Box, useColorModeValue } from "@chakra-ui/react";
|
||||
import { useSortable } from "@dnd-kit/sortable";
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
import { GripVertical } from "lucide-react";
|
||||
import { PropsWithChildren, useState } from "react";
|
||||
import { RxDragHandleDots2 } from "react-icons/rx";
|
||||
|
||||
export const SortableItem = ({
|
||||
children,
|
||||
@@ -45,7 +45,7 @@ export const SortableItem = ({
|
||||
style={style}
|
||||
shadow="base"
|
||||
>
|
||||
<Box pr="4">{isEditable ? <RxDragHandleDots2 size="20px" /> : `${index + 1}.`}</Box>
|
||||
<Box pr="4">{isEditable ? <GripVertical size="20px" /> : `${index + 1}.`}</Box>
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Box, Flex, IconButton, Tooltip, useColorModeValue } from "@chakra-ui/react";
|
||||
import { FiEdit2 } from "react-icons/fi";
|
||||
import { Edit2 } from "lucide-react";
|
||||
import { SkipButton } from "src/components/Buttons/Skip";
|
||||
import { SubmitButton } from "src/components/Buttons/Submit";
|
||||
import { TaskInfo } from "src/components/TaskInfo/TaskInfo";
|
||||
@@ -36,7 +36,13 @@ export const TaskControls = (props: TaskControlsProps) => {
|
||||
{props.taskStatus === "REVIEW" || props.taskStatus === "SUBMITTED" ? (
|
||||
<>
|
||||
<Tooltip label="Edit">
|
||||
<IconButton size="lg" data-cy="edit" aria-label="edit" onClick={props.onEdit} icon={<FiEdit2 />} />
|
||||
<IconButton
|
||||
size="lg"
|
||||
data-cy="edit"
|
||||
aria-label="edit"
|
||||
onClick={props.onEdit}
|
||||
icon={<Edit2 size="1em" />}
|
||||
/>
|
||||
</Tooltip>
|
||||
<SubmitButton
|
||||
colorScheme="green"
|
||||
|
||||
@@ -36,7 +36,7 @@ export const CreateTask = ({
|
||||
<TaskHeader taskType={taskType} />
|
||||
{task.conversation ? (
|
||||
<Box mt="4" borderRadius="lg" bg={cardColor} className="p-3 sm:p-6">
|
||||
<MessageTable messages={task.conversation.messages} />
|
||||
<MessageTable messages={task.conversation.messages} highlightLastMessage />
|
||||
</Box>
|
||||
) : null}
|
||||
</>
|
||||
|
||||
@@ -38,7 +38,7 @@ export const EvaluateTask = ({
|
||||
<SurveyCard>
|
||||
<TaskHeader taskType={taskType} />
|
||||
<Box mt="4" p="6" borderRadius="lg" bg={cardColor}>
|
||||
<MessageTable messages={messages} />
|
||||
<MessageTable messages={messages} highlightLastMessage />
|
||||
</Box>
|
||||
<Sortable
|
||||
items={task[sortables]}
|
||||
|
||||
@@ -53,6 +53,7 @@ export const LabelTask = ({
|
||||
message_id: task.message_id,
|
||||
},
|
||||
]}
|
||||
highlightLastMessage
|
||||
/>
|
||||
</Box>
|
||||
) : (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { HStack, IconButton, Link, Stack, Text, useColorModeValue } from "@chakra-ui/react";
|
||||
import { FiHelpCircle } from "react-icons/fi";
|
||||
import { HelpCircle } from "lucide-react";
|
||||
import type { TaskInfo } from "src/components/Tasks/TaskTypes";
|
||||
|
||||
interface TaskHeaderProps {
|
||||
@@ -22,7 +22,7 @@ const TaskHeader = ({ taskType }: TaskHeaderProps) => {
|
||||
{taskType.label}
|
||||
</Text>
|
||||
<Link href={taskType.help_link} isExternal>
|
||||
<IconButton variant="ghost" aria-label="More Information" icon={<FiHelpCircle />} />
|
||||
<IconButton variant="ghost" aria-label="More Information" icon={<HelpCircle size="1em" />} />
|
||||
</Link>
|
||||
</HStack>
|
||||
<Text fontSize="md" color={labelColor}>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { IconButton } from "@chakra-ui/react";
|
||||
import { createColumnHelper } from "@tanstack/react-table";
|
||||
import { Pencil } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { memo, useState } from "react";
|
||||
import { FaPen } from "react-icons/fa";
|
||||
import { get } from "src/lib/api";
|
||||
import { FetchUsersResponse } from "src/lib/oasst_api_client";
|
||||
import type { User } from "src/types/Users";
|
||||
@@ -49,7 +49,7 @@ const columns: DataTableColumnDef<User>[] = [
|
||||
as={Link}
|
||||
href={`/admin/manage_user/${getValue()}`}
|
||||
aria-label="Manage"
|
||||
icon={<FaPen></FaPen>}
|
||||
icon={<Pencil size="1em"></Pencil>}
|
||||
></IconButton>
|
||||
),
|
||||
header: "Update",
|
||||
|
||||
@@ -221,7 +221,7 @@ export class OasstApiClient {
|
||||
// pagination direction but they both take the same cursor value.
|
||||
// Depending on direction, pick the right query param.
|
||||
if (cursor !== "") {
|
||||
params.append(direction === "forward" ? "gt" : "lt", cursor);
|
||||
params.append(direction === "forward" ? "after" : "before", cursor);
|
||||
}
|
||||
const BASE_URL = `/api/v1/users/cursor`;
|
||||
const url = `${BASE_URL}/?${params.toString()}`;
|
||||
@@ -269,8 +269,8 @@ export class OasstApiClient {
|
||||
/**
|
||||
* Returns the counts of all tasks (some might be zero)
|
||||
*/
|
||||
async fetch_available_tasks(user: BackendUserCore): Promise<AvailableTasks> {
|
||||
return this.post(`/api/v1/tasks/availability`, user);
|
||||
async fetch_available_tasks(user: BackendUserCore, lang: string): Promise<AvailableTasks> {
|
||||
return this.post(`/api/v1/tasks/availability`, { ...user, lang });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ const LOCALE_SET = new Set(i18n.locales);
|
||||
* the i18n module.
|
||||
* 3. "en" as a final fallback.
|
||||
*/
|
||||
const getUserLanguage = (req: NextApiRequest) => {
|
||||
const getUserLanguage = (req: NextApiRequest): string => {
|
||||
const cookieLanguage = req.cookies["NEXT_LOCALE"];
|
||||
if (cookieLanguage) {
|
||||
return cookieLanguage;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Box, Button, Center, Link, Text } from "@chakra-ui/react";
|
||||
import { AlertTriangle } from "lucide-react";
|
||||
import Head from "next/head";
|
||||
import { FiAlertTriangle } from "react-icons/fi";
|
||||
import { EmptyState } from "src/components/EmptyState";
|
||||
import { getTransparentHeaderLayout } from "src/components/Layout";
|
||||
export { getDefaultStaticProps as getStaticProps } from "src/lib/default_static_props";
|
||||
@@ -13,12 +13,12 @@ function Error() {
|
||||
<meta name="404" content="Sorry, this page doesn't exist." />
|
||||
</Head>
|
||||
<Center flexDirection="column" gap="4" fontSize="lg" className="subpixel-antialiased">
|
||||
<EmptyState text="Sorry, the page you are looking for does not exist." icon={FiAlertTriangle} />
|
||||
<EmptyState text="Sorry, the page you are looking for does not exist." icon={AlertTriangle} />
|
||||
<Box display="flex" flexDirection="column" alignItems="center" gap="2" mt="6">
|
||||
<Text fontSize="sm">If you were trying to contribute data but ended up here, please file a bug.</Text>
|
||||
<Button
|
||||
width="fit-content"
|
||||
leftIcon={<FiAlertTriangle className="text-blue-500" aria-hidden="true" />}
|
||||
leftIcon={<AlertTriangle size={"1em"} className="text-blue-500" aria-hidden="true" />}
|
||||
variant="solid"
|
||||
size="xs"
|
||||
>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Box, Button, Center, Link, Text } from "@chakra-ui/react";
|
||||
import { AlertTriangle } from "lucide-react";
|
||||
import Head from "next/head";
|
||||
import { FiAlertTriangle } from "react-icons/fi";
|
||||
import { EmptyState } from "src/components/EmptyState";
|
||||
import { getTransparentHeaderLayout } from "src/components/Layout";
|
||||
export { getDefaultStaticProps as getStaticProps } from "src/lib/default_static_props";
|
||||
@@ -13,15 +13,12 @@ function ServerError() {
|
||||
<meta name="404" content="Sorry, this page doesn't exist." />
|
||||
</Head>
|
||||
<Center flexDirection="column" gap="4" fontSize="lg" className="subpixel-antialiased">
|
||||
<EmptyState
|
||||
text="Sorry, we encountered a server error. We're not sure what went wrong."
|
||||
icon={FiAlertTriangle}
|
||||
/>
|
||||
<EmptyState text="Sorry, we encountered a server error. We're not sure what went wrong." icon={AlertTriangle} />
|
||||
<Box display="flex" flexDirection="column" alignItems="center" gap="2" mt="6">
|
||||
<Text fontSize="sm">If you were trying to contribute data but ended up here, please file a bug.</Text>
|
||||
<Button
|
||||
width="fit-content"
|
||||
leftIcon={<FiAlertTriangle className="text-blue-500" aria-hidden="true" />}
|
||||
leftIcon={<AlertTriangle size="1em" className="text-blue-500" aria-hidden="true" />}
|
||||
variant="solid"
|
||||
size="xs"
|
||||
>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Button, Divider, Flex, Grid, Icon, Text } from "@chakra-ui/react";
|
||||
import { Divider, Flex, Grid, Icon, Text } from "@chakra-ui/react";
|
||||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
import { useSession } from "next-auth/react";
|
||||
import React from "react";
|
||||
export { getDefaultStaticProps as getStaticProps } from "src/lib/default_static_props";
|
||||
import { MdOutlineEdit } from "react-icons/md";
|
||||
import { Pencil } from "lucide-react";
|
||||
import { SurveyCard } from "src/components/Survey/SurveyCard";
|
||||
|
||||
export default function Account() {
|
||||
@@ -34,7 +34,7 @@ export default function Account() {
|
||||
<Flex gap={2}>
|
||||
{session.user.name ?? "(No username)"}
|
||||
<Link href="/account/edit">
|
||||
<Icon boxSize={5} as={MdOutlineEdit} />
|
||||
<Icon boxSize={5} as={Pencil} size="1em" />
|
||||
</Link>
|
||||
</Flex>
|
||||
<Text as="b">Email</Text>
|
||||
|
||||
@@ -4,12 +4,12 @@ import {
|
||||
CardBody,
|
||||
CircularProgress,
|
||||
SimpleGrid,
|
||||
Text,
|
||||
Table,
|
||||
TableCaption,
|
||||
TableContainer,
|
||||
Tbody,
|
||||
Td,
|
||||
Text,
|
||||
Th,
|
||||
Thead,
|
||||
Tr,
|
||||
@@ -19,9 +19,10 @@ import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { useEffect } from "react";
|
||||
import useSWRImmutable from "swr/immutable";
|
||||
import { getAdminLayout } from "src/components/Layout";
|
||||
import { get } from "src/lib/api";
|
||||
import useSWRImmutable from "swr/immutable";
|
||||
export { getDefaultStaticProps as getStaticProps } from "src/lib/default_static_props";
|
||||
|
||||
/**
|
||||
* Provides the admin status page that shows result of calls to several backend API endpoints,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { withoutRole } from "src/lib/auth";
|
||||
import { oasstApiClient } from "src/lib/oasst_api_client";
|
||||
import { getBackendUserCore } from "src/lib/users";
|
||||
import { getBackendUserCore, getUserLanguage } from "src/lib/users";
|
||||
|
||||
const handler = withoutRole("banned", async (req, res, token) => {
|
||||
const user = await getBackendUserCore(token.sub);
|
||||
const availableTasks = await oasstApiClient.fetch_available_tasks(user);
|
||||
const userLanguage = getUserLanguage(req);
|
||||
const availableTasks = await oasstApiClient.fetch_available_tasks(user, userLanguage);
|
||||
res.status(200).json(availableTasks);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import { Button, ButtonProps, Input, Stack, useColorModeValue } from "@chakra-ui/react";
|
||||
import { useColorMode } from "@chakra-ui/react";
|
||||
import { Bug, Github, Mail } from "lucide-react";
|
||||
import { GetServerSideProps } from "next";
|
||||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { ClientSafeProvider, getProviders, signIn } from "next-auth/react";
|
||||
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { FaBug, FaDiscord, FaEnvelope, FaGithub } from "react-icons/fa";
|
||||
import { AuthLayout } from "src/components/AuthLayout";
|
||||
import { Footer } from "src/components/Footer";
|
||||
import { Header } from "src/components/Header";
|
||||
import { Discord } from "src/components/Icons/Discord";
|
||||
import { Role, RoleSelect } from "src/components/RoleSelect";
|
||||
|
||||
export type SignInErrorTypes =
|
||||
@@ -89,7 +90,7 @@ function Signin({ providers }: SigninProps) {
|
||||
placeholder="Email Address"
|
||||
{...register("email")}
|
||||
/>
|
||||
<SigninButton data-cy="signin-email-button" leftIcon={<FaEnvelope />}>
|
||||
<SigninButton data-cy="signin-email-button" leftIcon={<Mail />}>
|
||||
Continue with Email
|
||||
</SigninButton>
|
||||
</Stack>
|
||||
@@ -103,7 +104,7 @@ function Signin({ providers }: SigninProps) {
|
||||
bg: "#454FBF",
|
||||
}}
|
||||
size="lg"
|
||||
leftIcon={<FaDiscord />}
|
||||
leftIcon={<Discord />}
|
||||
color="white"
|
||||
onClick={() => signIn(discord.id, { callbackUrl: "/" })}
|
||||
// isDisabled="false"
|
||||
@@ -119,7 +120,7 @@ function Signin({ providers }: SigninProps) {
|
||||
bg: "#101010",
|
||||
}}
|
||||
size={"lg"}
|
||||
leftIcon={<FaGithub />}
|
||||
leftIcon={<Github />}
|
||||
colorScheme="blue"
|
||||
// isDisabled="false"
|
||||
>
|
||||
@@ -165,7 +166,7 @@ const SigninButton = (props: ButtonProps) => {
|
||||
return (
|
||||
<Button
|
||||
size={"lg"}
|
||||
leftIcon={<FaEnvelope />}
|
||||
leftIcon={<Mail />}
|
||||
type="submit"
|
||||
colorScheme={buttonColorScheme}
|
||||
color="white"
|
||||
@@ -203,7 +204,7 @@ const DebugSigninForm = ({ credentials, bgColorClass }: { credentials: ClientSaf
|
||||
<Stack>
|
||||
<Input variant="outline" size="lg" placeholder="Username" {...register("username")} />
|
||||
<RoleSelect {...register("role")}></RoleSelect>
|
||||
<SigninButton leftIcon={<FaBug />}>Continue with Debug User</SigninButton>
|
||||
<SigninButton leftIcon={<Bug />}>Continue with Debug User</SigninButton>
|
||||
</Stack>
|
||||
</form>
|
||||
);
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import Head from "next/head";
|
||||
import { useMemo } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { LeaderboardTable, TaskOption, WelcomeCard } from "src/components/Dashboard";
|
||||
import { getDashboardLayout } from "src/components/Layout";
|
||||
import { TaskCategory } from "src/components/Tasks/TaskTypes";
|
||||
import { get } from "src/lib/api";
|
||||
import { AvailableTasks, TaskType } from "src/types/Task";
|
||||
export { getDefaultStaticProps as getStaticProps } from "src/lib/default_static_props";
|
||||
import useSWRImmutable from "swr/immutable";
|
||||
import useSWR from "swr";
|
||||
|
||||
const Dashboard = () => {
|
||||
const { data } = useSWRImmutable<AvailableTasks>("/api/available_tasks", get);
|
||||
const {
|
||||
i18n: { language },
|
||||
} = useTranslation();
|
||||
const [activeLang, setLang] = useState<string>(null);
|
||||
const { data, mutate: fetchTasks } = useSWR<AvailableTasks>("/api/available_tasks", get, {
|
||||
refreshInterval: 2 * 60 * 1000, //2 minutes
|
||||
revalidateOnMount: false, // triggered in the hook below
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
// re-fetch tasks if the language has changed
|
||||
if (activeLang !== language) {
|
||||
setLang(language);
|
||||
fetchTasks();
|
||||
}
|
||||
}, [activeLang, setLang, language, fetchTasks]);
|
||||
|
||||
const availableTaskTypes = useMemo(() => {
|
||||
const taskTypes = filterAvailableTasks(data ?? {});
|
||||
|
||||
@@ -4,11 +4,13 @@ export const colors = {
|
||||
btn: "gray.50",
|
||||
div: "white",
|
||||
text: "black",
|
||||
highlight: "blue.400",
|
||||
},
|
||||
dark: {
|
||||
bg: "gray.900",
|
||||
btn: "gray.600",
|
||||
div: "gray.700",
|
||||
text: "gray.200",
|
||||
highlight: "blue.500",
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user