-
-
-
-
- #
- {{ project.title }}
-
-
+
+
+
+
+
+ #
+ {{ project.title }}
+
+
+
+
+
+
+ {{ t(projectStatus?.title) }}
+
+
+ Set status
+
+
-
-
-
- {{ projectStatus?.title }}
-
-
- Set status
-
-
-
-
-
-
+
+
+
diff --git a/packages/app/src/main.ts b/packages/app/src/main.ts
index f73efe9..28032c0 100644
--- a/packages/app/src/main.ts
+++ b/packages/app/src/main.ts
@@ -111,27 +111,18 @@ app
})
.use(router);
-
-
-
inject() // injecting analytics
-function customRule(choice: number, choicesLength: number) {
- if (choice === 0) {
- return 0
- }
+function customRule(choice: number, _choicesLength: number) {
+ const calcValue = Math.abs(choice) % 100;
+ const num = calcValue % 10;
- const teen = choice > 10 && choice < 20
- const endsWithOne = choice % 10 === 1
- if (!teen && endsWithOne) {
- return 1
- }
- if (!teen && choice % 10 >= 2 && choice % 10 <= 4) {
- return 2
- }
-
- return choicesLength < 4 ? 2 : 3
+ if (calcValue > 10 && calcValue < 20) return 3;
+ if (num > 1 && num < 5) return 2;
+ if (num === 1) return 1;
+ return 3;
}
+
const i18n = createI18n({
locale: "ru",
fallbackLocale: "en",
diff --git a/packages/app/src/views/office/projects.vue b/packages/app/src/views/office/projects.vue
index 7fdf372..c6b4e6d 100644
--- a/packages/app/src/views/office/projects.vue
+++ b/packages/app/src/views/office/projects.vue
@@ -11,136 +11,168 @@ import hotkeys from "hotkeys-js";
import { useDeleteModalStore } from "@store/delete-modal";
import { nanoid } from "nanoid";
import { onMounted, onUnmounted, ref } from "vue";
+import { useI18n } from "vue-i18n";
const projectStore = useProjectStore();
const projectStatusModalStore = useProjectStatusModalStore();
+const { t } = useI18n({
+ messages: {
+ en: {
+ title: "Projects",
+ create: "New project",
+ updateStatus: "Update {length} projects?",
+ column: {
+ title: "Title",
+ status: "Status"
+ },
+ deleteModal: {
+ multipleDelete: `Are you sure you want to delete {length} projects?`,
+ warning: "Delete would be permanent, you can’t restore issues later.",
+ spesificDelete: `Are you sure you want to delete “{title}”?`
+ },
+ },
+
+ ru: {
+ title: "Проекты",
+ create: "Новый проект",
+ updateStatus: "Обновить {length} проект? | Обновить {length} проекта? | Обновить {length} проектов?",
+ column: {
+ title: "Название",
+ status: "Статус"
+ },
+ deleteModal: {
+ multipleDelete: `Вы уверенны, что хотите удалить {length} проект? | Вы уверенны, что хотите удалить {length} проекта? | Вы уверенны, что хотите удалить {length} проектов?`,
+ warning: "Удаление будет пермонентным, вы не сможете восстановить проекты",
+ spesificDelete: `Вы уверены, что хотети удалить “{title}”?`
+ },
+ }
+ }
+})
+
const rowsContainer = ref
(null);
onMounted(async () => {
- await projectStore.loadProjects();
+ await projectStore.loadProjects();
- hotkeys("C", onCreateProject);
+ hotkeys("C", onCreateProject);
- hotkeys("x", () => {
- if (hoveredProjectId.value) {
- updateSelection(hoveredProjectId.value);
- }
- });
+ hotkeys("x", () => {
+ if (hoveredProjectId.value) {
+ updateSelection(hoveredProjectId.value);
+ }
+ });
- hotkeys("cmd+backspace", () => {
- removeProject();
- });
+ hotkeys("cmd+backspace", () => {
+ removeProject();
+ });
- hotkeys("S", () => {
- onSetStatus();
- });
+ hotkeys("S", () => {
+ onSetStatus();
+ });
- hotkeys("esc", () => {
- selectedProjectsIds.value = [];
- });
+ hotkeys("esc", () => {
+ selectedProjectsIds.value = [];
+ });
});
onUnmounted(() => {
- hotkeys.unbind("C", "all", onCreateProject);
+ hotkeys.unbind("C", "all", onCreateProject);
});
function onUpdateProject(id: string, project: Partial) {
- if (project?.title === "") return;
+ if (project?.title === "") return;
- projectStore.edit(id, project);
+ projectStore.edit(id, project);
}
function onCreateProject() {
- projectStore.create("");
+ projectStore.create("");
- setTimeout(() => {
- if (!rowsContainer.value) return;
+ setTimeout(() => {
+ if (!rowsContainer.value) return;
- const addedElement = Array.from(rowsContainer.value.children).find((el) => {
- const editable = el.querySelector("[contenteditable]")!;
- return editable.textContent === "";
+ const addedElement = Array.from(rowsContainer.value.children).find((el) => {
+ const editable = el.querySelector("[contenteditable]")!;
+ return editable.textContent === "";
+ });
+
+ addedElement?.scrollIntoView();
+ addedElement &&
+ focusOnEditableElement(
+ addedElement.querySelector("[contenteditable]") as HTMLElement,
+ );
});
-
- addedElement?.scrollIntoView();
- addedElement &&
- focusOnEditableElement(
- addedElement.querySelector("[contenteditable]") as HTMLElement,
- );
- });
}
const selectedProjectsIds = ref([]);
function updateSelection(projectId: string) {
- if (selectedProjectsIds.value.includes(projectId)) {
- const idx = selectedProjectsIds.value.findIndex((id) => id === projectId);
- selectedProjectsIds.value.splice(idx, 1);
- return;
- }
+ if (selectedProjectsIds.value.includes(projectId)) {
+ const idx = selectedProjectsIds.value.findIndex((id) => id === projectId);
+ selectedProjectsIds.value.splice(idx, 1);
+ return;
+ }
- selectedProjectsIds.value.push(projectId);
+ selectedProjectsIds.value.push(projectId);
}
-
async function onSetStatus() {
- if (selectedProjectsIds.value.length <= 0) {
- if (!hoveredProjectId.value) return;
+ if (selectedProjectsIds.value.length <= 0) {
+ if (!hoveredProjectId.value) return;
- const project = projectStore.getOne(hoveredProjectId.value);
- if (!project) return;
+ const project = projectStore.getOne(hoveredProjectId.value);
+ if (!project) return;
- selectedProjectsIds.value = [];
+ selectedProjectsIds.value = [];
+
+ const statusId = await projectStatusModalStore.use({
+ hintText: project.title,
+ statusId: project.statusId,
+ });
+
+ projectStore.edit(project.id, { statusId });
+
+ return;
+ }
const statusId = await projectStatusModalStore.use({
- hintText: project.title,
- statusId: project.statusId,
+ hintText: t("updateStatus", { length: selectedProjectsIds.value.length }, selectedProjectsIds.value.length),
+ statusId: null,
});
- projectStore.edit(project.id, { statusId });
+ selectedProjectsIds.value.forEach((id) => {
+ projectStore.edit(id, { statusId });
+ });
- return;
- }
-
- const statusId = await projectStatusModalStore.use({
- hintText: `Update ${selectedProjectsIds.value.length} projects`,
- statusId: null,
- });
-
- selectedProjectsIds.value.forEach((id) => {
- projectStore.edit(id, { statusId });
- });
-
- selectedProjectsIds.value = [];
+ selectedProjectsIds.value = [];
}
const deleteModalStore = useDeleteModalStore();
async function removeProject() {
- if (selectedProjectsIds.value.length) {
+ if (selectedProjectsIds.value.length) {
+ const res = await deleteModalStore.use({
+ titleText: t("deleteModal.multipleDelete", { length: selectedProjectsIds.value.length }, selectedProjectsIds.value.length),
+ descriptionText: t("deleteModal.warning"),
+ });
+ if (!res) return;
+
+ projectStore.remove(selectedProjectsIds.value);
+ selectedProjectsIds.value = [];
+
+ return;
+ }
+
+ const draft = hoveredProjectId.value
+ ? projectStore.getOne(hoveredProjectId.value)
+ : null;
+ if (!draft) return;
+
const res = await deleteModalStore.use({
- titleText: `Are you sure you want to delete ${selectedProjectsIds.value.length} drafts?`,
- descriptionText:
- "Delete would be permanent, you can’t restore projects later.",
+ titleText: t("deleteModal.spesificDelete", { title: draft.title }),
+ descriptionText: t("deleteModal.warning"),
});
- if (!res) return;
- projectStore.remove(selectedProjectsIds.value);
- selectedProjectsIds.value = [];
-
- return;
- }
-
- const draft = hoveredProjectId.value
- ? projectStore.getOne(hoveredProjectId.value)
- : null;
- if (!draft) return;
-
- const res = await deleteModalStore.use({
- titleText: `Are you sure you want to delete “${draft.title}”?`,
- descriptionText:
- "Delete would be permanent, you can’t restore project later.",
- });
-
- res && projectStore.remove(draft.id);
+ res && projectStore.remove(draft.id);
}
const contextMenuOpen = ref(false);
@@ -151,88 +183,63 @@ const clickY = ref(0);
const clickX = ref(0);
function onOpenContextMenu(evt: MouseEvent) {
- clickX.value = evt.clientX;
- clickY.value = evt.clientY;
+ clickX.value = evt.clientX;
+ clickY.value = evt.clientY;
- contextMenuOpen.value = true;
- setScrolling(false);
+ contextMenuOpen.value = true;
+ setScrolling(false);
}
function onListLeave() {
- if (!contextMenuOpen.value) {
- hoveredProjectId.value = null;
- }
+ if (!contextMenuOpen.value) {
+ hoveredProjectId.value = null;
+ }
}
function onSelectOption(action: string) {
- if (action === "stat") {
- onSetStatus();
- } else if (action === "del") {
- removeProject();
- }
+ if (action === "stat") {
+ onSetStatus();
+ } else if (action === "del") {
+ removeProject();
+ }
- contextMenuOpen.value = false;
+ contextMenuOpen.value = false;
}
-
-
-
Projects
-
- New project +
-
+
+
+
{{ t("title") }}
+
+ {{ t("create") }} +
+
+
+
+
+ {{ t("column.title") }}
+
+
+ {{ t("column.status") }}
+
+
+
-
-
- Title
-
-
- Status
-
-
-
-
-
-
-
-
+
+
+
+
@store/select-modal