improve consistency

This commit is contained in:
marlon-erler
2026-09-23 00:29:48 +02:00
parent 2b446ac203
commit 9607a9f80c
8 changed files with 345 additions and 322 deletions
+7 -2
View File
@@ -202,7 +202,7 @@ body {
--color-1: hsl(150, 60%, 30%); --color-1: hsl(150, 60%, 30%);
--color-2: hsl(150, 60%, 25%); --color-2: hsl(150, 60%, 25%);
filter: var(--backdrop-grass-filter); filter: var(--backdrop-grass-filter);
opacity: .7; opacity: 0.7;
background-image: background-image:
linear-gradient( linear-gradient(
350deg, 350deg,
@@ -214,7 +214,7 @@ body {
--color-1: hsl(110, 60%, 40%); --color-1: hsl(110, 60%, 40%);
--color-2: hsl(110, 60%, 35%); --color-2: hsl(110, 60%, 35%);
filter: var(--backdrop-grass-filter); filter: var(--backdrop-grass-filter);
opacity: .7; opacity: 0.7;
background-image: background-image:
linear-gradient( linear-gradient(
9deg, 9deg,
@@ -396,6 +396,11 @@ body[showing-chat] #chat-page-wrapper {
gap: var(--gap-between-tiles); gap: var(--gap-between-tiles);
padding: var(--gap-between-tiles); padding: var(--gap-between-tiles);
} }
@media (pointer: coarse) and (max-width: 480px) {
#chat-page > div > #ribbon #close-button {
order: 1;
}
}
#chat-page > div > #main > div > .pane-wrapper > .pane > .toolbar { #chat-page > div > #main > div > .pane-wrapper > .pane > .toolbar {
justify-content: start; justify-content: start;
justify-content: space-between; justify-content: space-between;
+245 -218
View File
@@ -314,6 +314,8 @@
confirmButton: "Confirm", confirmButton: "Confirm",
saveButton: "Save", saveButton: "Save",
setButton: "Set", setButton: "Set",
filterOrCreateLabel: "Search or create",
createLabel: (query) => `Create "${query}"`,
reloadAppButton: "Reload App", reloadAppButton: "Reload App",
fileVersionLabel: "Version", fileVersionLabel: "Version",
searchLabel: "Search", searchLabel: "Search",
@@ -481,9 +483,6 @@
questionReaction: "Reaction: question mark" questionReaction: "Reaction: question mark"
}, },
task: { task: {
newBoardNamePlaceholder: "Create a board",
createBoardButtonAudioLabel: "create board",
///
noBoardSelected: "No board selected", noBoardSelected: "No board selected",
boardNotFound: "Board not found", boardNotFound: "Board not found",
/// ///
@@ -556,6 +555,8 @@
confirmButton: "Best\xE4tigen", confirmButton: "Best\xE4tigen",
saveButton: "Speichern", saveButton: "Speichern",
setButton: "OK", setButton: "OK",
filterOrCreateLabel: "Suchen oder erstellen",
createLabel: (query) => `"${query}" erstellen`,
reloadAppButton: "Neu laden", reloadAppButton: "Neu laden",
fileVersionLabel: "Version", fileVersionLabel: "Version",
searchLabel: "Suche", searchLabel: "Suche",
@@ -713,8 +714,6 @@
questionReaction: "Reaktion: Fragezeichen" questionReaction: "Reaktion: Fragezeichen"
}, },
task: { task: {
newBoardNamePlaceholder: "Board erstellen",
createBoardButtonAudioLabel: "board erstellen",
noBoardSelected: "Kein Board ausgew\xE4hlt", noBoardSelected: "Kein Board ausgew\xE4hlt",
boardNotFound: "Board nicht gefunden", boardNotFound: "Board nicht gefunden",
closeBoardButtonAudioLabel: "board schlie\xDFen", closeBoardButtonAudioLabel: "board schlie\xDFen",
@@ -778,6 +777,8 @@
confirmButton: "Confirmar", confirmButton: "Confirmar",
saveButton: "Guardar", saveButton: "Guardar",
setButton: "OK", setButton: "OK",
filterOrCreateLabel: "Buscar o crear",
createLabel: (query) => `Crear "${query}"`,
reloadAppButton: "Recargar app", reloadAppButton: "Recargar app",
fileVersionLabel: "Versi\xF3n", fileVersionLabel: "Versi\xF3n",
searchLabel: "Buscar", searchLabel: "Buscar",
@@ -935,8 +936,6 @@
questionReaction: "Reaccion: signo de interrogaci\xF3n" questionReaction: "Reaccion: signo de interrogaci\xF3n"
}, },
task: { task: {
newBoardNamePlaceholder: "Crear un tablero",
createBoardButtonAudioLabel: "crear tablero",
noBoardSelected: "Ning\xFAn tablero seleccionado", noBoardSelected: "Ning\xFAn tablero seleccionado",
boardNotFound: "Tablero no encontrado", boardNotFound: "Tablero no encontrado",
closeBoardButtonAudioLabel: "cerrar tablero", closeBoardButtonAudioLabel: "cerrar tablero",
@@ -1031,46 +1030,6 @@
function createTimestamp() { function createTimestamp() {
return (/* @__PURE__ */ new Date()).toISOString(); return (/* @__PURE__ */ new Date()).toISOString();
} }
function checkDoesObjectMatchReference(reference, stringEntryObject, explicitEmptyValue = false) {
reference_entry_loop: for (const referenceEntry of Object.entries(
reference
)) {
const [referenceKey, referenceValue] = referenceEntry;
const stringEntryObjectValue = stringEntryObject[referenceKey];
if (referenceValue == void 0) return false;
if (referenceValue[0] == "-") {
const strippedReferenceValue = referenceValue.toString().substring(1);
if (strippedReferenceValue == "" && stringEntryObjectValue != void 0 && stringEntryObjectValue != "") {
return false;
}
if (stringEntryObjectValue == strippedReferenceValue) {
return false;
}
} else {
if (explicitEmptyValue == false) {
if (referenceValue == "" && (stringEntryObjectValue == void 0 || stringEntryObjectValue == "")) {
return false;
} else if (referenceValue == "") {
continue reference_entry_loop;
}
}
if (stringEntryObjectValue != referenceValue) {
return false;
}
}
}
return true;
}
function collectObjectValuesForKey(key, converter, objects) {
const values = /* @__PURE__ */ new Set();
for (const object of objects) {
const stringEntryObject = converter(object);
const stringEntryObjectValue = stringEntryObject[key];
if (stringEntryObjectValue == void 0) continue;
values.add(stringEntryObjectValue.toString());
}
return [...values.values()];
}
function checkDoesObjectMatchSearch(query, getStringsOfObject, object) { function checkDoesObjectMatchSearch(query, getStringsOfObject, object) {
if (query == "") return true; if (query == "") return true;
const stringsInObject = getStringsOfObject(object); const stringsInObject = getStringsOfObject(object);
@@ -1094,6 +1053,20 @@
} }
return true; return true;
} }
function implementFilter(allItems, matches, query, itemToString) {
function update() {
matches.clear();
allItems.value.forEach((item) => {
if (!itemToString(item).toLowerCase().includes(query.value.toLowerCase())) return;
matches.add(item);
allItems.handleRemoval(item, () => {
matches.remove(item);
});
});
}
query.subscribe(update);
allItems.handleAddition(update);
}
var HandlerManager = class { var HandlerManager = class {
constructor() { constructor() {
this.handlers = /* @__PURE__ */ new Map(); this.handlers = /* @__PURE__ */ new Map();
@@ -1275,6 +1248,46 @@
]); ]);
}); });
} }
function collectObjectValuesForKey(key, converter, objects) {
const values = /* @__PURE__ */ new Set();
for (const object of objects) {
const stringEntryObject = converter(object);
const stringEntryObjectValue = stringEntryObject[key];
if (stringEntryObjectValue == void 0) continue;
values.add(stringEntryObjectValue.toString());
}
return [...values.values()];
}
function checkDoesObjectMatchReference(reference, stringEntryObject, explicitEmptyValue = false) {
reference_entry_loop: for (const referenceEntry of Object.entries(
reference
)) {
const [referenceKey, referenceValue] = referenceEntry;
const stringEntryObjectValue = stringEntryObject[referenceKey];
if (referenceValue == void 0) return false;
if (referenceValue[0] == "-") {
const strippedReferenceValue = referenceValue.toString().substring(1);
if (strippedReferenceValue == "" && stringEntryObjectValue != void 0 && stringEntryObjectValue != "") {
return false;
}
if (stringEntryObjectValue == strippedReferenceValue) {
return false;
}
} else {
if (explicitEmptyValue == false) {
if (referenceValue == "" && (stringEntryObjectValue == void 0 || stringEntryObjectValue == "")) {
return false;
} else if (referenceValue == "") {
continue reference_entry_loop;
}
}
if (stringEntryObjectValue != referenceValue) {
return false;
}
}
}
return true;
}
// src/ViewModel/Global/coreViewModel.ts // src/ViewModel/Global/coreViewModel.ts
var CoreViewModel = class _CoreViewModel { var CoreViewModel = class _CoreViewModel {
@@ -1285,7 +1298,7 @@
this.connectionModel = connectionModel2; this.connectionModel = connectionModel2;
this.chatListModel = chatListModel2; this.chatListModel = chatListModel2;
this.fileTransferModel = fileTransferModel2; this.fileTransferModel = fileTransferModel2;
this.BUILD = "Build 26.09.22.B"; this.BUILD = "Build 26.09.22.C";
// CONTEXT // CONTEXT
this.contextStack = /* @__PURE__ */ new Map(); this.contextStack = /* @__PURE__ */ new Map();
this.closeContext = (contextId, fromHistoryEvent = false) => { this.closeContext = (contextId, fromHistoryEvent = false) => {
@@ -1300,7 +1313,8 @@
} }
}; };
this.handleKeyDown = (e) => { this.handleKeyDown = (e) => {
if (!(e instanceof KeyboardEvent)) return console.trace("NOT A KEY EVENT"); if (!(e instanceof KeyboardEvent))
return console.trace("NOT A KEY EVENT");
if (_CoreViewModel.checkIsKeystroke(e) == false) return; if (_CoreViewModel.checkIsKeystroke(e) == false) return;
console.log(e.key); console.log(e.key);
e.preventDefault(); e.preventDefault();
@@ -1400,9 +1414,7 @@
if (this.isOpen == false) return; if (this.isOpen == false) return;
const selection = this.contextSelection; const selection = this.contextSelection;
if (!selection) return; if (!selection) return;
const selectedContext = this.contexts.get( const selectedContext = this.contexts.get(selection);
selection
);
if (!selectedContext) return; if (!selectedContext) return;
if (selectedContext != this.currentContext.value) { if (selectedContext != this.currentContext.value) {
this.closeCurrentContext(); this.closeCurrentContext();
@@ -1793,12 +1805,8 @@
this.selectedModalPage = new State(void 0); this.selectedModalPage = new State(void 0);
this.requiresReload = new State(false); this.requiresReload = new State(false);
this.firstDayOfWeek = new State("0"); this.firstDayOfWeek = new State("0");
this.language = new State( this.language = new State("en" /* English */);
"en" /* English */ this.theme = new State("system" /* System */);
);
this.theme = new State(
"system" /* System */
);
// guards // guards
this.cannotSetName = createProxyState( this.cannotSetName = createProxyState(
[this.usernameInput], [this.usernameInput],
@@ -1854,9 +1862,15 @@
} }
}; };
this.setScene = (scene) => { this.setScene = (scene) => {
document.body.style.setProperty("--backdrop-grass-filter", `brightness(${scene.brightness})`); document.body.style.setProperty(
"--backdrop-grass-filter",
`brightness(${scene.brightness})`
);
function setSkyColor(tone, hue, saturation, luma) { function setSkyColor(tone, hue, saturation, luma) {
document.body.style.setProperty(`--sky-${tone}`, `hsl(${hue}, ${saturation}%, ${luma}%)`); document.body.style.setProperty(
`--sky-${tone}`,
`hsl(${hue}, ${saturation}%, ${luma}%)`
);
} }
setSkyColor(1, scene.hue1, scene.saturation, scene.luma); setSkyColor(1, scene.hue1, scene.saturation, scene.luma);
setSkyColor(2, scene.hue2, scene.saturation - 10, scene.luma - 10); setSkyColor(2, scene.hue2, scene.saturation - 10, scene.luma - 10);
@@ -2210,6 +2224,7 @@
this.coreViewModel.connectionModel.address this.coreViewModel.connectionModel.address
); );
} }
this.hideConnectionModal();
}; };
// methods // methods
this.connect = () => { this.connect = () => {
@@ -2225,6 +2240,8 @@
this.removePreviousAddress = (address) => { this.removePreviousAddress = (address) => {
this.coreViewModel.connectionModel.removeAddress(address); this.coreViewModel.connectionModel.removeAddress(address);
this.updatePreviousAddresses(); this.updatePreviousAddresses();
if (this.previousAddresses.value.size > 0) return;
this.hideConnectionModal();
}; };
// view // view
this.showConnectionModal = () => { this.showConnectionModal = () => {
@@ -2819,7 +2836,9 @@
this.time = new State(""); this.time = new State("");
this.selectedVersionId = new State(""); this.selectedVersionId = new State("");
this.versionIds = new ListState(); this.versionIds = new ListState();
this.isPresentingFullScreenDescription = new State(false); this.isPresentingFullScreenDescription = new State(
false
);
// methods // methods
this.dragStart = (event) => { this.dragStart = (event) => {
ViewController.allowDrag(event); ViewController.allowDrag(event);
@@ -2865,12 +2884,16 @@
if (this.containingViewModel.taskCategorySuggestions.value.has( if (this.containingViewModel.taskCategorySuggestions.value.has(
this.category.value this.category.value
) == false) { ) == false) {
this.containingViewModel.taskCategorySuggestions.add(this.category.value); this.containingViewModel.taskCategorySuggestions.add(
this.category.value
);
} }
if (this.containingViewModel.taskStatusSuggestions.value.has( if (this.containingViewModel.taskStatusSuggestions.value.has(
this.status.value this.status.value
) == false) { ) == false) {
this.containingViewModel.taskStatusSuggestions.add(this.status.value); this.containingViewModel.taskStatusSuggestions.add(
this.status.value
);
} }
}; };
// settings // settings
@@ -3042,7 +3065,10 @@
[this.searchInput], [this.searchInput],
() => this.searchInput.value == "" () => this.searchInput.value == ""
); );
this.hasNoSuggestions = createProxyState([this.suggestions], () => this.suggestions.value.size == 0); this.hasNoSuggestions = createProxyState(
[this.suggestions],
() => this.suggestions.value.size == 0
);
// methods // methods
this.search = (searchTerm) => { this.search = (searchTerm) => {
this.searchInput.value = searchTerm; this.searchInput.value = searchTerm;
@@ -3173,9 +3199,7 @@
searchTerm searchTerm
]; ];
this.coreViewModel.storageModel.write(suggestionPath, ""); this.coreViewModel.storageModel.write(suggestionPath, "");
if (!this.searchSuggestions.value.has( if (!this.searchSuggestions.value.has(searchTerm) && searchTerm != "") {
searchTerm
) && searchTerm != "") {
this.searchSuggestions.add(searchTerm); this.searchSuggestions.add(searchTerm);
} }
const lastSearchPath = this.getLastSearchPath(); const lastSearchPath = this.getLastSearchPath();
@@ -3369,22 +3393,23 @@
return [...this.getBasePath(), "last-used-board" /* LastUsedBoard */]; return [...this.getBasePath(), "last-used-board" /* LastUsedBoard */];
}; };
// state // state
this.newBoardNameInput = new State(""); this.boardQuery = new State("");
this.boardViewModels = new MapState(); this.boardViewModels = new MapState();
this.boardMatches = new ListState();
this.isShowingBoadList = new State(true); this.isShowingBoadList = new State(true);
this.selectedBoardId = new State( this.selectedBoardId = new State(
void 0 void 0
); );
// guards // guards
this.cannotCreateBoard = createProxyState( this.cannotCreateBoard = createProxyState(
[this.newBoardNameInput], [this.boardQuery],
() => this.newBoardNameInput.value == "" () => this.boardQuery.value == ""
); );
// methods // methods
this.createBoard = () => { this.createBoard = () => {
if (this.cannotCreateBoard.value == true) return; if (this.cannotCreateBoard.value == true) return;
const boardInfoFileContent = this.boardsAndTasksModel.createBoard(this.newBoardNameInput.value); const boardInfoFileContent = this.boardsAndTasksModel.createBoard(this.boardQuery.value);
this.newBoardNameInput.value = ""; this.boardQuery.value = "";
this.showBoardInList(boardInfoFileContent); this.showBoardInList(boardInfoFileContent);
this.boardsAndTasksModel.updateBoardAndSend(boardInfoFileContent); this.boardsAndTasksModel.updateBoardAndSend(boardInfoFileContent);
this.updateBoardIndices(); this.updateBoardIndices();
@@ -3468,6 +3493,7 @@
}; };
this.loadData(); this.loadData();
this.chatViewModel = chatViewModel; this.chatViewModel = chatViewModel;
implementFilter(this.boardViewModels, this.boardMatches, this.boardQuery, (board) => board.name.value);
this.chatViewModel.registerContext("tasks" /* Tasks */, this); this.chatViewModel.registerContext("tasks" /* Tasks */, this);
this.selectedBoardId.subscribeSilent(this.updateContexts); this.selectedBoardId.subscribeSilent(this.updateContexts);
boardsAndTasksModel.boardHandlerManager.setHandler( boardsAndTasksModel.boardHandlerManager.setHandler(
@@ -5438,111 +5464,112 @@
const isSelected = entry[0] == taskViewModel.task.boardId; const isSelected = entry[0] == taskViewModel.task.boardId;
return Option(entry[1], entry[0], isSelected); return Option(entry[1], entry[0], isSelected);
}; };
return /* @__PURE__ */ createElement("div", { class: "modal task-settings", open: true, "toggle:full-description": taskViewModel.isPresentingFullScreenDescription }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", { id: "standard-main" }, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.chatPage.task.taskSettingsHeadline), /* @__PURE__ */ createElement("div", { class: "column-wrapper" }, /* @__PURE__ */ createElement("div", { class: "flex-column" }, /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "label"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskNameLabel), /* @__PURE__ */ createElement( return /* @__PURE__ */ createElement(
"input",
{
"bind:value": taskViewModel.name
}
))), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "category"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskBoardLabel), /* @__PURE__ */ createElement(
"select",
{
"bind:value": taskViewModel.boardId,
"children:append": [
taskViewModel.chatViewModel.taskBoardSuggestions,
BoardOptionConverter
]
}
), /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_drop_down"))), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "description"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskDescriptionLabel), /* @__PURE__ */ createElement(
"textarea",
{
rows: "10",
"bind:value": taskViewModel.description
}
))), /* @__PURE__ */ createElement("div", { class: "flex-row justify-end" }, /* @__PURE__ */ createElement(
"button",
{
class: "width-50",
"on:click": taskViewModel.openFullscreenDecription
},
coreViewModel2.translations.general.fullscreenButton,
/* @__PURE__ */ createElement("span", { class: "icon" }, "fullscreen")
))), /* @__PURE__ */ createElement("hr", { class: "mobile-only" }), /* @__PURE__ */ createElement("div", { class: "flex-column" }, /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "category"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskCategoryLabel), /* @__PURE__ */ createElement(
"input",
{
"bind:value": taskViewModel.category,
list: categorySuggestionId
}
))), /* @__PURE__ */ createElement(
"datalist",
{
hidden: true,
id: categorySuggestionId,
"children:append": [
taskViewModel.containingViewModel.taskCategorySuggestions,
StringToOption
]
}
), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "clock_loader_40"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskStatusLabel), /* @__PURE__ */ createElement(
"input",
{
"bind:value": taskViewModel.status,
list: statusSuggestionId
}
))), /* @__PURE__ */ createElement(
"datalist",
{
hidden: true,
id: statusSuggestionId,
"children:append": [
taskViewModel.containingViewModel.taskStatusSuggestions,
StringToOption
]
}
), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "priority_high"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskPriorityLabel), /* @__PURE__ */ createElement(
"input",
{
type: "number",
"bind:value": taskViewModel.priority
}
))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "calendar_month"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskDateLabel), /* @__PURE__ */ createElement(
"input",
{
type: "date",
"bind:value": taskViewModel.date
}
))), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "schedule"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskTimeLabel), /* @__PURE__ */ createElement(
"input",
{
type: "time",
"bind:value": taskViewModel.time
}
))))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "history"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.general.fileVersionLabel), /* @__PURE__ */ createElement(
"select",
{
"bind:value": taskViewModel.selectedVersionId,
"children:append": [
taskViewModel.versionIds,
VersionIdToOption
]
}
), /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_drop_down"))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "width-input" }, DangerousActionButton(
coreViewModel2,
coreViewModel2.translations.chatPage.task.deleteTaskButton,
"delete_forever",
taskViewModel.deleteTask
))), /* @__PURE__ */ createElement("main", { id: "fullscreen-main" }, /* @__PURE__ */ createElement(
"textarea",
{
style: "height: 100%; width: 100%; max-width: unset",
"bind:value": taskViewModel.description
}
)), /* @__PURE__ */ createElement(
"div", "div",
{ {
class: "flex-row width-100", class: "modal task-settings",
id: "fullscreen-exit" open: true,
"toggle:full-description": taskViewModel.isPresentingFullScreenDescription
}, },
/* @__PURE__ */ createElement( /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", { id: "standard-main" }, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.chatPage.task.taskSettingsHeadline), /* @__PURE__ */ createElement("div", { class: "column-wrapper" }, /* @__PURE__ */ createElement("div", { class: "flex-column" }, /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "label"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskNameLabel), /* @__PURE__ */ createElement(
"input",
{
"bind:value": taskViewModel.name
}
))), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "category"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskBoardLabel), /* @__PURE__ */ createElement(
"select",
{
"bind:value": taskViewModel.boardId,
"children:append": [
taskViewModel.chatViewModel.taskBoardSuggestions,
BoardOptionConverter
]
}
), /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_drop_down"))), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "description"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskDescriptionLabel), /* @__PURE__ */ createElement(
"textarea",
{
rows: "10",
"bind:value": taskViewModel.description
}
))), /* @__PURE__ */ createElement("div", { class: "flex-row justify-end" }, /* @__PURE__ */ createElement(
"button",
{
class: "width-50",
"on:click": taskViewModel.openFullscreenDecription
},
coreViewModel2.translations.general.fullscreenButton,
/* @__PURE__ */ createElement("span", { class: "icon" }, "fullscreen")
))), /* @__PURE__ */ createElement("hr", { class: "mobile-only" }), /* @__PURE__ */ createElement("div", { class: "flex-column" }, /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "category"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskCategoryLabel), /* @__PURE__ */ createElement(
"input",
{
"bind:value": taskViewModel.category,
list: categorySuggestionId
}
))), /* @__PURE__ */ createElement(
"datalist",
{
hidden: true,
id: categorySuggestionId,
"children:append": [
taskViewModel.containingViewModel.taskCategorySuggestions,
StringToOption
]
}
), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "clock_loader_40"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskStatusLabel), /* @__PURE__ */ createElement(
"input",
{
"bind:value": taskViewModel.status,
list: statusSuggestionId
}
))), /* @__PURE__ */ createElement(
"datalist",
{
hidden: true,
id: statusSuggestionId,
"children:append": [
taskViewModel.containingViewModel.taskStatusSuggestions,
StringToOption
]
}
), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "priority_high"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskPriorityLabel), /* @__PURE__ */ createElement(
"input",
{
type: "number",
"bind:value": taskViewModel.priority
}
))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "calendar_month"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskDateLabel), /* @__PURE__ */ createElement(
"input",
{
type: "date",
"bind:value": taskViewModel.date
}
))), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "schedule"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.chatPage.task.taskTimeLabel), /* @__PURE__ */ createElement(
"input",
{
type: "time",
"bind:value": taskViewModel.time
}
))))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "history"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.general.fileVersionLabel), /* @__PURE__ */ createElement(
"select",
{
"bind:value": taskViewModel.selectedVersionId,
"children:append": [
taskViewModel.versionIds,
VersionIdToOption
]
}
), /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_drop_down"))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "width-input" }, DangerousActionButton(
coreViewModel2,
coreViewModel2.translations.chatPage.task.deleteTaskButton,
"delete_forever",
taskViewModel.deleteTask
))), /* @__PURE__ */ createElement("main", { id: "fullscreen-main" }, /* @__PURE__ */ createElement(
"textarea",
{
style: "height: 100%; width: 100%; max-width: unset",
"bind:value": taskViewModel.description
}
)), /* @__PURE__ */ createElement("div", { class: "flex-row width-100", id: "fullscreen-exit" }, /* @__PURE__ */ createElement(
"button", "button",
{ {
class: "flex", class: "flex",
@@ -5550,22 +5577,14 @@
}, },
coreViewModel2.translations.general.exitButton, coreViewModel2.translations.general.exitButton,
/* @__PURE__ */ createElement("span", { class: "icon" }, "fullscreen_exit") /* @__PURE__ */ createElement("span", { class: "icon" }, "fullscreen_exit")
) )), /* @__PURE__ */ createElement("div", { class: "flex-row width-100", id: "controls" }, /* @__PURE__ */ createElement(
), /* @__PURE__ */ createElement(
"div",
{
class: "flex-row width-100",
id: "controls"
},
/* @__PURE__ */ createElement(
"button", "button",
{ {
class: "flex", class: "flex",
"on:click": taskViewModel.closeAndDiscard "on:click": taskViewModel.closeAndDiscard
}, },
coreViewModel2.translations.general.closeButton coreViewModel2.translations.general.closeButton
), ), /* @__PURE__ */ createElement(
/* @__PURE__ */ createElement(
"button", "button",
{ {
class: "flex primary", class: "flex primary",
@@ -5573,8 +5592,8 @@
}, },
coreViewModel2.translations.general.saveButton, coreViewModel2.translations.general.saveButton,
/* @__PURE__ */ createElement("span", { class: "icon" }, "save") /* @__PURE__ */ createElement("span", { class: "icon" }, "save")
) )))
))); );
} }
// src/View/Modals/searchModal.tsx // src/View/Modals/searchModal.tsx
@@ -5625,27 +5644,26 @@
"toggle:disabled": searchViewModel.cannotApplySearch "toggle:disabled": searchViewModel.cannotApplySearch
}, },
/* @__PURE__ */ createElement("span", { class: "icon" }, "search") /* @__PURE__ */ createElement("span", { class: "icon" }, "search")
)), /* @__PURE__ */ createElement( )), /* @__PURE__ */ createElement("div", { "toggle:hidden": searchViewModel.hasNoSuggestions }, /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("h3", null, coreViewModel2.translations.general.searchSuggestionsLabel), /* @__PURE__ */ createElement(
"div", "div",
{ {
"toggle:hidden": searchViewModel.hasNoSuggestions class: "flex-column gap",
}, "children:append": [
/* @__PURE__ */ createElement("hr", null), searchViewModel.suggestions,
/* @__PURE__ */ createElement("h3", null, coreViewModel2.translations.general.searchSuggestionsLabel), (suggestion) => SuggestionView(
/* @__PURE__ */ createElement( suggestion,
"div", searchViewModel,
{ coreViewModel2
class: "flex-column gap", )
"children:append": [ ]
searchViewModel.suggestions, }
(suggestion) => SuggestionView(suggestion, searchViewModel, coreViewModel2) ))), /* @__PURE__ */ createElement("button", { "on:click": close }, coreViewModel2.translations.general.closeButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
]
}
)
)), /* @__PURE__ */ createElement("button", { "on:click": close }, coreViewModel2.translations.general.closeButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
} }
function SuggestionView(suggestion, searchViewModel, coreViewModel2) { function SuggestionView(suggestion, searchViewModel, coreViewModel2) {
const isApplied = createProxyState([searchViewModel.appliedQuery], () => searchViewModel.appliedQuery.value == suggestion); const isApplied = createProxyState(
[searchViewModel.appliedQuery],
() => searchViewModel.appliedQuery.value == suggestion
);
function deleteSuggestion() { function deleteSuggestion() {
searchViewModel.deleteSuggestion(suggestion); searchViewModel.deleteSuggestion(suggestion);
} }
@@ -5855,7 +5873,7 @@
"button", "button",
{ {
"set:color": boardViewModel.color, "set:color": boardViewModel.color,
class: "tile colored-tile", class: "tile colored-tile slide-up",
"toggle:selected": boardViewModel.isSelected, "toggle:selected": boardViewModel.isSelected,
"on:click": boardViewModel.select, "on:click": boardViewModel.select,
"on:dragover": ViewController.allowDrop, "on:dragover": ViewController.allowDrop,
@@ -5879,6 +5897,22 @@
return BoardEntry(boardViewModel); return BoardEntry(boardViewModel);
}; };
// src/View/Components/newItemEntry.tsx
function NewItemEntry(coreViewModel2, query, fn) {
const isHidden = createProxyState([query], () => query.value == "");
const label = createProxyState([query], () => coreViewModel2.translations.general.createLabel(query.value));
return /* @__PURE__ */ createElement(
"button",
{
class: "standard slide-up",
"toggle:hidden": isHidden,
"on:click": fn
},
/* @__PURE__ */ createElement("span", { "subscribe:innerText": label }),
/* @__PURE__ */ createElement("span", { class: "icon" }, "add")
);
}
// src/View/ChatPages/taskPage.tsx // src/View/ChatPages/taskPage.tsx
function TaskPage(coreViewModel2, taskPageViewModel) { function TaskPage(coreViewModel2, taskPageViewModel) {
taskPageViewModel.loadData(); taskPageViewModel.loadData();
@@ -5921,26 +5955,17 @@
"input", "input",
{ {
class: "no-outline", class: "no-outline",
"bind:value": taskPageViewModel.newBoardNameInput, "bind:value": taskPageViewModel.boardQuery,
"on:enter": taskPageViewModel.createBoard, "on:enter": taskPageViewModel.createBoard,
placeholder: coreViewModel2.translations.chatPage.task.newBoardNamePlaceholder placeholder: coreViewModel2.translations.general.filterOrCreateLabel
} }
), /* @__PURE__ */ createElement( ))), /* @__PURE__ */ createElement("div", { class: "content gap" }, NewItemEntry(coreViewModel2, taskPageViewModel.boardQuery, taskPageViewModel.createBoard), /* @__PURE__ */ createElement(
"button",
{
class: "primary",
"aria-label": coreViewModel2.translations.chatPage.task.createBoardButtonAudioLabel,
"on:click": taskPageViewModel.createBoard,
"toggle:disabled": taskPageViewModel.cannotCreateBoard
},
/* @__PURE__ */ createElement("span", { class: "icon" }, "add")
))), /* @__PURE__ */ createElement("div", { class: "content" }, /* @__PURE__ */ createElement(
"div", "div",
{ {
class: "grid gap", class: "grid gap",
style: "grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr))", style: "grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr))",
"children:append": [ "children:append": [
taskPageViewModel.boardViewModels, taskPageViewModel.boardMatches,
BoardViewModelToEntry BoardViewModelToEntry
] ]
} }
@@ -6762,6 +6787,7 @@
"button", "button",
{ {
class: "ghost", class: "ghost",
id: "close-button",
"aria-label": coreViewModel2.translations.chatPage.closeChatAudioLabe, "aria-label": coreViewModel2.translations.chatPage.closeChatAudioLabe,
"on:click": chatViewModel.close "on:click": chatViewModel.close
}, },
@@ -6772,7 +6798,8 @@
class: "danger", class: "danger",
"aria-label": coreViewModel2.translations.general.restoreConnection, "aria-label": coreViewModel2.translations.general.restoreConnection,
"on:click": chatViewModel.connectionViewModel.showConnectionModal, "on:click": chatViewModel.connectionViewModel.showConnectionModal,
"toggle:hidden": chatViewModel.connectionViewModel.isConnected "toggle:hidden": chatViewModel.connectionViewModel.isConnected,
"toggle:disabled": chatViewModel.connectionViewModel.hasNoPreviousConnections
}, },
/* @__PURE__ */ createElement("span", { class: "icon" }, "signal_disconnected") /* @__PURE__ */ createElement("span", { class: "icon" }, "signal_disconnected")
), /* @__PURE__ */ createElement("span", { class: "marquee", "children:set": marqueeContent }), /* @__PURE__ */ createElement("span", { class: "navigation-buttons" }, ChatViewToggleButton( ), /* @__PURE__ */ createElement("span", { class: "marquee", "children:set": marqueeContent }), /* @__PURE__ */ createElement("span", { class: "navigation-buttons" }, ChatViewToggleButton(
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+92 -101
View File
@@ -4,6 +4,7 @@ import { StringToOption } from "../Components/option";
import * as React from "../../react"; import * as React from "../../react";
import SearchViewModel from "../../ViewModel/Utility/searchViewModel"; import SearchViewModel from "../../ViewModel/Utility/searchViewModel";
import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel";
import {DeletableListItem} from "../Components/deletableListItem";
export function SearchModal<T>( export function SearchModal<T>(
coreViewModel: CoreViewModel, coreViewModel: CoreViewModel,
@@ -12,92 +13,92 @@ export function SearchModal<T>(
isOpen: React.State<boolean>, isOpen: React.State<boolean>,
) { ) {
function close() { function close() {
isOpen.value = false; isOpen.value = false;
} }
const suggestionId = v4(); const suggestionId = v4();
isOpen.subscribe((isOpen) => { isOpen.subscribe((isOpen) => {
if (!isOpen) return; if (!isOpen) return;
ViewController.setFocusWithDelay(); ViewController.setFocusWithDelay();
}); });
return ( return (
<div class="modal" toggle:open={isOpen} extended> <div class="modal" toggle:open={isOpen} extended>
<div> <div>
<main> <main>
<h2>{headline}</h2> <h2>{headline}</h2>
<div class="flex-row"> <div class="flex-row">
<input <input
id="focused" id="focused"
style="max-width: unset" style="max-width: unset"
placeholder={ placeholder={
coreViewModel.translations.general.searchLabel coreViewModel.translations.general.searchLabel
} }
bind:value={searchViewModel.searchInput} bind:value={searchViewModel.searchInput}
on:enter={searchViewModel.applySearch} on:enter={searchViewModel.applySearch}
list={suggestionId} list={suggestionId}
></input> ></input>
<datalist <datalist
hidden hidden
id={suggestionId} id={suggestionId}
children:append={[ children:append={[
searchViewModel.suggestions, searchViewModel.suggestions,
StringToOption, StringToOption,
]} ]}
></datalist> ></datalist>
<button <button
class="standard" class="standard"
aria-label={ aria-label={
coreViewModel.translations.general coreViewModel.translations.general
.searchButtonClearAudioLabel .searchButtonClearAudioLabel
} }
on:click={searchViewModel.clear} on:click={searchViewModel.clear}
toggle:disabled={searchViewModel.cannotClear} toggle:disabled={searchViewModel.cannotClear}
> >
<span class="icon">close</span> <span class="icon">close</span>
</button> </button>
<button <button
class="primary" class="primary"
aria-label={ aria-label={
coreViewModel.translations.general coreViewModel.translations.general
.searchButtonAudioLabel .searchButtonAudioLabel
} }
on:click={searchViewModel.applySearch} on:click={searchViewModel.applySearch}
toggle:disabled={searchViewModel.cannotApplySearch} toggle:disabled={searchViewModel.cannotApplySearch}
> >
<span class="icon">search</span> <span class="icon">search</span>
</button> </button>
</div> </div>
<div toggle:hidden={searchViewModel.hasNoSuggestions}> <div toggle:hidden={searchViewModel.hasNoSuggestions}>
<hr></hr> <hr></hr>
<h3> <h3>
{ {
coreViewModel.translations.general coreViewModel.translations.general
.searchSuggestionsLabel .searchSuggestionsLabel
} }
</h3> </h3>
<div <div
class="flex-column gap" class="flex-column gap"
children:append={[ children:append={[
searchViewModel.suggestions, searchViewModel.suggestions,
(suggestion: string) => (suggestion: string) =>
SuggestionView( SuggestionView(
suggestion, suggestion,
searchViewModel, searchViewModel,
coreViewModel, coreViewModel,
), ),
]} ]}
></div> ></div>
</div> </div>
</main> </main>
<button on:click={close}> <button on:click={close}>
{coreViewModel.translations.general.closeButton} {coreViewModel.translations.general.closeButton}
<span class="icon">close</span> <span class="icon">close</span>
</button> </button>
</div> </div>
</div> </div>
); );
} }
@@ -107,36 +108,26 @@ function SuggestionView<T>(
coreViewModel: CoreViewModel, coreViewModel: CoreViewModel,
) { ) {
const isApplied = React.createProxyState( const isApplied = React.createProxyState(
[searchViewModel.appliedQuery], [searchViewModel.appliedQuery],
() => searchViewModel.appliedQuery.value == suggestion, () => searchViewModel.appliedQuery.value == suggestion,
); );
function deleteSuggestion() { function deleteSuggestion() {
searchViewModel.deleteSuggestion(suggestion); searchViewModel.deleteSuggestion(suggestion);
} }
function applySuggestion() { function applySuggestion() {
searchViewModel.search(suggestion); searchViewModel.search(suggestion);
} }
return ( return DeletableListItem(coreViewModel, suggestion,
<div class="flex-row surface align-center"> <button
<span class="width-100 flex-1 padding-h">{suggestion}</span> class="primary"
<button aria-label={coreViewModel.translations.general.applyButton}
class="danger" on:click={applySuggestion}
aria-label={coreViewModel.translations.general.deleteButton} toggle:disabled={isApplied}
on:click={deleteSuggestion} >
> <span class="icon">check</span>
<span class="icon">delete</span> </button>
</button> , deleteSuggestion)
<button
class="primary"
aria-label={coreViewModel.translations.general.applyButton}
on:click={applySuggestion}
toggle:disabled={isApplied}
>
<span class="icon">check</span>
</button>
</div>
);
} }
+1 -1
View File
@@ -9,7 +9,7 @@ import ConnectionModel from "../../Model/Global/connectionModel";
import ChatListModel from "../../Model/Chat/chatListModel"; import ChatListModel from "../../Model/Chat/chatListModel";
export default class CoreViewModel { export default class CoreViewModel {
readonly BUILD = "Build 26.09.22.B"; readonly BUILD = "Build 26.09.22.C";
translations: Translations; translations: Translations;