add kanban view
This commit is contained in:
Vendored
+23
-6
@@ -293,6 +293,7 @@ body[showing-chat] #chat-page-wrapper {
|
||||
flex-direction: column;
|
||||
scroll-snap-align: center;
|
||||
min-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
#chat-page > div > #main > div > .pane-wrapper > .pane:not(.side),
|
||||
#chat-page > div > #main > div > .pane-wrapper > .pane:not(.side) .content {
|
||||
@@ -303,6 +304,8 @@ body[showing-chat] #chat-page-wrapper {
|
||||
min-width: unset;
|
||||
}
|
||||
#chat-page > div > #main > div > .pane-wrapper.side {
|
||||
width: 18rem;
|
||||
min-width: 18rem;
|
||||
max-width: 18rem;
|
||||
}
|
||||
}
|
||||
@@ -566,28 +569,42 @@ body[showing-chat] #chat-page-wrapper {
|
||||
}
|
||||
|
||||
/* src/View/ChatPages/taskPage.css */
|
||||
#task-page .task-grid {
|
||||
#chat-page > div > #main > #task-page > .pane-wrapper > .pane > .main-content {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
padding: 0px;
|
||||
}
|
||||
#chat-page > div > #main > #task-page .task-grid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--gap-between-tiles);
|
||||
padding: var(--content-padding);
|
||||
}
|
||||
#chat-page > div > #main > #task-page .kanban-board-wrapper {
|
||||
display: flex;
|
||||
gap: var(--large-gap);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
padding: var(--content-padding);
|
||||
}
|
||||
@media (min-width: 640px) {
|
||||
#task-page .task-grid {
|
||||
#chat-page > div > #main > #task-page .task-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
|
||||
}
|
||||
}
|
||||
@media (max-width: 1024px) {
|
||||
#task-page #board-list {
|
||||
#chat-page > div > #main > #task-page #board-list {
|
||||
display: false;
|
||||
}
|
||||
#task-page #board-content {
|
||||
#chat-page > div > #main > #task-page #board-content {
|
||||
display: none;
|
||||
}
|
||||
#task-page[isshowingboard] #board-list {
|
||||
#chat-page > div > #main > #task-page[isshowingboard] #board-list {
|
||||
display: none;
|
||||
}
|
||||
#task-page[isshowingboard] #board-content {
|
||||
#chat-page > div > #main > #task-page[isshowingboard] #board-content {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+201
-38
@@ -330,6 +330,45 @@
|
||||
}
|
||||
};
|
||||
};
|
||||
function checkDoesObjectMatchReference(reference, stringEntryObject) {
|
||||
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.substring(1);
|
||||
if (strippedReferenceValue == "" && stringEntryObjectValue != void 0 && stringEntryObjectValue != "") {
|
||||
return false;
|
||||
}
|
||||
if (stringEntryObjectValue == strippedReferenceValue) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
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 || stringEntryObjectValue == "")
|
||||
continue;
|
||||
values.add(stringEntryObjectValue);
|
||||
}
|
||||
return [...values.values()].sort(localeCompare);
|
||||
}
|
||||
var IndexManager = class {
|
||||
itemToString;
|
||||
sortedStrings = [];
|
||||
@@ -2145,7 +2184,9 @@
|
||||
taskDescriptionLabel: "Description",
|
||||
taskDateLabel: "Date",
|
||||
taskTimeLabel: "Time",
|
||||
deleteTaskButton: "Delete task"
|
||||
deleteTaskButton: "Delete task",
|
||||
///
|
||||
renameCategoryInputPlaceholder: "Rename category,"
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -2404,9 +2445,166 @@
|
||||
))))));
|
||||
}
|
||||
|
||||
// src/View/Components/filteredList.tsx
|
||||
function FilteredList(reference, stringEntryObjectConverter, objects, viewBuilder) {
|
||||
const matchingObjects = new ListState();
|
||||
objects.handleAddition((newObject) => {
|
||||
const doesMatch = checkDoesObjectMatchReference(
|
||||
reference,
|
||||
stringEntryObjectConverter(newObject)
|
||||
);
|
||||
if (doesMatch == false) return;
|
||||
matchingObjects.add(newObject);
|
||||
objects.handleRemoval(newObject, () => {
|
||||
matchingObjects.remove(newObject);
|
||||
});
|
||||
});
|
||||
return viewBuilder(matchingObjects);
|
||||
}
|
||||
|
||||
// src/View/Components/propertyList.tsx
|
||||
function PropertyValueList(propertyKey, stringEntryObjectConverter, objects, viewBuilder) {
|
||||
const propertyValues = new ListState();
|
||||
function collectValues() {
|
||||
propertyValues.clear();
|
||||
const values = collectObjectValuesForKey(
|
||||
propertyKey,
|
||||
stringEntryObjectConverter,
|
||||
[...objects.value.values()]
|
||||
);
|
||||
propertyValues.add(...values);
|
||||
}
|
||||
objects.subscribe(() => {
|
||||
collectValues();
|
||||
});
|
||||
return viewBuilder(propertyValues);
|
||||
}
|
||||
|
||||
// src/ViewModel/Pages/taskPropertyBulkChangeViewModel.ts
|
||||
var TaskPropertyBulkChangeViewModel = class {
|
||||
taskViewModels;
|
||||
// state
|
||||
inputValue = new State("");
|
||||
// guards
|
||||
cannotSet;
|
||||
// methods
|
||||
set = () => {
|
||||
if (this.cannotSet.value == true) return;
|
||||
this.taskViewModels.value.forEach((taskViewModel) => {
|
||||
this.setValue(this.inputValue.value, taskViewModel);
|
||||
});
|
||||
};
|
||||
setValue;
|
||||
// init
|
||||
constructor(taskViewModels, valueSetter, initialValue) {
|
||||
this.taskViewModels = taskViewModels;
|
||||
this.inputValue.value = initialValue;
|
||||
this.setValue = valueSetter;
|
||||
this.cannotSet = createProxyState(
|
||||
[this.inputValue],
|
||||
() => this.inputValue.value == "" || this.inputValue.value == initialValue
|
||||
);
|
||||
}
|
||||
};
|
||||
var TaskCategoryBulkChangeViewModel = class extends TaskPropertyBulkChangeViewModel {
|
||||
constructor(taskViewModels, initialValue) {
|
||||
super(
|
||||
taskViewModels,
|
||||
(newCategory, taskViewModel) => {
|
||||
taskViewModel.category.value = newCategory;
|
||||
taskViewModel.save();
|
||||
},
|
||||
initialValue
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// src/View/Components/taskEntry.tsx
|
||||
function TaskEntry(taskViewModel) {
|
||||
const details = {
|
||||
description: taskViewModel.description.value || "---",
|
||||
priority_high: taskViewModel.priority.value || "---",
|
||||
category: taskViewModel.category.value || "---",
|
||||
clock_loader_40: taskViewModel.status.value || "---",
|
||||
calendar_month: taskViewModel.date.value || "---",
|
||||
schedule: taskViewModel.time.value || "---"
|
||||
};
|
||||
const view = /* @__PURE__ */ createElement("button", { class: "tile flex-no", "on:click": taskViewModel.open }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", { "subscribe:innerText": taskViewModel.name }), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement(
|
||||
"div",
|
||||
{
|
||||
class: "grid secondary",
|
||||
style: "grid-template-columns: repeat(2, 1fr); column-gap: 1rem; row-gap: .5rem"
|
||||
},
|
||||
...Object.entries(details).map((entry) => /* @__PURE__ */ createElement(
|
||||
"span",
|
||||
{
|
||||
class: "flex-row align-center width-100 flex-no clip",
|
||||
style: "gap: 1rem"
|
||||
},
|
||||
/* @__PURE__ */ createElement("span", { class: "icon", style: "font-size: 1.1rem" }, entry[0]),
|
||||
/* @__PURE__ */ createElement("span", { class: "ellipsis" }, entry[1])
|
||||
))
|
||||
)));
|
||||
taskViewModel.index.subscribe((newIndex) => {
|
||||
view.style.order = newIndex;
|
||||
});
|
||||
return view;
|
||||
}
|
||||
var TaskViewModelToEntry = (taskViewModel) => {
|
||||
return TaskEntry(taskViewModel);
|
||||
};
|
||||
|
||||
// src/View/ChatPages/boardKanbanPage.tsx
|
||||
function BoardKanbanPage(boardViewModel) {
|
||||
return /* @__PURE__ */ createElement("div", null, "Kanban");
|
||||
const categoryNameConverter = (categoryName) => {
|
||||
return KanbanBoard(categoryName, boardViewModel);
|
||||
};
|
||||
return PropertyValueList(
|
||||
"category",
|
||||
(taskViewModel) => taskViewModel.task,
|
||||
boardViewModel.taskViewModels,
|
||||
(categories) => {
|
||||
return /* @__PURE__ */ createElement(
|
||||
"div",
|
||||
{
|
||||
class: "kanban-board-wrapper",
|
||||
"children:append": [categories, categoryNameConverter]
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
function KanbanBoard(categoryName, boardViewModel) {
|
||||
return FilteredList(
|
||||
{ category: categoryName },
|
||||
(taskViewModel) => taskViewModel.task,
|
||||
boardViewModel.taskViewModels,
|
||||
(taskViewModels) => {
|
||||
const viewModel = new TaskCategoryBulkChangeViewModel(taskViewModels, categoryName);
|
||||
return /* @__PURE__ */ createElement("div", { class: "flex-column flex-no", style: "width: 18rem; min-width: 18rem" }, /* @__PURE__ */ createElement("div", { class: "flex-row width-input" }, /* @__PURE__ */ createElement(
|
||||
"input",
|
||||
{
|
||||
placeholder: translations.chatPage.task.renameCategoryInputPlaceholder,
|
||||
"bind:value": viewModel.inputValue,
|
||||
"on:enter": viewModel.set
|
||||
}
|
||||
), /* @__PURE__ */ createElement(
|
||||
"button",
|
||||
{
|
||||
class: "primary",
|
||||
"on:click": viewModel.set,
|
||||
"toggle:disabled": viewModel.cannotSet
|
||||
},
|
||||
/* @__PURE__ */ createElement("span", { class: "icon" }, "check")
|
||||
)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement(
|
||||
"div",
|
||||
{
|
||||
class: "flex-column gap",
|
||||
"children:append": [taskViewModels, TaskViewModelToEntry]
|
||||
}
|
||||
));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// src/View/Modals/boardSettingsModal.tsx
|
||||
@@ -2471,41 +2669,6 @@
|
||||
))), /* @__PURE__ */ createElement("div", { class: "flex-row width-100" }, /* @__PURE__ */ createElement("button", { class: "flex", "on:click": taskViewModel.close }, translations.general.closeButton), /* @__PURE__ */ createElement("button", { class: "flex primary", "on:click": taskViewModel.closeAndSave }, translations.general.saveButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "save")))));
|
||||
}
|
||||
|
||||
// src/View/Components/taskEntry.tsx
|
||||
function TaskEntry(taskViewModel) {
|
||||
const details = {
|
||||
description: taskViewModel.description.value || "---",
|
||||
priority_high: taskViewModel.priority.value || "---",
|
||||
category: taskViewModel.category.value || "---",
|
||||
clock_loader_40: taskViewModel.status.value || "---",
|
||||
calendar_month: taskViewModel.date.value || "---",
|
||||
schedule: taskViewModel.time.value || "---"
|
||||
};
|
||||
const view = /* @__PURE__ */ createElement("button", { class: "tile", "on:click": taskViewModel.open }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", { "subscribe:innerText": taskViewModel.name }), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement(
|
||||
"div",
|
||||
{
|
||||
class: "grid secondary",
|
||||
style: "grid-template-columns: repeat(2, 1fr); column-gap: 1rem; row-gap: .5rem"
|
||||
},
|
||||
...Object.entries(details).map((entry) => /* @__PURE__ */ createElement(
|
||||
"span",
|
||||
{
|
||||
class: "flex-row align-center width-100 flex-no clip",
|
||||
style: "gap: 1rem"
|
||||
},
|
||||
/* @__PURE__ */ createElement("span", { class: "icon", style: "font-size: 1.1rem" }, entry[0]),
|
||||
/* @__PURE__ */ createElement("span", { class: "ellipsis" }, entry[1])
|
||||
))
|
||||
)));
|
||||
taskViewModel.index.subscribe((newIndex) => {
|
||||
view.style.order = newIndex;
|
||||
});
|
||||
return view;
|
||||
}
|
||||
var TaskViewModelToEntry = (taskViewModel) => {
|
||||
return TaskEntry(taskViewModel);
|
||||
};
|
||||
|
||||
// src/View/ChatPages/boardPage.tsx
|
||||
function BoardPage(boardViewModel) {
|
||||
boardViewModel.loadData();
|
||||
@@ -2588,7 +2751,7 @@
|
||||
"on:click": boardViewModel.createTask
|
||||
},
|
||||
/* @__PURE__ */ createElement("span", { class: "icon" }, "add")
|
||||
))), /* @__PURE__ */ createElement("div", { class: "content", "children:set": mainContent }), BoardSettingsModal(boardViewModel), /* @__PURE__ */ createElement("div", { "children:set": taskSettingsModal }));
|
||||
))), /* @__PURE__ */ createElement("div", { class: "content main-content", "children:set": mainContent }), BoardSettingsModal(boardViewModel), /* @__PURE__ */ createElement("div", { "children:set": taskSettingsModal }));
|
||||
}
|
||||
|
||||
// src/View/Components/boardEntry.tsx
|
||||
|
||||
Reference in New Issue
Block a user