move translations to CoreVM, move models to CoreVM for sentralization

This commit is contained in:
marlon-erler
2026-04-09 16:48:22 +00:00
parent 6204669ba3
commit 78672afc40
42 changed files with 1786 additions and 1322 deletions
+13 -4
View File
@@ -11,9 +11,12 @@ import { TaskCategoryBulkChangeViewModel } from "../../ViewModel/Utility/taskPro
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
import { TaskViewModelToEntry } from "../Components/taskEntry";
import { allowDrop } from "../utility";
import { translations } from "../translations";
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
export function BoardKanbanPage(boardViewModel: BoardViewModel) {
export function BoardKanbanPage(
coreViewModel: CoreViewModel,
boardViewModel: BoardViewModel,
) {
return PropertyValueList(
"category",
(taskViewModel: TaskViewModel) => taskViewModel.task,
@@ -30,7 +33,12 @@ export function BoardKanbanPage(boardViewModel: BoardViewModel) {
sortedCategories,
categoryName,
);
return Column(categoryName, index, boardViewModel);
return Column(
coreViewModel,
categoryName,
index,
boardViewModel,
);
};
return (
@@ -44,6 +52,7 @@ export function BoardKanbanPage(boardViewModel: BoardViewModel) {
}
function Column(
coreViewModel: CoreViewModel,
categoryName: string,
index: React.State<number>,
boardViewModel: BoardViewModel,
@@ -72,7 +81,7 @@ function Column(
<div class="flex-row width-input">
<input
placeholder={
translations.chatPage.task
coreViewModel.translations.chatPage.task
.renameCategoryInputPlaceholder
}
bind:value={viewModel.inputValue}
+23 -14
View File
@@ -11,10 +11,13 @@ import { BoardViewToggleButton } from "../Components/boardViewToggleButton";
import { SearchModal } from "../Modals/searchModal";
import { TaskSettingsModal } from "../Modals/taskSettingsModal";
import { TaskViewModelToEntry } from "../Components/taskEntry";
import { translations } from "../translations";
import { setFocusWithDelay } from "../utility";
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
export function BoardPage(boardViewModel: BoardViewModel) {
export function BoardPage(
coreViewModel: CoreViewModel,
boardViewModel: BoardViewModel,
) {
boardViewModel.loadData();
// main content
@@ -23,10 +26,10 @@ export function BoardPage(boardViewModel: BoardViewModel) {
() => {
switch (boardViewModel.selectedPage.value) {
case BoardPageTypes.Kanban: {
return BoardKanbanPage(boardViewModel);
return BoardKanbanPage(coreViewModel, boardViewModel);
}
case BoardPageTypes.StatusGrid: {
return BoardStatusGridPage(boardViewModel);
return BoardStatusGridPage(coreViewModel, boardViewModel);
}
default: {
return (
@@ -53,6 +56,7 @@ export function BoardPage(boardViewModel: BoardViewModel) {
setFocusWithDelay();
return TaskSettingsModal(
coreViewModel,
boardViewModel.selectedTaskViewModel.value,
);
}
@@ -66,7 +70,7 @@ export function BoardPage(boardViewModel: BoardViewModel) {
<button
class="ghost board-close-button"
aria-label={
translations.chatPage.task
coreViewModel.translations.chatPage.task
.closeBoardButtonAudioLabel
}
on:click={boardViewModel.close}
@@ -76,7 +80,7 @@ export function BoardPage(boardViewModel: BoardViewModel) {
<button
class="ghost board-toggle-button inset-outline"
aria-label={
translations.chatPage.task
coreViewModel.translations.chatPage.task
.toggleBoardButtonAudioLabel
}
on:click={
@@ -91,7 +95,8 @@ export function BoardPage(boardViewModel: BoardViewModel) {
<button
class="ghost"
aria-label={
translations.chatPage.task.boardSettingsHeadline
coreViewModel.translations.chatPage.task
.boardSettingsHeadline
}
on:click={boardViewModel.showSettings}
>
@@ -100,19 +105,22 @@ export function BoardPage(boardViewModel: BoardViewModel) {
</span>
<span class="scroll-h ribbon">
{BoardViewToggleButton(
translations.chatPage.task.listViewButtonAudioLabel,
coreViewModel.translations.chatPage.task
.listViewButtonAudioLabel,
"view_list",
BoardPageTypes.List,
boardViewModel,
)}
{BoardViewToggleButton(
translations.chatPage.task.kanbanViewButtonAudioLabel,
coreViewModel.translations.chatPage.task
.kanbanViewButtonAudioLabel,
"view_kanban",
BoardPageTypes.Kanban,
boardViewModel,
)}
{BoardViewToggleButton(
translations.chatPage.task.statusViewButtonAudioLabel,
coreViewModel.translations.chatPage.task
.statusViewButtonAudioLabel,
"grid_view",
BoardPageTypes.StatusGrid,
boardViewModel,
@@ -122,7 +130,7 @@ export function BoardPage(boardViewModel: BoardViewModel) {
<button
class="ghost"
aria-label={
translations.chatPage.task
coreViewModel.translations.chatPage.task
.filterTasksButtonAudioLabel
}
on:click={boardViewModel.showFilterModal}
@@ -132,7 +140,7 @@ export function BoardPage(boardViewModel: BoardViewModel) {
<button
class="ghost"
aria-label={
translations.chatPage.task
coreViewModel.translations.chatPage.task
.createTaskButtonAudioLabel
}
on:click={boardViewModel.createTask}
@@ -143,10 +151,11 @@ export function BoardPage(boardViewModel: BoardViewModel) {
</div>
<div class="content main-content" children:set={mainContent}></div>
{BoardSettingsModal(boardViewModel)}
{BoardSettingsModal(coreViewModel, boardViewModel)}
{SearchModal(
coreViewModel,
boardViewModel.searchViewModel,
translations.chatPage.task.filterTasksHeadline,
coreViewModel.translations.chatPage.task.filterTasksHeadline,
TaskViewModelToEntry,
boardViewModel.isPresentingFilterModal,
)}
+12 -5
View File
@@ -16,9 +16,12 @@ import { FilteredList } from "../Components/filteredList";
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
import { TaskViewModelToEntry } from "../Components/taskEntry";
import { allowDrop } from "../utility";
import { translations } from "../translations";
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
export function BoardStatusGridPage(boardViewModel: BoardViewModel) {
export function BoardStatusGridPage(
coreViewModel: CoreViewModel,
boardViewModel: BoardViewModel,
) {
const statuses: React.ListState<string> = new React.ListState();
const sortedStatuses: React.State<string[]> =
createSortedPropertyValueState(statuses);
@@ -36,7 +39,7 @@ export function BoardStatusGridPage(boardViewModel: BoardViewModel) {
statusName: string,
) => {
const index = createPropertyValueIndexState(sortedStatuses, statusName);
return StatusNameCell(statusName, index, boardViewModel);
return StatusNameCell(coreViewModel, statusName, index, boardViewModel);
};
return (
@@ -63,6 +66,7 @@ export function BoardStatusGridPage(boardViewModel: BoardViewModel) {
);
return CategoryRow(
coreViewModel,
categoryName,
index,
statuses,
@@ -84,6 +88,7 @@ export function BoardStatusGridPage(boardViewModel: BoardViewModel) {
}
function StatusNameCell(
coreViewModel: CoreViewModel,
statusName: string,
index: React.State<number>,
boardViewModel: BoardViewModel,
@@ -118,7 +123,8 @@ function StatusNameCell(
<div class="property-input-wrapper">
<input
placeholder={
translations.chatPage.task.renameStatusInputPlaceholder
coreViewModel.translations.chatPage.task
.renameStatusInputPlaceholder
}
bind:value={viewModel.inputValue}
on:enter={viewModel.set}
@@ -142,6 +148,7 @@ function StatusNameCell(
}
function CategoryRow(
coreViewModel: CoreViewModel,
categoryName: string,
index: React.State<number>,
allStatuses: React.ListState<string>,
@@ -180,7 +187,7 @@ function CategoryRow(
<div class="property-input-wrapper">
<input
placeholder={
translations.chatPage.task
coreViewModel.translations.chatPage.task
.renameCategoryInputPlaceholder
}
bind:value={viewModel.inputValue}
+21 -16
View File
@@ -7,10 +7,13 @@ import CalendarPageViewModel from "../../ViewModel/Pages/calendarPageViewModel";
import { MonthGrid } from "../Components/monthGrid";
import { TaskSettingsModal } from "../Modals/taskSettingsModal";
import { TaskViewModelToEntry } from "../Components/taskEntry";
import { translations } from "../translations";
import { setFocusWithDelay } from "../utility";
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
export function CalendarPage(calendarPageViewModel: CalendarPageViewModel) {
export function CalendarPage(
coreViewModel: CoreViewModel,
calendarPageViewModel: CalendarPageViewModel,
) {
calendarPageViewModel.loadData();
const mainContent = React.createProxyState(
@@ -30,6 +33,7 @@ export function CalendarPage(calendarPageViewModel: CalendarPageViewModel) {
}
return MonthGrid(
coreViewModel,
monthGrid,
calendarPageViewModel.selectedDate,
drop,
@@ -58,8 +62,8 @@ export function CalendarPage(calendarPageViewModel: CalendarPageViewModel) {
<div class="width-100 height-100 flex-column justify-center align-center">
<span class="secondary slide-up">
{
translations.chatPage.calendar
.noEvents
coreViewModel.translations.chatPage
.calendar.noEvents
}
</span>
</div>
@@ -99,6 +103,7 @@ export function CalendarPage(calendarPageViewModel: CalendarPageViewModel) {
setFocusWithDelay();
return TaskSettingsModal(
coreViewModel,
calendarPageViewModel.selectedTaskViewModel.value,
);
}
@@ -114,7 +119,7 @@ export function CalendarPage(calendarPageViewModel: CalendarPageViewModel) {
<button
class="ghost"
aria-label={
translations.chatPage.calendar
coreViewModel.translations.chatPage.calendar
.todayButtonAudioLabel
}
on:click={calendarPageViewModel.showToday}
@@ -126,7 +131,7 @@ export function CalendarPage(calendarPageViewModel: CalendarPageViewModel) {
<button
class="ghost"
aria-label={
translations.chatPage.calendar
coreViewModel.translations.chatPage.calendar
.previousMonthButtonAudioLabel
}
on:click={
@@ -140,12 +145,12 @@ export function CalendarPage(calendarPageViewModel: CalendarPageViewModel) {
class="year-input"
type="number"
aria-label={
translations.chatPage.calendar
.yearInputAudioLabel
coreViewModel.translations.chatPage
.calendar.yearInputAudioLabel
}
placeholder={
translations.chatPage.calendar
.yearInputPlaceholder
coreViewModel.translations.chatPage
.calendar.yearInputPlaceholder
}
bind:value={
calendarPageViewModel.selectedYear
@@ -155,12 +160,12 @@ export function CalendarPage(calendarPageViewModel: CalendarPageViewModel) {
class="month-input"
type="number"
aria-label={
translations.chatPage.calendar
.monthInputAudioLabel
coreViewModel.translations.chatPage
.calendar.monthInputAudioLabel
}
placeholder={
translations.chatPage.calendar
.monthInputPlaceholder
coreViewModel.translations.chatPage
.calendar.monthInputPlaceholder
}
bind:value={
calendarPageViewModel.selectedMonth
@@ -170,7 +175,7 @@ export function CalendarPage(calendarPageViewModel: CalendarPageViewModel) {
<button
class="ghost"
aria-label={
translations.chatPage.calendar
coreViewModel.translations.chatPage.calendar
.nextMonthButtonAudioLabel
}
on:click={calendarPageViewModel.showNextMonth}
@@ -182,7 +187,7 @@ export function CalendarPage(calendarPageViewModel: CalendarPageViewModel) {
<button
class="ghost"
aria-label={
translations.chatPage.task
coreViewModel.translations.chatPage.task
.createTaskButtonAudioLabel
}
on:click={calendarPageViewModel.createEvent}
+20 -6
View File
@@ -2,12 +2,21 @@ import "./messagePage.css";
import * as React from "bloatless-react";
import { ChatMessageViewModelToView } from "../Components/chatMessage";
import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
import { translations } from "../translations";
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
import { ChatMessage } from "../Components/chatMessage";
export function MessagePage(messagePageViewModel: MessagePageViewModel) {
export function MessagePage(
coreViewModel: CoreViewModel,
messagePageViewModel: MessagePageViewModel,
) {
messagePageViewModel.loadData();
const ChatMessageViewModelToView: React.StateItemConverter<
ChatMessageViewModel
> = (chatMessageViewModel: ChatMessageViewModel) => {
return ChatMessage(coreViewModel, chatMessageViewModel);
};
const messageContainer = (
<div
@@ -45,7 +54,10 @@ export function MessagePage(messagePageViewModel: MessagePageViewModel) {
<div class="pane">
<div class="toolbar">
<span class="title">
{translations.chatPage.message.messagesHeadline}
{
coreViewModel.translations.chatPage.message
.messagesHeadline
}
</span>
</div>
<div class="content">
@@ -61,14 +73,16 @@ export function MessagePage(messagePageViewModel: MessagePageViewModel) {
messagePageViewModel.sendMessage
}
placeholder={
translations.chatPage.message
coreViewModel.translations.chatPage
.message
.composerInputPlaceholder
}
></input>
<button
class="primary"
aria-label={
translations.chatPage.message
coreViewModel.translations.chatPage
.message
.sendMessageButtonAudioLabel
}
on:click={
+35 -19
View File
@@ -5,17 +5,25 @@ import { ColorPicker } from "../Components/colorPicker";
import { DangerousActionButton } from "../Components/dangerousActionButton";
import { DeletableListItem } from "../Components/deletableListItem";
import SettingsPageViewModel from "../../ViewModel/Pages/settingsPageViewModel";
import { translations } from "../translations";
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
export function SettingsPage(
coreViewModel: CoreViewModel,
settingsPageViewModel: SettingsPageViewModel,
) {
settingsPageViewModel.loadData();
const secondaryChannelConverter: React.StateItemConverter<string> = (
secondaryChannel: string,
) => {
return DeletableListItem(secondaryChannel, <span></span>, () => {
settingsPageViewModel.removeSecondaryChannel(secondaryChannel);
});
return DeletableListItem(
coreViewModel,
secondaryChannel,
<span></span>,
() => {
settingsPageViewModel.removeSecondaryChannel(secondaryChannel);
},
);
};
return (
@@ -24,7 +32,10 @@ export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
<div class="pane">
<div class="toolbar">
<span class="title">
{translations.chatPage.settings.settingsHeadline}
{
coreViewModel.translations.chatPage.settings
.settingsHeadline
}
</span>
</div>
<div class="content">
@@ -33,8 +44,8 @@ export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
<div>
<span>
{
translations.chatPage.settings
.primaryChannelLabel
coreViewModel.translations.chatPage
.settings.primaryChannelLabel
}
</span>
<input
@@ -51,7 +62,7 @@ export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
<button
class="width-50"
aria-label={
translations.chatPage.settings
coreViewModel.translations.chatPage.settings
.setPrimaryChannelButtonAudioLabel
}
on:click={
@@ -61,7 +72,7 @@ export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
settingsPageViewModel.cannotSetPrimaryChannel
}
>
{translations.general.setButton}
{coreViewModel.translations.general.setButton}
<span class="icon">check</span>
</button>
</div>
@@ -71,11 +82,11 @@ export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
<div class="flex-row width-input margin-bottom">
<input
aria-label={
translations.chatPage.settings
coreViewModel.translations.chatPage.settings
.newSecondaryChannelAudioLabel
}
placeholder={
translations.chatPage.settings
coreViewModel.translations.chatPage.settings
.newSecondaryChannelPlaceholder
}
bind:value={
@@ -88,7 +99,7 @@ export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
<button
class="primary"
aria-label={
translations.chatPage.settings
coreViewModel.translations.chatPage.settings
.addSecondaryChannelButtonAudioLabel
}
on:click={
@@ -117,8 +128,8 @@ export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
<div>
<span>
{
translations.chatPage.settings
.encryptionKeyLabel
coreViewModel.translations.chatPage
.settings.encryptionKeyLabel
}
</span>
<input
@@ -138,7 +149,7 @@ export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
<button
class="width-50"
aria-label={
translations.chatPage.settings
coreViewModel.translations.chatPage.settings
.setEncryptionKeyButtonAudioLabel
}
on:click={
@@ -148,7 +159,7 @@ export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
settingsPageViewModel.cannotSetEncryptionKey
}
>
{translations.general.setButton}
{coreViewModel.translations.general.setButton}
<span class="icon">check</span>
</button>
</div>
@@ -160,7 +171,10 @@ export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
settingsPageViewModel.shouldShowEncryptionKey
}
></input>
{translations.chatPage.settings.showEncryptionKey}
{
coreViewModel.translations.chatPage.settings
.showEncryptionKey
}
</label>
<hr></hr>
@@ -171,7 +185,9 @@ export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
<div class="width-input">
{DangerousActionButton(
translations.chatPage.settings.deleteChatButton,
coreViewModel,
coreViewModel.translations.chatPage.settings
.deleteChatButton,
"chat_error",
settingsPageViewModel.remove,
)}
+16 -7
View File
@@ -5,9 +5,12 @@ import * as React from "bloatless-react";
import { BoardPage } from "./boardPage";
import { BoardViewModelToEntry } from "../Components/boardEntry";
import TaskPageViewModel from "../../ViewModel/Pages/taskPageViewModel";
import { translations } from "../translations";
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
export function TaskPage(taskPageViewModel: TaskPageViewModel) {
export function TaskPage(
coreViewModel: CoreViewModel,
taskPageViewModel: TaskPageViewModel,
) {
taskPageViewModel.loadData();
const isShowingBoard = React.createProxyState(
@@ -23,7 +26,10 @@ export function TaskPage(taskPageViewModel: TaskPageViewModel) {
return (
<div class="pane align-center justify-center">
<span class="secondary">
{translations.chatPage.task.noBoardSelected}
{
coreViewModel.translations.chatPage.task
.noBoardSelected
}
</span>
</div>
);
@@ -34,13 +40,16 @@ export function TaskPage(taskPageViewModel: TaskPageViewModel) {
return (
<div class="pane align-center justify-center">
<span class="secondary">
{translations.chatPage.task.boardNotFound}
{
coreViewModel.translations.chatPage.task
.boardNotFound
}
</span>
</div>
);
}
return BoardPage(selectedBoard);
return BoardPage(coreViewModel, selectedBoard);
},
);
@@ -63,14 +72,14 @@ export function TaskPage(taskPageViewModel: TaskPageViewModel) {
bind:value={taskPageViewModel.newBoardNameInput}
on:enter={taskPageViewModel.createBoard}
placeholder={
translations.chatPage.task
coreViewModel.translations.chatPage.task
.newBoardNamePlaceholder
}
></input>
<button
class="primary"
aria-label={
translations.chatPage.task
coreViewModel.translations.chatPage.task
.createBoardButtonAudioLabel
}
on:click={taskPageViewModel.createBoard}