Skip to content

Commit

Permalink
changes to the admin area
Browse files Browse the repository at this point in the history
  • Loading branch information
julianjelfs committed Jan 23, 2024
1 parent 05be9b1 commit d1df683
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 120 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
<script lang="ts">
import { _ } from "svelte-i18n";
import type { OpenChat, TranslationCorrection, TranslationCorrections } from "openchat-client";
import MenuIcon from "../../MenuIcon.svelte";
import Hamburger from "svelte-material-icons/Menu.svelte";
import Check from "svelte-material-icons/Check.svelte";
import EyeOutline from "svelte-material-icons/EyeOutline.svelte";
import Send from "svelte-material-icons/Send.svelte";
import Translate from "svelte-material-icons/Translate.svelte";
import Close from "svelte-material-icons/Close.svelte";
import HoverIcon from "../../HoverIcon.svelte";
import Menu from "../../Menu.svelte";
import MenuItem from "../../MenuItem.svelte";
import type {
OpenChat,
TranslationCorrection,
TranslationCorrections,
TranslationRejectionReason,
} from "openchat-client";
import { getContext, onMount } from "svelte";
import Button from "../../Button.svelte";
import ButtonGroup from "../../ButtonGroup.svelte";
import { iconSize } from "../../../stores/iconSize";
const client = getContext<OpenChat>("client");
Expand All @@ -21,23 +35,48 @@
});
function flattenCorrections(corrections: TranslationCorrections): TranslationCorrection[] {
// return [
// {
// locale: "fr",
// key: "group.welcome",
// value: "Ta mère était fossoyeuse {groupName}",
// proposedBy: "cpmcr-yeaaa-aaaaa-qaala-cai",
// proposedAt: Date.now(),
// status: "pending",
// },
// ];
return Object.values(corrections)
.flatMap((val) => Object.values(val))
.filter((c) => !c.approved);
.filter((c) => c.status !== "deployed");
}
function approveCorrection(correction: TranslationCorrection) {
// correction.status = "approved";
// corrections = corrections;
client
.approveTranslationCorrection(correction)
.then((res) => (corrections = flattenCorrections(res)));
}
function rejectCorrection(correction: TranslationCorrection) {
function markDeployed(correction: TranslationCorrection) {
console.log("Let's deploy: ", correction);
}
function rejectCorrection(
correction: TranslationCorrection,
reason: TranslationRejectionReason,
) {
client
.rejectTranslationCorrection(correction)
.rejectTranslationCorrection(correction, reason)
.then((res) => (corrections = flattenCorrections(res)));
}
function previewCorrection(correction: TranslationCorrection) {
// This will pretend that the value is english and apply it to the english i18n dictionary temporarily.
// This is just so that we have the option to look at it in the UI to check for layout problems
client.previewTranslationCorrection({ ...correction, locale: "en" });
}
function verifyCorrection(correction: TranslationCorrection) {
verifying = { ...correction };
verifying.value = "Translating to English ...";
Expand Down Expand Up @@ -77,50 +116,107 @@
<table class="data">
<thead>
<tr>
<th>Locale</th>
<th>Key</th>
<th>English value</th>
<th>Current value</th>
<th>Proposed value</th>
<th>Proposed by</th>
<th>Proposed at</th>
<th class="locale">Locale</th>
<th class="key">Key</th>
<th class="english">English value</th>
<th class="current">Current value</th>
<th class="proposed">Suggested value</th>
<th class="proposed_by">Proposed by</th>
<th class="proposed_at">Proposed at</th>
<th class="action"></th>
</tr>
</thead>
<tbody>
{#each corrections as correction}
<tr>
<td>{correction.locale}</td>
<td>{correction.key}</td>
<td>{$_(correction.key, { locale: "en" })}</td>
<td>{$_(correction.key, { locale: correction.locale })}</td>
<td>
<div class="suggestion">
{#if verifying !== undefined && verifying.locale === correction.locale && verifying.key === correction.key}
{verifying.value}
{:else}
{correction.value}
{/if}
</div>
<div class="review">
{#if verifying !== undefined && verifying.locale === correction.locale && verifying.key === correction.key}
<ButtonGroup align="fill">
<Button secondary on:click={() => (verifying = undefined)} tiny
>Show Proposed
</Button>
<Button tiny on:click={() => rejectCorrection(correction)}
>Reject</Button>
<Button tiny on:click={() => approveCorrection(correction)}
>Approve</Button>
</ButtonGroup>
{:else}
<Button on:click={() => verifyCorrection(correction)} tiny
>Show English
</Button>
{/if}
</div>
<tr class={correction.status}>
<td class="locale">{correction.locale}</td>
<td class="key">{correction.key}</td>
<td class="english">{$_(correction.key, { locale: "en" })}</td>
<td class="current">{$_(correction.key, { locale: correction.locale })}</td>
<td class="proposed">
{#if verifying !== undefined && verifying.locale === correction.locale && verifying.key === correction.key}
{verifying.value}
{:else}
{correction.value}
{/if}
</td>
<td class="proposed_by"
>{$userStore[correction.proposedBy]?.username ?? correction.proposedBy}</td>
<td class="proposed_at"
>{client.toDatetimeString(new Date(correction.proposedAt))}</td>
<td class="action">
<MenuIcon position="bottom" align="end">
<span slot="icon">
<HoverIcon>
<Hamburger size={$iconSize} color={"var(--txt)"} />
</HoverIcon>
</span>
<span slot="menu">
<Menu>
{#if correction.status === "pending"}
<MenuItem on:click={() => previewCorrection(correction)}>
<EyeOutline
size={$iconSize}
color={"var(--icon-inverted-txt)"}
slot="icon" />
<span slot="text">Preview</span>
</MenuItem>
{#if verifying !== undefined && verifying.locale === correction.locale && verifying.key === correction.key}
<MenuItem on:click={() => (verifying = undefined)}>
<Translate
size={$iconSize}
color={"var(--icon-inverted-txt)"}
slot="icon" />
<span slot="text">Show proposed</span>
</MenuItem>
{:else}
<MenuItem on:click={() => verifyCorrection(correction)}>
<Translate
size={$iconSize}
color={"var(--icon-inverted-txt)"}
slot="icon" />
<span slot="text">Show suggestion in English</span>
</MenuItem>
{/if}
<MenuItem on:click={() => approveCorrection(correction)}>
<Check
size={$iconSize}
color={"var(--icon-inverted-txt)"}
slot="icon" />
<span slot="text">Approve</span>
</MenuItem>
<MenuItem
on:click={() =>
rejectCorrection(correction, "bad_translation")}>
<Close
size={$iconSize}
color={"var(--icon-inverted-txt)"}
slot="icon" />
<span slot="text">Reject - bad translation</span>
</MenuItem>
<MenuItem
on:click={() =>
rejectCorrection(correction, "layout_problem")}>
<Close
size={$iconSize}
color={"var(--icon-inverted-txt)"}
slot="icon" />
<span slot="text">Reject - layout problem</span>
</MenuItem>
{/if}
{#if correction.status === "approved"}
<MenuItem on:click={() => markDeployed(correction)}>
<Send
size={$iconSize}
color={"var(--icon-inverted-txt)"}
slot="icon" />
<span slot="text">Deploy</span>
</MenuItem>
{/if}
</Menu>
</span>
</MenuIcon>
</td>
<td>{$userStore[correction.proposedBy]?.username ?? correction.proposedBy}</td>
<td>{client.toDatetimeString(new Date(correction.proposedAt))}</td>
</tr>
{/each}
</tbody>
Expand Down Expand Up @@ -150,6 +246,13 @@
tr {
border-bottom: 1px solid var(--bd);
&.pending {
background-color: #e91e63;
}
&.approved {
background-color: #66bb6a;
}
}
td,
Expand All @@ -164,19 +267,22 @@
td {
padding: $sp3;
text-align: left;
vertical-align: middle;
}
th {
background-color: var(--button-bg);
color: var(--button-txt);
}
tr {
cursor: pointer;
}
&.locale,
&.action {
width: 40px;
}
tr:hover {
background-color: rgba(255, 255, 255, 0.1);
&.proposed_by,
&.proposed_at {
width: 150px;
}
}
.suggestion {
Expand Down
28 changes: 21 additions & 7 deletions frontend/openchat-agent/src/services/openchatAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ import {
import { AnonUserClient } from "./user/anonUser.client";
import { excludeLatestKnownUpdateIfBeforeFix } from "./common/replicaUpToDateChecker";
import { ICPCoinsClient } from "./icpcoins/icpcoins.client";
import type { TranslationRejectionReason } from "openchat-shared";

export class OpenChatAgent extends EventTarget {
private _userIndexClient: UserIndexClient;
Expand Down Expand Up @@ -409,7 +410,9 @@ export class OpenChatAgent extends EventTarget {
) {
return this.userClient.sendMessageWithTransferToChannel(
chatId,
event.event.content.kind !== "p2p_swap_content_initial" ? event.event.content.transfer.recipient : undefined,
event.event.content.kind !== "p2p_swap_content_initial"
? event.event.content.transfer.recipient
: undefined,
user,
event,
threadRootMessageIndex,
Expand Down Expand Up @@ -438,7 +441,9 @@ export class OpenChatAgent extends EventTarget {
) {
return this.userClient.sendMessageWithTransferToGroup(
chatId,
event.event.content.kind !== "p2p_swap_content_initial" ? event.event.content.transfer.recipient : undefined,
event.event.content.kind !== "p2p_swap_content_initial"
? event.event.content.transfer.recipient
: undefined,
user,
event,
threadRootMessageIndex,
Expand Down Expand Up @@ -3091,8 +3096,9 @@ export class OpenChatAgent extends EventTarget {

rejectTranslationCorrection(
correction: TranslationCorrection,
reason: TranslationRejectionReason,
): Promise<TranslationCorrections> {
console.log("Rejecting translation correction: ", correction);
console.log("Rejecting translation correction: ", correction, reason);
// TODO - for now I'm just going to record these corrections in indexed db
// eventually we will want an api, but let's get the shape right first
return this.getTranslationCorrections();
Expand All @@ -3113,7 +3119,11 @@ export class OpenChatAgent extends EventTarget {
return this._userIndexClient.reportedMessages(userId);
}

acceptP2PSwap(chatId: ChatIdentifier, threadRootMessageIndex: number | undefined, messageId: bigint): Promise<AcceptP2PSwapResponse> {
acceptP2PSwap(
chatId: ChatIdentifier,
threadRootMessageIndex: number | undefined,
messageId: bigint,
): Promise<AcceptP2PSwapResponse> {
if (chatId.kind === "channel") {
return this.communityClient(chatId.communityId).acceptP2PSwap(
chatId.channelId,
Expand All @@ -3128,9 +3138,13 @@ export class OpenChatAgent extends EventTarget {
} else {
return this.userClient.acceptP2PSwap(chatId.userId, messageId);
}
}
}

cancelP2PSwap(chatId: ChatIdentifier, threadRootMessageIndex: number | undefined, messageId: bigint): Promise<CancelP2PSwapResponse> {
cancelP2PSwap(
chatId: ChatIdentifier,
threadRootMessageIndex: number | undefined,
messageId: bigint,
): Promise<CancelP2PSwapResponse> {
if (chatId.kind === "channel") {
return this.communityClient(chatId.communityId).cancelP2PSwap(
chatId.channelId,
Expand All @@ -3145,5 +3159,5 @@ export class OpenChatAgent extends EventTarget {
} else {
return this.userClient.cancelP2PSwap(chatId.userId, messageId);
}
}
}
}
Loading

0 comments on commit d1df683

Please sign in to comment.