From a53878ab3176e06617f4665039ec163a0a60d56c Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 27 Sep 2020 01:03:55 +0200 Subject: [PATCH 001/131] feat: add new productivity tips --- src/index.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/index.html b/src/index.html index b0cfc35dc..8e75a0ea6 100644 --- a/src/index.html +++ b/src/index.html @@ -190,7 +190,13 @@ TODO configure more restrictive Content-Security-Policy ['Mess creates stress', 'Clean up your desk!'], ['Focus on a single task', 'Multi-tasking is the worst.'], ['Set your goals', 'Having a goal to aim for (or even some smaller ones) increases motivation and focus. Remind yourself why you are doing something.'], - ['Try to get it right the first time', 'This can help you to avoid dragging a task on forever.'] + ['Try to get it right the first time', 'This can help you to avoid dragging a task on forever.'], + ['We are what we repeatedly do.', 'Excellence, then, is not an act, but a habit. - Aristotle'], + ['You don’t learn to walk by following rules.', 'You learn by doing, and by falling over. - Richard Branson'], + ['A problem well-put is half-solved', '- John Dewey'], + ['Wisdom is learning what to overlook', '- William James'], + ['It is not that I’m so smart', 'But I stay with the questions much longer - Albert Einstein'], + ['No problem can withstand the assault of sustained thinking', '- Voltaire'], ]; var randomIndex = Math.floor(Math.random() * productivityTips.length); document.getElementById('heading').innerText = productivityTips[randomIndex][0]; From a8d371ed53552c3e354d4bfa9bcc839d15f3856b Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 27 Sep 2020 16:54:48 +0200 Subject: [PATCH 002/131] fix: lint error --- src/app/imex/sync/is-valid-app-data.util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/imex/sync/is-valid-app-data.util.ts b/src/app/imex/sync/is-valid-app-data.util.ts index ab084bb41..89e544d33 100644 --- a/src/app/imex/sync/is-valid-app-data.util.ts +++ b/src/app/imex/sync/is-valid-app-data.util.ts @@ -103,7 +103,7 @@ const _isEntityStatesConsistent = (data: AppDataComplete): boolean => { || projectStateKeys.find(projectModelKey => { const dataForProjects = data[projectModelKey]; - if (typeof dataForProjects !== 'object') { + if (typeof (dataForProjects as any) !== 'object') { throw new Error('No dataForProjects'); } return Object.keys(dataForProjects).find(projectId => From 7a7cabbb959e5e4dbe0e7e843cd974c75a0b9b02 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 28 Sep 2020 18:41:15 +0200 Subject: [PATCH 003/131] chore: update win store release flow --- .gitignore | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 59f8a89ab..42d8fcef8 100644 --- a/.gitignore +++ b/.gitignore @@ -56,4 +56,5 @@ electron/**/*.js.map all-certs.p12 mac-cert.tar build/electron-builder.appx.yaml +electron-builder.win-store.yaml diff --git a/package.json b/package.json index dbe2285b0..28ea2134e 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "dist:win": "yarn buildAllElectron:noTests && electron-builder --win", "dist:win:only": "electron-builder --win", "dist:win:appx": "yarn buildAllElectron:prod && electron-builder --win --config=build/electron-builder.appx.yaml", - "dist:win:store": "git stash && git pull && yarn && git stash pop && yarn dist:win", + "dist:win:store": "git pull && yarn && copy electron-builder.win-store.yaml electron-builder.yaml && yarn dist:win && git checkout electron-builder.yaml || git checkout electron-builder.yaml", "dist:mac:dl": "cp dl.provisionprofile embedded.provisionprofile && electron-builder --mac", "dist:mac:mas": "cp mas.provisionprofile embedded.provisionprofile; electron-builder --mac mas --config=build/electron-builder.mas.yaml", "dist:mac:mas:dev": "cp mas-dev.provisionprofile embedded.provisionprofile; electron-builder --mac mas-dev --config=build/electron-builder.mas-dev.yaml", From ab121111d27bd9b96bb98f97c0d6d34f21dc7be4 Mon Sep 17 00:00:00 2001 From: icr1001 Date: Wed, 30 Sep 2020 01:34:14 +0800 Subject: [PATCH 004/131] Improve spanish translation --- src/assets/i18n/es.json | 178 +++++++++++++++++++++------------------- 1 file changed, 92 insertions(+), 86 deletions(-) diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index 12c3082cb..7e1f9a00f 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -2,15 +2,15 @@ "APP": { "B_INSTALL": { "IGNORE": "Ignorar", - "INSTALL": "instalar", - "MSG": "¿Desea instalar Super Productividad como PWA?" + "INSTALL": "Instalar", + "MSG": "¿Deseas instalar Super Productivity como una PWA?" }, - "B_OFFLINE": "Estás desconectado de internet. Sincronizar y solicitar datos del proveedor de problemas no funcionará.", + "B_OFFLINE": "Estás desconectado de internet. La sincronización y solicitud de datos del proveedor no funcionarán.", "D_INITIAL": { "TITLE": "Bienvenido a v{{nr}}" }, - "UPDATE_MAIN_MODEL": "¡Super Productivity ha recibido una actualización importante! Se requieren algunas migraciones para sus datos. Tenga en cuenta que esto hace que sus datos sean incompatibles con versiones anteriores de la aplicación.", - "UPDATE_MAIN_MODEL_NO_UPDATE": "No se eligió ninguna actualización del modelo. Tenga en cuenta que, si no desea realizar la actualización del modelo, debe bajar a la última versión.", + "UPDATE_MAIN_MODEL": "¡Super Productivity ha recibido una actualización importante! Se requieren algunas migraciones de tus datos. Ten en cuenta que esto hace que tus datos sean incompatibles con versiones anteriores de la aplicación.", + "UPDATE_MAIN_MODEL_NO_UPDATE": "No se eligió ninguna actualización del modelo. Ten en cuenta que, si no deseas realizar la actualización del modelo, debes descargar la última versión.", "UPDATE_WEB_APP": "Nueva versión disponible. ¿Cargar nueva versión?" }, "BL": { @@ -23,21 +23,21 @@ "DATETIME_SCHEDULE": { "LATER_TODAY": "Mas tarde, hoy", "NEXT_WEEK": "La próxima semana", - "PLACEHOLDER": "Por favor seleccione una fecha", - "PRESS_ENTER_AGAIN": "Presione enter nuevamente para guardar", + "PLACEHOLDER": "Selecciona una fecha", + "PRESS_ENTER_AGAIN": "Presiona enter nuevamente para guardar", "TOMORROW": "mañana" }, "F": { "ATTACHMENT": { "DIALOG_EDIT": { - "ADD_ATTACHMENT": "Añadir un adjunto", + "ADD_ATTACHMENT": "Agregar un adjunto", "EDIT_ATTACHMENT": "Editar adjunto", "LABELS": { "FILE": "Ruta de archivo", "IMG": "Imagen", "LINK": "Url" }, - "SELECT_TYPE": "Seleccione un tipo", + "SELECT_TYPE": "Selecciona un tipo", "TYPES": { "FILE": "Archivo (abierto por la aplicación predeterminada del sistema)", "IMG": "Imagen (mostrada como miniatura)", @@ -47,13 +47,13 @@ }, "BOOKMARK": { "BAR": { - "ADD": "Añadir marcador", + "ADD": "Agregar marcador", "DROP": "Suelta aquí para agregar un marcador", "EDIT": "Editar marcadores", "NO_BOOKMARKS": "No tienes marcadores de proyectos. Agregue una a través de arrastrar y soltar o haciendo clic en el ícono ''." }, "DIALOG_EDIT": { - "ADD_BOOKMARK": "Añadir marcador", + "ADD_BOOKMARK": "Agregar marcador", "EDIT_BOOKMARK": "Editar marcador", "LABELS": { "COMMAND": "Comando", @@ -61,8 +61,8 @@ "IMG": "Imagen", "LINK": "Url" }, - "SELECT_ICON": "Seleccione un ícono", - "SELECT_TYPE": "Seleccione un tipo", + "SELECT_ICON": "Selecciona un ícono", + "SELECT_TYPE": "Selecciona un tipo", "TYPES": { "COMMAND": "Comando (comando shell personalizado)", "FILE": "Archivo (abierto por la aplicación predeterminada del sistema)", @@ -97,7 +97,7 @@ }, "FORM": { "B_GENERATE_TOKEN": "Generar token", - "FOLLOW_LINK": "Abra el siguiente enlace y copie el código de autenticación proporcionado allí en el campo de entrada.", + "FOLLOW_LINK": "Abre el siguiente enlace y copia el código de autenticación proporcionado allí en el campo de entrada.", "L_ACCESS_TOKEN": "Token de acceso (generado a partir del código de autenticación)", "L_AUTH_CODE": "código de autenticación", "L_ENABLE_SYNCING": "Habilitar sincronización de Dropbox", @@ -232,7 +232,7 @@ "ERROR": "Google Drive - Error:", "ERROR_INITIAL_IMPORT": "Google Drive: error al intentar importar datos inicialmente", "LOCAL_UP_TO_DATE": "Google Drive: datos locales ya actualizados", - "MULTIPLE_SYNC_FILES_WITH_SAME_NAME": "Se encontraron varios archivos con el nombre \"{{newFileName}}\". Por favor, elimine todos menos uno o elija un nombre diferente.", + "MULTIPLE_SYNC_FILES_WITH_SAME_NAME": "Se encontraron varios archivos con el nombre \"{{newFileName}}\". Elimine todos menos uno o elija un nombre diferente.", "NO_UPDATE_REQUIRED": "Google Drive: No se requiere actualización", "REMOTE_UP_TO_DATE": "Google Drive: datos remotos ya actualizados", "SUCCESS": "Google Drive: Copia de seguridad guardada con éxito", @@ -260,7 +260,7 @@ }, "JIRA": { "BANNER": { - "BLOCK_ACCESS_MSG": "Jira: Para evitar el cierre de api, Super Productividad ha bloqueado el acceso. ¡Probablemente deberías revisar tu configuración de jira!", + "BLOCK_ACCESS_MSG": "Jira: Para evitar el cierre de api, Super Productivity ha bloqueado el acceso. ¡Probablemente deberías revisar tu configuración de jira!", "BLOCK_ACCESS_UNBLOCK": "Desbloquear" }, "CFG_CMP": { @@ -285,7 +285,7 @@ "TITLE": "Configurar Jira para Proyecto" }, "DIALOG_TRANSITION": { - "CHOOSE_STATUS": "Elija estado para asignar", + "CHOOSE_STATUS": "Elija estado a asignar", "CURRENT_ASSIGNEE": "Asignado actual:", "CURRENT_STATUS": "Estado actual:", "TITLE": "Jira: Estado de actualización", @@ -293,7 +293,7 @@ }, "DIALOG_WORKLOG": { "CURRENTLY_LOGGED": "Tiempo registrado actualmente:", - "INVALID_DATE": "El valor introducido no es una fecha!", + "INVALID_DATE": "¡El valor introducido no es una fecha!", "SAVE_WORKLOG": "Guardar registro de trabajo", "STARTED": "Empezado", "SUBMIT_WORKLOG_FOR": "Enviar un registro de trabajo a Jira para", @@ -304,12 +304,12 @@ "IS_AUTO_ADD_TO_BACKLOG": "Agregar automáticamente problemas sin resolver desde Github al registro de trabajo", "IS_AUTO_POLL": "Comprobar automáticamente los problemas de git importados por cambios", "IS_SEARCH_ISSUES_FROM_GITHUB": "Mostrar problemas de git como sugerencias al agregar nuevas tareas", - "REPO": "\"username / repositoryName\" para el repositorio de git que desee seguir" + "REPO": "\"username/repositoryName\" para el repositorio de git que desee seguir" }, "FORM_ADV": { "AUTO_ADD_BACKLOG_JQL_QUERY": "JQL usado para agregar tareas automáticamente al registro de trabajo", "IS_ADD_WORKLOG_ON_SUB_TASK_DONE": "Abrir el cuadro de diálogo para enviar el registro de trabajo a jira cuando se realiza la subtarea", - "IS_AUTO_ADD_TO_BACKLOG": "Añadir automáticamente problemas al registro de trabajo de Jira", + "IS_AUTO_ADD_TO_BACKLOG": "Agregar automáticamente problemas al registro de trabajo de Jira", "IS_AUTO_POLL_TICKETS": "Verifica automáticamente los problemas importados por cambios y notifica", "IS_CHECK_TO_RE_ASSIGN_TICKET_ON_TASK_START": "Compruebe si el problema actualmente trabajado está asignado al usuario actual", "IS_WORKLOG_ENABLED": "Abrir el cuadro de diálogo para enviar el registro de trabajo a jira cuando se realiza la tarea", @@ -358,7 +358,7 @@ }, "S": { "ADDED_WORKLOG_FOR": "Jira: Registro de trabajo agregado para {{issueKey}}", - "EXTENSION_NOT_LOADED": "Extensión de Super Productividad no cargada. Recargar la página podría ayudar", + "EXTENSION_NOT_LOADED": "Extensión de Super Productivity no cargada. Recargar la página podría ayudar", "IMPORTED_MULTIPLE_ISSUES": "Jira: Importó {{issuesLength}} problemas nuevos de jira al registro de trabajo", "IMPORTED_SINGLE_ISSUE": "Jira: problema importado \"{{issueText}}\" de jira al registro de trabajo", "INSUFFICIENT_SETTINGS": "Ajustes insuficientes proporcionados para Jira", @@ -373,14 +373,14 @@ "TRANSITION": "Jira: establece el problema \"{{issueKey}}\" en \"{{name}}\"", "TRANSITIONS_LOADED": "Jira: Transiciones cargadas. Usa las selecciones de abajo para asignarlas.", "TRANSITION_SUCCESS": "Jira: establece el problema {{issueKey}} a {{chosenTransition}}", - "UNABLE_TO_REASSIGN": "Jira: No se puede reasignar el ticket a ti mismo, porque no especificaste un nombre de usuario. Por favor, visite los ajustes." + "UNABLE_TO_REASSIGN": "Jira: No se puede reasignar el ticket a ti mismo, porque no especificaste un nombre de usuario. Visite los ajustes." }, "STEPPER": { "CREDENTIALS": "Credenciales", "DONE": "Ya has terminado.", "LOGIN_SUCCESS": "¡Inicio de sesión exitoso!", "TEST_CREDENTIALS": "Credenciales de prueba", - "WELCOME_USER": "Bienvenido {{user}}!" + "WELCOME_USER": "¡Bienvenido {{user}}!" } }, "METRIC": { @@ -399,12 +399,12 @@ "MOOD_PRODUCTIVITY_OVER_TIME": "Estado de ánimo y productividad a lo largo del tiempo.", "NO_ADDITIONAL_DATA_YET": "No se han recopilado datos adicionales todavía. Use el formulario en el resumen diario \"Evaluación\" del panel para hacerlo.", "OBSTRUCTION_SELECTION_COUNT": "Número de veces que se seleccionó un factor de obstrucción", - "TASKS_DONE_CREATED": "Tareas (realizada / creada)", + "TASKS_DONE_CREATED": "Tareas (realizada/creada)", "TIME_ESTIMATED": "Tiempo estimado", "TIME_SPENT": "Tiempo empleado" }, "EVAL_FORM": { - "ADD_NOTE_FOR_TOMORROW": "Añadir nota para mañana", + "ADD_NOTE_FOR_TOMORROW": "Agregar nota para mañana", "DISABLE_REPEAT_EVERY_DAY": "Desactivar repetir todos los días", "ENABLE_REPEAT_EVERY_DAY": "Repite todos los dias", "HELP_H1": "¿Por qué debería importarme?", @@ -442,7 +442,7 @@ "EDIT_FULLSCREEN": "Editar en pantalla completa", "EDIT_REMINDER": "Editar recordatorio", "NOTES_CMP": { - "ADD_BTN": "Añadir nueva nota", + "ADD_BTN": "Agregar nueva nota", "DROP_TO_ADD": "Suelta aquí para agregar una nueva nota" }, "NOTE_CMP": { @@ -459,7 +459,7 @@ }, "POMODORO": { "BACK_TO_WORK": "¡Volver al trabajo!", - "BREAK_IS_DONE": "Tu descanso ha terminado!", + "BREAK_IS_DONE": "!Tu descanso ha terminado!", "ENJOY_YOURSELF": "Diviértete, muévete, vuelve en:", "FINISH_SESSION_X": "¡Has completado exitosamente la sesión {{nr}}!", "NOTIFICATION": { @@ -492,7 +492,7 @@ "TITLE": "Curiosidad" }, "H1": "¡Relájate un poco!", - "P1": "Primero que nada, a relajarse! Todo el mundo lo hace de vez en cuando. Y si no estás haciendo lo que debes, ¡al menos deberías disfrutarlo! Entonces revisa las secciones de abajo para algo útil.", + "P1": "!Primero que nada, a relajarse! Todo el mundo lo hace de vez en cuando. Y si no estás haciendo lo que debes, ¡al menos deberías disfrutarlo! Entonces revisa las secciones de abajo para algo útil.", "P2": "Si desea saber más sobre la ciencia detrás de todo esto, puedo recomendar este artículo , en el cual se encuentran algunos de los ejercicios.", "P3": "Recuerde: la procrastinación es un problema de regulación emocional, no un problema de gestión del tiempo.", "REFRAME": { @@ -560,7 +560,7 @@ "TITLE": "Editar contador simple" }, "FORM": { - "ADD_NEW": "Añadir contador simple", + "ADD_NEW": "Agregar contador simple", "HELP": "Aquí puede configurar botones simples que aparecerán en la esquina superior derecha. Pueden ser temporizadores o simplemente un contador simple, que se cuenta, haciendo clic en él.", "L_AUTO_COUNT_UP": "El gatillo automático cuenta para", "L_AUTO_SWITCH_OFF": "Disparador automático apagado para", @@ -600,8 +600,8 @@ }, "TASK": { "ADDITIONAL_INFO": { - "ADD_ATTACHMENT": "Añadir un adjunto", - "ADD_SUB_TASK": "Añadir sub tarea", + "ADD_ATTACHMENT": "Agregar un adjunto", + "ADD_SUB_TASK": "Agregar subtarea", "ATTACHMENTS": "Adjuntos {{nr}}", "FROM_PARENT": "(del padre)", "LOCAL_ATTACHMENTS": "Adjuntos locales", @@ -619,15 +619,15 @@ "ADD_TASK": "Agregar tarea", "ADD_TASK_TO_BACKLOG": "Agregar tarea al registro de trabajo", "CREATE_TASK": "Crear nueva tarea", - "EXAMPLE": "Ejemplo: \"Un título de tarea + nombre de proyecto # alguna etiqueta # alguna otra etiqueta 10m / 3h\"", + "EXAMPLE": "Ejemplo: \"Título de tarea + nombre de proyecto #una etiqueta #otra etiqueta 10m/3h\"", "START": "Presiona entrar una vez más para comenzar" }, "B": { - "ADD_HALF_HOUR": "Añadir 1/2 hora", + "ADD_HALF_HOUR": "Agregar 1/2 hora", "ESTIMATE_EXCEEDED": "Tiempo estimado superado para \"{{title}}\"" }, "CMP": { - "ADD_SUB_TASK": "Añadir subtarea", + "ADD_SUB_TASK": "Agregar subtarea", "ADD_TO_MY_DAY": "Agregar a mi día", "ADD_TO_PROJECT": "Agregar a un proyecto", "CONVERT_TO_PARENT_TASK": "Convertir a tarea principal", @@ -647,8 +647,8 @@ "REPEAT_EDIT": "Editar Repetir Tarea Config.", "SCHEDULE": "Programar tarea", "SHOW_UPDATES": "Mostrar actualizaciones", - "TOGGLE_ADDITIONAL": "Mostrar / Ocultar información adicional", - "TOGGLE_ATTACHMENTS": "Mostrar / Ocultar archivos adjuntos", + "TOGGLE_ADDITIONAL": "Mostrar/Ocultar información adicional", + "TOGGLE_ATTACHMENTS": "Mostrar/Ocultar archivos adjuntos", "TOGGLE_DONE": "Marcar como realizada / no realizada", "TOGGLE_SUB_TASK_VISIBILITY": "Alternar visibilidad de subtareas", "TRACK_TIME": "Comenzar el tiempo de seguimiento", @@ -663,8 +663,8 @@ "UNSCHEDULE": "Desprogramar" }, "D_REMINDER_VIEW": { - "ADD_ALL_TO_TODAY": "Agrega todo a hoy", - "ADD_TO_TODAY": "Añadir a hoy", + "ADD_ALL_TO_TODAY": "Agregar todo a hoy", + "ADD_TO_TODAY": "Agregar a hoy", "DISMISS": "Descartar recordatorio", "DISMISS_ALL": "Descartar todo", "DUE_TASK": "Tarea debida", @@ -680,7 +680,7 @@ "SWITCH_CONTEXT_START": "Cambiar contexto e inicio" }, "D_TIME": { - "ADD_FOR_OTHER_DAY": "Añadir tiempo empleado para otro día", + "ADD_FOR_OTHER_DAY": "Agregar tiempo empleado para otro día", "DELETE_FOR": "Borrar entrada por dia", "ESTIMATE": "Estimado", "TIME_SPENT": "Tiempo empleado", @@ -688,14 +688,14 @@ "TITLE": "Tiempo empleado / Estimaciones" }, "D_TIME_FOR_DAY": { - "ADD_ENTRY_FOR": "Añadir nueva entrada para {{date}}", + "ADD_ENTRY_FOR": "Agregar nueva entrada para {{date}}", "DATE": "Fecha para la nueva entrada", "HELP": "Ejemplos:
30m => 30 minutos
2h => 2 horas
2h 30m => 2 horas y 30 minutos", "TINE_SPENT": "Tiempo empleado", - "TITLE": "Añadir para el día" + "TITLE": "Agregar para el día" }, "N": { - "ESTIMATE_EXCEEDED": "Tiempo estimado superado!", + "ESTIMATE_EXCEEDED": "!Tiempo estimado superado!", "ESTIMATE_EXCEEDED_BODY": "Has excedido tu tiempo estimado para \"{{title}}\"." }, "S": { @@ -724,7 +724,7 @@ "OK": "Quitar completamente" }, "D_EDIT": { - "ADD": "Añadir Repetir configuración de tarea", + "ADD": "Agregar Repetir configuración de tarea", "EDIT": "Editar Repetir Tarea Config.", "HELP1": "Las tareas repetitivas están destinadas a las tareas diarias, por ejemplo, \"Organización\", \"Reunión diaria\", \"Revisión de código\", \"Comprobación de correos electrónicos\" o tareas similares que pueden ocurrir una y otra vez.", "HELP2": "Una vez configurada, se volverá a crear una tarea repetitiva en cada día seleccionado a continuación tan pronto como abra su proyecto y se marcará automáticamente como finalizada al final del día. Serán manejados como diferentes instancias. Así que puedes agregar libremente subtareas, etc.", @@ -774,7 +774,7 @@ "D_EXPORT_TITLE": "Exportar registro de trabajo {{start}}-{{end}}", "D_EXPORT_TITLE_SINGLE": "Exportar registro de trabajo {{day}}", "EXPORT": { - "ADD_COL": "Añadir columna", + "ADD_COL": "Agregar columna", "COPY_TO_CLIPBOARD": "Copiar al portapapeles", "DONT_ROUND": "no redondear", "EDIT_COL": "Editar columna", @@ -871,42 +871,42 @@ "TITLE": "Importación y exportación" }, "KEYBOARD": { - "ADD_NEW_NOTE": "Añadir nueva nota", + "ADD_NEW_NOTE": "Agregar nueva nota", "ADD_NEW_TASK": "Agregar nueva tarea", - "APP_WIDE_SHORTCUTS": "Accesos directos globales (en toda la aplicación)", + "APP_WIDE_SHORTCUTS": "Atajos globales (en toda la aplicación)", "COLLAPSE_SUB_TASKS": "Contraer subtareas", "EXPAND_SUB_TASKS": "Expandir subtareas", - "GLOBAL_ADD_NOTE": "Añadir nueva nota", + "GLOBAL_ADD_NOTE": "Agregar nueva nota", "GLOBAL_ADD_TASK": "Agregar nueva tarea", - "GLOBAL_SHOW_HIDE": "Mostrar / Ocultar Super Productividad", + "GLOBAL_SHOW_HIDE": "Mostrar/Ocultar Super Productivity", "GLOBAL_TOGGLE_TASK_START": "Alternar el seguimiento de tiempo para la última tarea activa", "GO_TO_DAILY_AGENDA": "Ir a Agenda", "GO_TO_FOCUS_MODE": "Ir al Modo de Enfoque", "GO_TO_SETTINGS": "Ir a Ajustes", "GO_TO_WORK_VIEW": "Ir a la Vista de Trabajo", - "HELP": "

Aquí puedes configurar todos los atajos del teclado.

Haga clic en la entrada de texto e ingrese la combinación de teclas deseada. Pulsa Enter para guardar y Escape para abortar.

Hay tres tipos de accesos directos:

  • Atajos globales: Cuando la aplicación se está ejecutando, se activará la acción desde cualquier otra aplicación.
  • Atajos de nivel de aplicación: Se activará desde todas las pantallas de la aplicación, pero no si está editando un campo de texto.
  • Atajos de nivel de tarea: Solo se activarán si ha seleccionado una tarea mediante el mouse o el teclado y, por lo general, activará una acción relacionada específicamente con esa tarea.
", + "HELP": "

Aquí puedes configurar todos los atajos del teclado.

Haga clic en la entrada de texto e ingrese la combinación de teclas deseada. Pulsa Enter para guardar y Escape para abortar.

Hay tres tipos de atajos:

  • Atajos globales: Cuando la aplicación se está ejecutando, se activará la acción desde cualquier otra aplicación.
  • Atajos de nivel de aplicación: Se activará desde todas las pantallas de la aplicación, pero no si está editando un campo de texto.
  • Atajos de nivel de tarea: Solo se activarán si ha seleccionado una tarea mediante el mouse o el teclado y, por lo general, activará una acción relacionada específicamente con esa tarea.
", "MOVE_TASK_DOWN": "Mueve la tarea hacia abajo en la lista", "MOVE_TASK_UP": "Mover la tarea hacia arriba en la lista", "MOVE_TO_BACKLOG": "Mover la tarea al registro de trabajo", "MOVE_TO_TODAYS_TASKS": "Mueve la tarea a la lista de tareas de hoy", - "OPEN_PROJECT_NOTES": "Mostrar / Ocultar Notas del Proyecto", + "OPEN_PROJECT_NOTES": "Mostrar/Ocultar Notas del Proyecto", "SELECT_NEXT_TASK": "Seleccionar tarea siguiente", "SELECT_PREVIOUS_TASK": "Seleccionar tarea previa", "SYSTEM_SHORTCUTS": "Atajos globales (en todo el sistema)", - "TASK_ADD_SUB_TASK": "Añadir subtarea", + "TASK_ADD_SUB_TASK": "Agregar subtarea", "TASK_DELETE": "Eliminar tarea", "TASK_EDIT_TITLE": "Editar Título", "TASK_MOVE_TO_PROJECT": "Abrir mover tarea al menú del proyecto", "TASK_OPEN_ESTIMATION_DIALOG": "Editar estimación / tiempo empleado", "TASK_SCHEDULE": "Programar tarea", "TASK_SHORTCUTS": "Tareas", - "TASK_SHORTCUTS_INFO": "Los siguientes atajos se aplican a la tarea seleccionada actualmente (seleccionada mediante una pestaña o un mouse).", - "TASK_TOGGLE_ADDITIONAL_INFO_OPEN": "Mostrar / Ocultar información adicional de la tarea", + "TASK_SHORTCUTS_INFO": "Los siguientes atajos se aplican a la tarea seleccionada actual (seleccionada a través de una pestaña o con el ratón).", + "TASK_TOGGLE_ADDITIONAL_INFO_OPEN": "Mostrar/Ocultar información adicional de la tarea", "TASK_TOGGLE_DONE": "Altenado realizado", "TITLE": "Atajos de teclado", - "TOGGLE_BACKLOG": "Mostrar / Ocultar registro de la tarea", - "TOGGLE_BOOKMARKS": "Mostrar / Ocultar barra de marcadores", - "TOGGLE_PLAY": "Iniciar / detener tarea", + "TOGGLE_BACKLOG": "Mostrar/Ocultar registro de la tarea", + "TOGGLE_BOOKMARKS": "Mostrar/Ocultar barra de marcadores", + "TOGGLE_PLAY": "Iniciar/Detener tarea", "ZOOM_DEFAULT": "Valor predeterminado de zoom (solo para escritorio)", "ZOOM_IN": "Acercar (solo para escritorio)", "ZOOM_OUT": "Alejar (solo para escritorio)" @@ -918,30 +918,30 @@ "ES": "Español", "FA": "Farsi", "FR": "Francés", - "IT": "italiano", + "IT": "Italiano", "JA": "Japonés", "KO": "Coreano", - "LABEL": "Por favor, seleccione un idioma", + "LABEL": "Selecciona un idioma", "NL": "Holandés", - "PT": "portugués", + "PT": "Portugués", "RU": "Ruso", "TITLE": "Idioma", "TR": "Turco", "ZH": "Chino" }, "MISC": { - "DEFAULT_PROJECT": "Proyecto predeterminado para usar para tareas si no se especifica ninguno", - "HELP": "

¿No ve las notificaciones de escritorio? Para Windows, es posible que desee revisar Sistema> Notificaciones y acciones y verificar si se han habilitado las notificaciones requeridas.

", - "IS_AUTO_ADD_WORKED_ON_TO_TODAY": "Agregue automáticamente la etiqueta de hoy a las tareas trabajadas", - "IS_AUTO_MARK_PARENT_AS_DONE": "Marque la tarea principal como realizada, cuando todas las subtareas estén listas", - "IS_AUTO_START_NEXT_TASK": "Comience a rastrear la siguiente tarea cuando marque actual como hecha", + "DEFAULT_PROJECT": "Proyecto predeterminado a usar para las tareas si no se especifica ninguno", + "HELP": "

¿No se ven las notificaciones de escritorio? En Windows, puedes revisar en Sistema> Notificaciones y acciones, y verificar si se han habilitado las notificaciones requeridas.

", + "IS_AUTO_ADD_WORKED_ON_TO_TODAY": "Agregar automáticamente la etiqueta de hoy a las tareas completadas", + "IS_AUTO_MARK_PARENT_AS_DONE": "Marcar la tarea principal como realizada, cuando se completen todas las subtareas", + "IS_AUTO_START_NEXT_TASK": "Comenzar a rastrear la siguiente tarea cuando se marque la tarea actual como completa", "IS_CONFIRM_BEFORE_EXIT": "Confirmar antes de salir de la aplicación", - "IS_DARK_MODE": "Modo oscuro", - "IS_DISABLE_INITIAL_DIALOG": "Deshabilite el diálogo de información inicial (¡podría perderse actualizaciones importantes!)", + "IS_DARK_MODE": "Modo Oscuro", + "IS_DISABLE_INITIAL_DIALOG": "Deshabilitar el diálogo de información inicial (¡podrías perderte actualizaciones importantes!)", "IS_HIDE_NAV": "Ocultar la navegación hasta que se desplace sobre el encabezado principal (solo para escritorio)", - "IS_NOTIFY_WHEN_TIME_ESTIMATE_EXCEEDED": "Notificar cuando se excedió el tiempo estimado", - "IS_TURN_OFF_MARKDOWN": "Desactiva el análisis de descuento para notas", - "TITLE": "Ajustes varios" + "IS_NOTIFY_WHEN_TIME_ESTIMATE_EXCEEDED": "Notificar cuando se excede el tiempo estimado", + "IS_TURN_OFF_MARKDOWN": "Desactivar la sintaxis markdown para las notas", + "TITLE": "Ajustes Variados" }, "POMODORO": { "BREAK_DURATION": "Duración de las pausas breves", @@ -952,16 +952,16 @@ "IS_MANUAL_CONTINUE": "Confirmar manualmente el inicio de la siguiente sesión de pomodoro", "IS_PLAY_SOUND": "Reproducir sonido cuando la sesión haya terminado", "IS_PLAY_SOUND_AFTER_BREAK": "Reproducir sonido cuando el descanso haya terminado", - "IS_PLAY_TICK": "Reproduce el sonido de tick cada segundo", + "IS_PLAY_TICK": "Reproducir el sonido de tick cada segundo", "IS_STOP_TRACKING_ON_BREAK": "Detener el tiempo de seguimiento para la tarea en descanso", "LONGER_BREAK_DURATION": "Duración de los descansos más largos", - "TITLE": "Pomodoro Timer" + "TITLE": "Temporizador Pomodoro" }, "SOUND": { "DONE_SOUND": "Sonido de tarea realizada", "IS_INCREASE_DONE_PITCH": "Aumente el tono para cada tarea realizada", "IS_PLAY_DONE_SOUND": "Reproducir sonido cuando la tarea esté marcada como terminada", - "TITLE": "Sonar", + "TITLE": "Sonido", "VOLUME": "Volumen" }, "TAKE_A_BREAK": { @@ -973,6 +973,12 @@ "MIN_WORKING_TIME": "Mostrar una notificación de descanso después de X tiempo trabajando sin una", "MOTIVATIONAL_IMG": "Imagen motivacional (url web)", "TITLE": "Recordatorio de descanso" + }, + "TRACKING_REMINDER": { + "HELP": "Establecer un recordatorio para que aparezca en caso de que haya olvidado iniciar el seguimiento del tiempo.", + "TITLE": "Recordatorio de Seguimiento de Tiempo", + "L_IS_ENABLED": "Activado", + "L_MIN_TIME": "Tiempo a esperar antes de que se mueste el recordatorio" } }, "GLOBAL_SNACK": { @@ -980,8 +986,8 @@ "ERR_COMPRESSION": "Error para la interfaz de compresión", "PERSISTENCE_DISALLOWED": "Los datos no se conservarán de forma permanente. ¡Tenga en cuenta que esto puede conducir a la pérdida de datos!", "RUNNING_X": "Ejecutando \"{{str}}\".", - "SHORTCUT_WARN_OPEN_BOOKMARKS_FROM_TAG": "{{keyCombo}} presionado, pero el acceso directo a marcadores abiertos solo está disponible en el contexto del proyecto.", - "SHORTCUT_WARN_OPEN_NOTES_FROM_TAG": "{{keyCombo}} presionado, pero el acceso directo de notas abiertas solo está disponible en el contexto del proyecto." + "SHORTCUT_WARN_OPEN_BOOKMARKS_FROM_TAG": "{{keyCombo}} presionado, pero el atajo a marcadores abiertos solo está disponible en el contexto del proyecto.", + "SHORTCUT_WARN_OPEN_NOTES_FROM_TAG": "{{keyCombo}} presionado, pero el atajo de notas abiertas solo está disponible en el contexto del proyecto." }, "GPB": { "ASSETS": "Cargando activos ...", @@ -1012,14 +1018,14 @@ "TAGS": "Etiquetas", "TASKS": "Tareas", "TASK_LIST": "Lista de tareas", - "TOGGLE_SHOW_BOOKMARKS": "Mostrar / Ocultar Marcadores", - "TOGGLE_SHOW_NOTES": "Mostrar / Ocultar Notas del Proyecto", + "TOGGLE_SHOW_BOOKMARKS": "Mostrar/Ocultar Marcadores", + "TOGGLE_SHOW_NOTES": "Mostrar/Ocultar Notas del Proyecto", "TOGGLE_TRACK_TIME": "Iniciar / Detener el tiempo de seguimiento", "WORKLOG": "Registro de trabajo" }, "PDS": { - "BACK": "Espera me olvidé de algo!", - "BREAK_LABEL": "Descansos (nr / tiempo)", + "BACK": "!Espera me olvidé de algo!", + "BREAK_LABEL": "Descansos (nr/tiempo)", "CELEBRATE": "¡Tómate un momento para celebrar !", "CLEAR_ALL_CONTINUE": "Borrar todo listo y continuar", "D_CONFIRM_APP_CLOSE": { @@ -1063,11 +1069,11 @@ "OK": "Archivar" }, "D_CONFIRM_DELETE": { - "MSG": "¿Estás seguro de que quieres eliminar este proyecto? Se recomienda hacer una copia de seguridad de sus datos antes de hacer esto.", + "MSG": "¿Seguro que quieres eliminar este proyecto? Se recomienda hacer una copia de seguridad de sus datos antes de hacer esto.", "OK": "Borrar" }, "D_CONFIRM_UNARCHIVE": { - "MSG": "¿Estás seguro de que quieres desarchivar este proyecto?", + "MSG": "¿Seguro que quieres desarchivar este proyecto?", "OK": "Desarchivar" }, "EDIT_PROJECT": "Editar proyecto", @@ -1084,11 +1090,11 @@ "GLOBAL_SETTINGS": "Ajustes globales", "ISSUE_INTEGRATION": "Integración de problemas", "PRIVATE_POLICY": "Política privada", - "PRODUCTIVITY_HELPER": "Ayudante de productividad", + "PRODUCTIVITY_HELPER": "Ayudante de Productividad", "PROJECT_SETTINGS": "Ajustes Específicos del Proyecto", "SYNC_EXPORT": "Sincronizar y Exportar", "TAG_SETTINGS": "Configuraciones específicas de etiqueta", - "TOGGLE_DARK_MODE": "Cambiar modo oscuro" + "TOGGLE_DARK_MODE": "Cambiar a modo oscuro" }, "S": { "SYNC": { @@ -1103,7 +1109,7 @@ "START_TASK": "Inicie la tarea ahora y elimine el recordatorio" }, "THEMES": { - "SELECT_THEME": "Seleccione el tema", + "SELECT_THEME": "Selecciona el tema", "amber": "Ámbar", "blue": "Azul", "blue-grey": "Gris azulado", @@ -1121,7 +1127,7 @@ "yellow": "Amarillo" }, "V": { - "E_1TO10": "Por favor, introduzca un valor entre 1 y 10", + "E_1TO10": "Ingresa un valor entre 1 y 10", "E_DATETIME": "El valor ingresado no es una fecha y hora!", "E_MAX": "No debe ser más grande que {{val}}", "E_MAX_LENGTH": "Debe tener una longitud máxima de {{val}} caracteres", @@ -1131,12 +1137,12 @@ "E_REQUIRED": "Este campo es requerido" }, "WW": { - "ADD_MORE": "Añadir más", + "ADD_MORE": "Agregar más", "ADD_SOME_TASKS": "¡Agrega algunas tareas para planificar tu día!", "COMPLETED_TASKS": "Tareas completadas", "ESTIMATE_REMAINING": "Estimación restante:", "FINISH_DAY": "Fin de dia", - "HELP_PROCRASTINATION": "Ayuda, estoy procrastinando!", + "HELP_PROCRASTINATION": "Ayuda, !estoy procrastinando!", "NO_COMPLETED_TASKS": "Actualmente no hay tareas completadas.", "NO_PLANNED_TASKS": "No hay tareas planificadas", "READY_TO_WORK": "¡Listo para trabajar!", From c96b846377807441500ea99565106190c8a6a8e3 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Wed, 30 Sep 2020 21:00:05 +0200 Subject: [PATCH 005/131] fix(task): only start first startable when there is none already running --- src/app/features/tasks/task.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/features/tasks/task.service.ts b/src/app/features/tasks/task.service.ts index d854fa88b..a56d6be55 100644 --- a/src/app/features/tasks/task.service.ts +++ b/src/app/features/tasks/task.service.ts @@ -204,7 +204,7 @@ export class TaskService { startFirstStartable() { this._workContextService.startableTasks$.pipe(take(1)).subscribe(tasks => { - if (tasks[0]) { + if (tasks[0] && !this.currentTaskId) { this.setCurrentId(tasks[0].id); } }); From 58be3561c4b1a9695f7bc75b01baf747dc54734a Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Wed, 30 Sep 2020 21:11:06 +0200 Subject: [PATCH 006/131] fix: chrome extension link --- src/assets/i18n/de.json | 2 +- src/assets/i18n/en.json | 2 +- src/assets/i18n/es.json | 2 +- src/assets/i18n/fa.json | 2 +- src/assets/i18n/fr.json | 2 +- src/assets/i18n/it.json | 2 +- src/assets/i18n/ja.json | 2 +- src/assets/i18n/ko.json | 2 +- src/assets/i18n/nl.json | 2 +- src/assets/i18n/pt.json | 2 +- src/assets/i18n/ru.json | 2 +- src/assets/i18n/tr.json | 2 +- src/assets/i18n/zh.json | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index a6c37c187..5f50a4d61 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -826,7 +826,7 @@ "DISMISS": "Verwerfen", "DO_IT": "TU es!", "EDIT": "Bearbeiten", - "EXTENSION_INFO": "Bitte laden Sie die Chrome-Erweiterung herunter, um die Kommunikation mit dem Jira Api und Idle Time Handling zu ermöglichen. Beachten Sie, dass dies für Handys nicht funktioniert.", + "EXTENSION_INFO": "Bitte laden Sie die Chrome-Erweiterung herunter, um die Kommunikation mit dem Jira Api und Idle Time Handling zu ermöglichen. Beachten Sie, dass dies für Handys nicht funktioniert.", "LOGIN": "Anmeldung", "LOGOUT": "Ausloggen", "MINUTES": "{{m}} Minuten", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index bff8a6e35..e4c397417 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -842,7 +842,7 @@ "DISMISS": "Dismiss", "DO_IT": "Do it!", "EDIT": "Edit", - "EXTENSION_INFO": "Please download the chrome extension in order to allow communication with the Jira Api and Idle Time Handling. Note that this doesn't work for mobile.", + "EXTENSION_INFO": "Please download the chrome extension in order to allow communication with the Jira Api and Idle Time Handling. Note that this doesn't work for mobile.", "LOGIN": "Login", "LOGOUT": "Logout", "MINUTES": "{{m}} minutes", diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index 7e1f9a00f..9ffe18730 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -826,7 +826,7 @@ "DISMISS": "Descartar", "DO_IT": "¡Hazlo!", "EDIT": "Editar", - "EXTENSION_INFO": "Por favor descargue la extensión de Chrome para permitir la comunicación con Jira Api y Idle Time Handling. Tenga en cuenta que esto no funciona para móviles.", + "EXTENSION_INFO": "Por favor descargue la extensión de Chrome para permitir la comunicación con Jira Api y Idle Time Handling. Tenga en cuenta que esto no funciona para móviles.", "LOGIN": "Iniciar sesión", "LOGOUT": "Cerrar sesión", "MINUTES": "{{m}} minutos", diff --git a/src/assets/i18n/fa.json b/src/assets/i18n/fa.json index f338e6fed..fb37ba72a 100644 --- a/src/assets/i18n/fa.json +++ b/src/assets/i18n/fa.json @@ -826,7 +826,7 @@ "DISMISS": "رد کردن", "DO_IT": "انجام بدهید!", "EDIT": "ویرایش", - "EXTENSION_INFO": "لطفا برای ارتباط با جیرا و مدیریت زمان افزونه گوگل کروم را دانلود کنید. توجه این افزونه برای نسخه موبایل کروم کار نمی کند.", + "EXTENSION_INFO": "لطفا برای ارتباط با جیرا و مدیریت زمان افزونه گوگل کروم را دانلود کنید. توجه این افزونه برای نسخه موبایل کروم کار نمی کند.", "LOGIN": "وارد شدن", "LOGOUT": "خارج شدن", "MINUTES": "{{m}} دقیقه", diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 178611a2d..3018a74ad 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -826,7 +826,7 @@ "DISMISS": "Rejeter", "DO_IT": "Fais le !", "EDIT": "modifier", - "EXTENSION_INFO": "Veuillez télécharger l'extension chrome afin de permettre la communication avec l'Api Jira et la gestion du temps d'inactivité. Notez que cela ne fonctionne pas sur mobile.", + "EXTENSION_INFO": "Veuillez télécharger l'extension chrome afin de permettre la communication avec l'Api Jira et la gestion du temps d'inactivité. Notez que cela ne fonctionne pas sur mobile.", "LOGIN": "S'identifier", "LOGOUT": "Se déconnecter", "MINUTES": "{{m}} minutes", diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index 6484a93c3..30e0500dc 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -826,7 +826,7 @@ "DISMISS": "Rimuovi", "DO_IT": "Fallo!", "EDIT": "Modifica", - "EXTENSION_INFO": "Per favore scarica l'estensione di chrome per permettere la comunicazione con le api di Jira e la gestione del tempo inattivo. Nota che non funziona su dispositivi mobile.", + "EXTENSION_INFO": "Per favore scarica l'estensione di chrome per permettere la comunicazione con le api di Jira e la gestione del tempo inattivo. Nota che non funziona su dispositivi mobile.", "LOGIN": "Login", "LOGOUT": "Logout", "MINUTES": "{{m}} minuti", diff --git a/src/assets/i18n/ja.json b/src/assets/i18n/ja.json index 89b6e8141..525115add 100644 --- a/src/assets/i18n/ja.json +++ b/src/assets/i18n/ja.json @@ -826,7 +826,7 @@ "DISMISS": "やめる", "DO_IT": "やれ!", "EDIT": "編集", - "EXTENSION_INFO": "Jira ApiおよびIdle Time Handlingとの通信を可能にするために、クロム拡張 をダウンロード してください。これはモバイルでは機能しないことに注意してください。", + "EXTENSION_INFO": "Jira ApiおよびIdle Time Handlingとの通信を可能にするために、クロム拡張 をダウンロード してください。これはモバイルでは機能しないことに注意してください。", "LOGIN": "ログイン", "LOGOUT": "ログアウト", "MINUTES": "{{m}} 分", diff --git a/src/assets/i18n/ko.json b/src/assets/i18n/ko.json index 5101d147f..80cb35951 100644 --- a/src/assets/i18n/ko.json +++ b/src/assets/i18n/ko.json @@ -826,7 +826,7 @@ "DISMISS": "버리다", "DO_IT": "해!", "EDIT": "편집하다", - "EXTENSION_INFO": "Jira Api 및 Idle Time Handling과의 통신을 허용하려면 크롬 확장 을 다운로드하십시오. 이 기능은 모바일에서 작동하지 않습니다.", + "EXTENSION_INFO": "Jira Api 및 Idle Time Handling과의 통신을 허용하려면 크롬 확장 을 다운로드하십시오. 이 기능은 모바일에서 작동하지 않습니다.", "LOGIN": "로그인", "LOGOUT": "로그 아웃", "MINUTES": "{{m}} 분", diff --git a/src/assets/i18n/nl.json b/src/assets/i18n/nl.json index c6f563dd1..93c557b08 100644 --- a/src/assets/i18n/nl.json +++ b/src/assets/i18n/nl.json @@ -826,7 +826,7 @@ "DISMISS": "Afwijzen", "DO_IT": "Doe het!", "EDIT": "Bewerk", - "EXTENSION_INFO": " Download de Chrome-extensie om communicatie met de Jira Api en Idle Time Handling mogelijk te maken. Merk op dat dit niet werkt voor mobiel.", + "EXTENSION_INFO": " Download de Chrome-extensie om communicatie met de Jira Api en Idle Time Handling mogelijk te maken. Merk op dat dit niet werkt voor mobiel.", "LOGIN": "Log in", "LOGOUT": "Uitloggen", "MINUTES": "{{m}} minuten", diff --git a/src/assets/i18n/pt.json b/src/assets/i18n/pt.json index c1ef0dea7..a0a08cb3d 100644 --- a/src/assets/i18n/pt.json +++ b/src/assets/i18n/pt.json @@ -826,7 +826,7 @@ "DISMISS": "Dispensar", "DO_IT": "Fazer isto!", "EDIT": "Editar", - "EXTENSION_INFO": "Por favor faça o download da extensão chrome para permitir a comunicação com o Jira Api e o Idle Time Handling. Observe que isso não funciona para dispositivos móveis.", + "EXTENSION_INFO": "Por favor faça o download da extensão chrome para permitir a comunicação com o Jira Api e o Idle Time Handling. Observe que isso não funciona para dispositivos móveis.", "LOGIN": "Login", "LOGOUT": "Sair", "MINUTES": "{{m}} minutos", diff --git a/src/assets/i18n/ru.json b/src/assets/i18n/ru.json index 173e2678e..fc6daa14a 100644 --- a/src/assets/i18n/ru.json +++ b/src/assets/i18n/ru.json @@ -826,7 +826,7 @@ "DISMISS": "Отклонить", "DO_IT": "Сделай это!", "EDIT": "Редактировать", - "EXTENSION_INFO": "Пожалуйста, загрузите расширение Chrome , чтобы обеспечить связь с Jira Api и Idle Time Handling. Обратите внимание, что это не работает для мобильных устройств.", + "EXTENSION_INFO": "Пожалуйста, загрузите расширение Chrome , чтобы обеспечить связь с Jira Api и Idle Time Handling. Обратите внимание, что это не работает для мобильных устройств.", "LOGIN": "Авторизоваться", "LOGOUT": "Выйти", "MINUTES": "{{m}} минут", diff --git a/src/assets/i18n/tr.json b/src/assets/i18n/tr.json index 6308a2272..23e9f6ef0 100644 --- a/src/assets/i18n/tr.json +++ b/src/assets/i18n/tr.json @@ -826,7 +826,7 @@ "DISMISS": "Reddet", "DO_IT": "Yap!", "EDIT": "Düzenle", - "EXTENSION_INFO": "Jira Api ve Idle Time Handling ile iletişime izin vermek için lütfen krom uzantısını indirin. Bunun mobil cihazlar için işe yaramadığını unutmayın.", + "EXTENSION_INFO": "Jira Api ve Idle Time Handling ile iletişime izin vermek için lütfen krom uzantısını indirin. Bunun mobil cihazlar için işe yaramadığını unutmayın.", "LOGIN": "Oturum aç", "LOGOUT": "Çıkış Yap", "MINUTES": "{{m}} dakika", diff --git a/src/assets/i18n/zh.json b/src/assets/i18n/zh.json index 0c92ed549..0b83f463a 100644 --- a/src/assets/i18n/zh.json +++ b/src/assets/i18n/zh.json @@ -826,7 +826,7 @@ "DISMISS": "取消", "DO_IT": "开始吧!", "EDIT": "编辑", - "EXTENSION_INFO": "请 下载Chrome扩展程序 ,以便与Jira Api和空闲时间处理进行通信。请注意,这不适用于移动设备。", + "EXTENSION_INFO": "请 下载Chrome扩展程序 ,以便与Jira Api和空闲时间处理进行通信。请注意,这不适用于移动设备。", "LOGIN": "登录", "LOGOUT": "登出", "MINUTES": "{{m}} 分钟", From ca7cb4bf5c702664ea83feba9c60265d2ad48b4d Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Wed, 30 Sep 2020 21:32:35 +0200 Subject: [PATCH 007/131] fix(jira): wrong issue link for auto-imported issues #551 --- .../issue/providers/jira/jira-issue/jira-issue-map.util.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/features/issue/providers/jira/jira-issue/jira-issue-map.util.ts b/src/app/features/issue/providers/jira/jira-issue/jira-issue-map.util.ts index 7d2685d53..4d249650c 100644 --- a/src/app/features/issue/providers/jira/jira-issue/jira-issue-map.util.ts +++ b/src/app/features/issue/providers/jira/jira-issue/jira-issue-map.util.ts @@ -23,7 +23,7 @@ export const mapToSearchResults = (res: any): SearchResultItem[] => { issueData: { ...issue, summary: issue.summaryText, - // NOTE THIS + // NOTE: we always use the key, because it allows us to create the right link id: issue.key, }, }; @@ -47,7 +47,8 @@ export const mapIssue = (issue: JiraIssueOriginal, cfg: JiraCfg): JiraIssue => { return { key: issueCopy.key, - id: issueCopy.id, + // NOTE: we always use the key, because it allows us to create the right link + id: issueCopy.key, components: fields.components, timeestimate: fields.timeestimate, timespent: fields.timespent, From d1067019240ce2fba36cb7e978768c5c7e1a3557 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 1 Oct 2020 10:52:45 +0200 Subject: [PATCH 008/131] built: add code analysis --- .github/workflows/codeql-analysis.yml | 71 +++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 000000000..8698521ca --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,71 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +name: "CodeQL" + +on: + push: + branches: [master] + pull_request: + # The branches below must be a subset of the branches above + branches: [master] + schedule: + - cron: '0 3 * * 6' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + # Override automatic language detection by changing the below list + # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] + language: ['javascript'] + # Learn more... + # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + # We must fetch at least the immediate parents so that if this is + # a pull request then we can checkout the head. + fetch-depth: 2 + + # If this run was triggered by a pull request event, then checkout + # the head of the pull request instead of the merge commit. + - run: git checkout HEAD^2 + if: ${{ github.event_name == 'pull_request' }} + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From c9c2e0cad56383fd69f3414d266aec7f6c44189d Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 1 Oct 2020 20:33:02 +0200 Subject: [PATCH 009/131] feat: improve broken data handling #555 --- src/app/core/data-init/data-init.service.ts | 2 +- src/app/core/data-repair/data-repair.service.ts | 11 ++++++++++- src/app/imex/sync/data-import.service.ts | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/app/core/data-init/data-init.service.ts b/src/app/core/data-init/data-init.service.ts index c88c2720c..0f8c369bc 100644 --- a/src/app/core/data-init/data-init.service.ts +++ b/src/app/core/data-init/data-init.service.ts @@ -54,7 +54,7 @@ export class DataInitService { if (isValid) { this._store$.dispatch(loadAllData({appDataComplete, isOmitTokens})); } else { - if (this._dataRepairService.isRepairConfirmed()) { + if (this._dataRepairService.isRepairPossibleAndConfirmed(appDataComplete)) { const fixedData = this._dataRepairService.repairData(appDataComplete); this._store$.dispatch(loadAllData({ appDataComplete: fixedData, diff --git a/src/app/core/data-repair/data-repair.service.ts b/src/app/core/data-repair/data-repair.service.ts index c236e3b1c..6cd306bf3 100644 --- a/src/app/core/data-repair/data-repair.service.ts +++ b/src/app/core/data-repair/data-repair.service.ts @@ -18,7 +18,16 @@ export class DataRepairService { return dataRepair(dataIn); } - isRepairConfirmed(): boolean { + isRepairPossibleAndConfirmed(dataIn: AppDataComplete): boolean { + const isDataRepairPossible: boolean = + typeof dataIn === 'object' && dataIn !== null + && typeof dataIn.task === 'object' && dataIn.task !== null + && typeof dataIn.project === 'object' && dataIn.project !== null + + if (!isDataRepairPossible) { + alert('Data damaged, repair not possible.') + return false; + } return confirm(this._translateService.instant(T.CONFIRM.AUTO_FIX)); } } diff --git a/src/app/imex/sync/data-import.service.ts b/src/app/imex/sync/data-import.service.ts index 749e1434b..f47950dd5 100644 --- a/src/app/imex/sync/data-import.service.ts +++ b/src/app/imex/sync/data-import.service.ts @@ -69,7 +69,7 @@ export class DataImportService { await this._importBackup(); this._imexMetaService.setDataImportInProgress(false); } - } else if (this._dataRepairService.isRepairConfirmed()) { + } else if (this._dataRepairService.isRepairPossibleAndConfirmed(data)) { const fixedData = this._dataRepairService.repairData(data); await this.importCompleteSyncData(fixedData, isBackupReload, true); } else { From 1012edbd42f8bb99217437843e8a455d7b729dfb Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 2 Oct 2020 14:15:37 +0200 Subject: [PATCH 010/131] feat: improve data repair handling #552 --- src/app/core/data-repair/data-repair.service.ts | 10 +++------- src/app/core/data-repair/data-repair.util.ts | 5 +++++ .../core/data-repair/is-data-repair-possible.util.ts | 7 +++++++ 3 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 src/app/core/data-repair/is-data-repair-possible.util.ts diff --git a/src/app/core/data-repair/data-repair.service.ts b/src/app/core/data-repair/data-repair.service.ts index 6cd306bf3..0f27ed53a 100644 --- a/src/app/core/data-repair/data-repair.service.ts +++ b/src/app/core/data-repair/data-repair.service.ts @@ -3,6 +3,7 @@ import { AppDataComplete } from '../../imex/sync/sync.model'; import { T } from '../../t.const'; import { TranslateService } from '@ngx-translate/core'; import { dataRepair } from './data-repair.util'; +import { isDataRepairPossible } from './is-data-repair-possible.util'; @Injectable({ providedIn: 'root' @@ -19,13 +20,8 @@ export class DataRepairService { } isRepairPossibleAndConfirmed(dataIn: AppDataComplete): boolean { - const isDataRepairPossible: boolean = - typeof dataIn === 'object' && dataIn !== null - && typeof dataIn.task === 'object' && dataIn.task !== null - && typeof dataIn.project === 'object' && dataIn.project !== null - - if (!isDataRepairPossible) { - alert('Data damaged, repair not possible.') + if (!isDataRepairPossible(dataIn)) { + alert('Data damaged, repair not possible.'); return false; } return confirm(this._translateService.instant(T.CONFIRM.AUTO_FIX)); diff --git a/src/app/core/data-repair/data-repair.util.ts b/src/app/core/data-repair/data-repair.util.ts index c003bd8b5..2d601f629 100644 --- a/src/app/core/data-repair/data-repair.util.ts +++ b/src/app/core/data-repair/data-repair.util.ts @@ -1,10 +1,15 @@ import { AppBaseDataEntityLikeStates, AppDataComplete } from '../../imex/sync/sync.model'; import { TagCopy } from '../../features/tag/tag.model'; import { ProjectCopy } from '../../features/project/project.model'; +import { isDataRepairPossible } from './is-data-repair-possible.util'; const ENTITY_STATE_KEYS: (keyof AppDataComplete)[] = ['task', 'taskArchive', 'taskRepeatCfg', 'tag', 'project', 'simpleCounter']; export const dataRepair = (data: AppDataComplete): AppDataComplete => { + if (!isDataRepairPossible(data)) { + throw new Error('Data repair attempted but not possible'); + } + // console.time('dataRepair'); let dataOut: AppDataComplete = data; // let dataOut: AppDataComplete = dirtyDeepCopy(data); diff --git a/src/app/core/data-repair/is-data-repair-possible.util.ts b/src/app/core/data-repair/is-data-repair-possible.util.ts new file mode 100644 index 000000000..d4062364a --- /dev/null +++ b/src/app/core/data-repair/is-data-repair-possible.util.ts @@ -0,0 +1,7 @@ +import { AppDataComplete } from '../../imex/sync/sync.model'; + +export const isDataRepairPossible = (data: AppDataComplete): boolean => { + return typeof data === 'object' && data !== null + && typeof data.task === 'object' && data.task !== null + && typeof data.project === 'object' && data.project !== null; +}; From b2b210bfe54c04e92b34b47bc25d1816241d7978 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 2 Oct 2020 14:48:09 +0200 Subject: [PATCH 011/131] feat(startTrackingReminder): hide on mobile per default and make configurable --- src/app/features/config/default-global-config.const.ts | 1 + .../config/form-cfgs/tracking-reminder-form.const.ts | 7 +++++++ src/app/features/config/global-config.model.ts | 1 + .../tracking-reminder/tracking-reminder.service.ts | 3 ++- src/app/t.const.ts | 1 + src/assets/i18n/en.json | 1 + 6 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/app/features/config/default-global-config.const.ts b/src/app/features/config/default-global-config.const.ts index 2b5e14a72..3ed75191c 100644 --- a/src/app/features/config/default-global-config.const.ts +++ b/src/app/features/config/default-global-config.const.ts @@ -115,6 +115,7 @@ export const DEFAULT_GLOBAL_CONFIG: GlobalConfigState = { }, trackingReminder: { isEnabled: true, + isShowOnMobile: false, minTime: minute * 2, } }; diff --git a/src/app/features/config/form-cfgs/tracking-reminder-form.const.ts b/src/app/features/config/form-cfgs/tracking-reminder-form.const.ts index bf082aedd..51a7b1c51 100644 --- a/src/app/features/config/form-cfgs/tracking-reminder-form.const.ts +++ b/src/app/features/config/form-cfgs/tracking-reminder-form.const.ts @@ -14,6 +14,13 @@ export const TRACKING_REMINDER_FORM_CFG: ConfigFormSection; diff --git a/src/app/features/time-tracking/tracking-reminder/tracking-reminder.service.ts b/src/app/features/time-tracking/tracking-reminder/tracking-reminder.service.ts index f871b66b8..a563e5235 100644 --- a/src/app/features/time-tracking/tracking-reminder/tracking-reminder.service.ts +++ b/src/app/features/time-tracking/tracking-reminder/tracking-reminder.service.ts @@ -15,6 +15,7 @@ import { getWorklogStr } from '../../../util/get-work-log-str'; import { T } from '../../../t.const'; import { TranslateService } from '@ngx-translate/core'; import { TrackingReminderConfig } from '../../config/global-config.model'; +import { IS_TOUCH_ONLY } from '../../../util/is-touch'; @Injectable({ providedIn: 'root' @@ -34,7 +35,7 @@ export class TrackingReminderService { ); remindCounter$: Observable = this._cfg$.pipe( - switchMap((cfg) => !cfg.isEnabled + switchMap((cfg) => !cfg.isEnabled || (!cfg.isShowOnMobile && IS_TOUCH_ONLY) ? EMPTY : combineLatest([ this._taskService.currentTaskId$, diff --git a/src/app/t.const.ts b/src/app/t.const.ts index 00398bf9b..b91efb6cd 100644 --- a/src/app/t.const.ts +++ b/src/app/t.const.ts @@ -994,6 +994,7 @@ export const T = { 'HELP': 'GCF.TRACKING_REMINDER.HELP', 'TITLE': 'GCF.TRACKING_REMINDER.TITLE', 'L_IS_ENABLED': 'GCF.TRACKING_REMINDER.L_IS_ENABLED', + 'L_IS_SHOW_ON_MOBILE': 'GCF.TRACKING_REMINDER.L_IS_SHOW_ON_MOBILE', 'L_MIN_TIME': 'GCF.TRACKING_REMINDER.L_MIN_TIME' } }, diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index e4c397417..11445de25 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -994,6 +994,7 @@ "HELP": "Configure a banner to show up in case you forgot to start time tracking.", "TITLE": "Time Tracking Reminder", "L_IS_ENABLED": "Enabled", + "L_IS_SHOW_ON_MOBILE": "Show on mobile app", "L_MIN_TIME": "Time to wait before showing Banner" } }, From a7e41d937655671986d080a62f8f202cedf4a138 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 2 Oct 2020 15:05:19 +0200 Subject: [PATCH 012/131] feat(startTrackingReminder): auto hide on idle and when starting to track on a task manually --- .../tracking-reminder.service.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/app/features/time-tracking/tracking-reminder/tracking-reminder.service.ts b/src/app/features/time-tracking/tracking-reminder/tracking-reminder.service.ts index a563e5235..2dc4dc18b 100644 --- a/src/app/features/time-tracking/tracking-reminder/tracking-reminder.service.ts +++ b/src/app/features/time-tracking/tracking-reminder/tracking-reminder.service.ts @@ -28,12 +28,17 @@ export class TrackingReminderService { _manualReset$: Subject = new Subject(); _resetableCounter$: Observable = merge( - of(true), + of('INITIAL'), this._manualReset$, ).pipe( switchMap(() => this._counter$), ); + _hideTrigger$: Observable = merge( + this._taskService.currentTaskId$.pipe(filter(currentId => !!currentId)), + this._idleService.isIdle$.pipe(filter(isIdle => isIdle)), + ); + remindCounter$: Observable = this._cfg$.pipe( switchMap((cfg) => !cfg.isEnabled || (!cfg.isShowOnMobile && IS_TOUCH_ONLY) ? EMPTY @@ -67,6 +72,14 @@ export class TrackingReminderService { this.remindCounter$.subscribe((count) => { this._triggerBanner(count, {}); }); + + this._hideTrigger$.subscribe((v) => { + this._hideBanner(); + }); + } + + private _hideBanner() { + this._bannerService.dismiss(BannerId.StartTrackingReminder); } private _triggerBanner(duration: number, cfg: any) { From 2c8255b0814e03623048ac52cd960cf7b3710999 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 2 Oct 2020 15:30:22 +0200 Subject: [PATCH 013/131] fix: allow to display images from file system #549 --- electron/main.ts | 7 ++++++- src/index.html | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/electron/main.ts b/electron/main.ts index b30689f50..041150658 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -1,5 +1,5 @@ 'use strict'; -import { App, app, BrowserWindow, globalShortcut, ipcMain, powerMonitor } from 'electron'; +import { App, app, BrowserWindow, globalShortcut, ipcMain, powerMonitor, protocol } from 'electron'; import * as electronDl from 'electron-dl'; import { info } from 'electron-log'; @@ -156,6 +156,11 @@ appIN.on('ready', () => { sendIdleMsgIfOverMin(Date.now() - suspendStart); mainWin.webContents.send(IPC.RESUME); }); + + protocol.registerFileProtocol('file', (request, callback) => { + const pathname = decodeURI(request.url.replace('file:///', '')); + callback(pathname); + }); }); appIN.on('will-quit', () => { diff --git a/src/index.html b/src/index.html index 8e75a0ea6..9b48fcbc0 100644 --- a/src/index.html +++ b/src/index.html @@ -52,7 +52,7 @@ TODO configure more restrictive Content-Security-Policy From b1b87960d7b394784d9bafa92cd84021cec64f7c Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 2 Oct 2020 16:55:10 +0200 Subject: [PATCH 014/131] fix: lint --- src/app/core/data-repair/is-data-repair-possible.util.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/app/core/data-repair/is-data-repair-possible.util.ts b/src/app/core/data-repair/is-data-repair-possible.util.ts index d4062364a..d8f2e9500 100644 --- a/src/app/core/data-repair/is-data-repair-possible.util.ts +++ b/src/app/core/data-repair/is-data-repair-possible.util.ts @@ -1,7 +1,8 @@ import { AppDataComplete } from '../../imex/sync/sync.model'; export const isDataRepairPossible = (data: AppDataComplete): boolean => { - return typeof data === 'object' && data !== null - && typeof data.task === 'object' && data.task !== null - && typeof data.project === 'object' && data.project !== null; + const d: any = data as any; + return typeof d === 'object' && d !== null + && typeof d.task === 'object' && d.task !== null + && typeof d.project === 'object' && d.project !== null; }; From 4a031fa3bc63a1ac2f1536a6901db2825fbc939d Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 2 Oct 2020 17:19:22 +0200 Subject: [PATCH 015/131] 5.9.1 --- CHANGELOG.md | 24 ++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e68cf8a87..d51003ee9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +## [5.9.1](https://github.com/johannesjo/super-productivity/compare/v5.9.0...v5.9.1) (2020-10-02) + + +### Bug Fixes + +* allow to display images from file system [#549](https://github.com/johannesjo/super-productivity/issues/549) ([2c8255b](https://github.com/johannesjo/super-productivity/commit/2c8255b0814e03623048ac52cd960cf7b3710999)) +* chrome extension link ([58be356](https://github.com/johannesjo/super-productivity/commit/58be3561c4b1a9695f7bc75b01baf747dc54734a)) +* lint ([b1b8796](https://github.com/johannesjo/super-productivity/commit/b1b87960d7b394784d9bafa92cd84021cec64f7c)) +* **jira:** wrong issue link for auto-imported issues [#551](https://github.com/johannesjo/super-productivity/issues/551) ([ca7cb4b](https://github.com/johannesjo/super-productivity/commit/ca7cb4bf5c702664ea83feba9c60265d2ad48b4d)) +* **task:** only start first startable when there is none already running ([c96b846](https://github.com/johannesjo/super-productivity/commit/c96b846377807441500ea99565106190c8a6a8e3)) +* lint error ([a8d371e](https://github.com/johannesjo/super-productivity/commit/a8d371ed53552c3e354d4bfa9bcc839d15f3856b)) + + +### Features + +* **startTrackingReminder:** auto hide on idle and when starting to track on a task manually ([a7e41d9](https://github.com/johannesjo/super-productivity/commit/a7e41d937655671986d080a62f8f202cedf4a138)) +* **startTrackingReminder:** hide on mobile per default and make configurable ([b2b210b](https://github.com/johannesjo/super-productivity/commit/b2b210bfe54c04e92b34b47bc25d1816241d7978)) +* add new productivity tips ([a53878a](https://github.com/johannesjo/super-productivity/commit/a53878ab3176e06617f4665039ec163a0a60d56c)) +* improve broken data handling [#555](https://github.com/johannesjo/super-productivity/issues/555) ([c9c2e0c](https://github.com/johannesjo/super-productivity/commit/c9c2e0cad56383fd69f3414d266aec7f6c44189d)) +* improve data repair handling [#552](https://github.com/johannesjo/super-productivity/issues/552) ([1012edb](https://github.com/johannesjo/super-productivity/commit/1012edbd42f8bb99217437843e8a455d7b729dfb)) +* make AppDataForProjects non optional ([8b1a9cf](https://github.com/johannesjo/super-productivity/commit/8b1a9cf79c01f5e876ec2d972e23ecebdac60c0d)) + + + # [5.9.0](https://github.com/johannesjo/super-productivity/compare/v5.8.2...v5.9.0) (2020-09-24) diff --git a/package.json b/package.json index 28ea2134e..2bca22b7c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.0", + "version": "5.9.1", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "johannesjo (http://super-productivity.com)", From 5144d3a093eae2928a3a8c5bb5d654cc63461263 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 2 Oct 2020 20:27:22 +0200 Subject: [PATCH 016/131] 5.9.2 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d51003ee9..9df4c9d0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [5.9.2](https://github.com/johannesjo/super-productivity/compare/v5.9.1...v5.9.2) (2020-10-02) + + + ## [5.9.1](https://github.com/johannesjo/super-productivity/compare/v5.9.0...v5.9.1) (2020-10-02) diff --git a/package.json b/package.json index 2bca22b7c..72a8486e5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.1", + "version": "5.9.2", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "johannesjo (http://super-productivity.com)", From b83bfeafc6fd1c8258da9b7a040815f578d2dbc7 Mon Sep 17 00:00:00 2001 From: Philipp Korn Date: Fri, 2 Oct 2020 22:08:36 +0200 Subject: [PATCH 017/131] feat: set first day of the week #528 --- .../config/default-global-config.const.ts | 3 ++- .../form-cfgs/misc-settings-form.const.ts | 17 +++++++++++++++++ src/app/features/config/global-config.model.ts | 1 + src/app/t.const.ts | 3 ++- .../ui/owl-wrapper/owl-wrapper.component.html | 1 + src/app/ui/owl-wrapper/owl-wrapper.component.ts | 10 +++++++++- src/assets/i18n/de.json | 3 ++- src/assets/i18n/en.json | 3 ++- 8 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/app/features/config/default-global-config.const.ts b/src/app/features/config/default-global-config.const.ts index 3ed75191c..f352a6891 100644 --- a/src/app/features/config/default-global-config.const.ts +++ b/src/app/features/config/default-global-config.const.ts @@ -14,7 +14,8 @@ export const DEFAULT_GLOBAL_CONFIG: GlobalConfigState = { isTurnOffMarkdown: false, isAutoAddWorkedOnToToday: false, isDisableInitialDialog: false, - defaultProjectId: null + defaultProjectId: null, + firstDayOfWeek: 0, }, evaluation: { isHideEvaluationSheet: false, diff --git a/src/app/features/config/form-cfgs/misc-settings-form.const.ts b/src/app/features/config/form-cfgs/misc-settings-form.const.ts index 1f494f7e0..038646186 100644 --- a/src/app/features/config/form-cfgs/misc-settings-form.const.ts +++ b/src/app/features/config/form-cfgs/misc-settings-form.const.ts @@ -70,5 +70,22 @@ export const MISC_SETTINGS_FORM_CFG: ConfigFormSection = { label: T.GCF.MISC.DEFAULT_PROJECT, }, }, + { + key: 'firstDayOfWeek', + type: 'select', + templateOptions: { + label: T.GCF.MISC.FIRST_DAY_OF_WEEK, + required: true, + options: [ + {label: T.F.TASK_REPEAT.F.SUNDAY, value: 0}, + {label: T.F.TASK_REPEAT.F.MONDAY, value: 1}, + {label: T.F.TASK_REPEAT.F.TUESDAY, value: 2}, + {label: T.F.TASK_REPEAT.F.WEDNESDAY, value: 3}, + {label: T.F.TASK_REPEAT.F.THURSDAY, value: 4}, + {label: T.F.TASK_REPEAT.F.FRIDAY, value: 5}, + {label: T.F.TASK_REPEAT.F.SATURDAY, value: 6}, + ], + }, + }, ] }; diff --git a/src/app/features/config/global-config.model.ts b/src/app/features/config/global-config.model.ts index 775de9102..1bd5cfc42 100644 --- a/src/app/features/config/global-config.model.ts +++ b/src/app/features/config/global-config.model.ts @@ -50,6 +50,7 @@ export type MiscConfig = Readonly<{ isAutoAddWorkedOnToToday: boolean; isDisableInitialDialog: boolean; defaultProjectId: string | null; + firstDayOfWeek: number; }>; export type EvaluationConfig = Readonly<{ diff --git a/src/app/t.const.ts b/src/app/t.const.ts index b91efb6cd..b9f2e04bb 100644 --- a/src/app/t.const.ts +++ b/src/app/t.const.ts @@ -957,7 +957,8 @@ export const T = { 'IS_HIDE_NAV': 'GCF.MISC.IS_HIDE_NAV', 'IS_NOTIFY_WHEN_TIME_ESTIMATE_EXCEEDED': 'GCF.MISC.IS_NOTIFY_WHEN_TIME_ESTIMATE_EXCEEDED', 'IS_TURN_OFF_MARKDOWN': 'GCF.MISC.IS_TURN_OFF_MARKDOWN', - 'TITLE': 'GCF.MISC.TITLE' + 'TITLE': 'GCF.MISC.TITLE', + "FIRST_DAY_OF_WEEK": 'GCF.MISC.FIRST_DAY_OF_WEEK', }, 'POMODORO': { 'BREAK_DURATION': 'GCF.POMODORO.BREAK_DURATION', diff --git a/src/app/ui/owl-wrapper/owl-wrapper.component.html b/src/app/ui/owl-wrapper/owl-wrapper.component.html index 94456f7fc..0a9f57ad2 100644 --- a/src/app/ui/owl-wrapper/owl-wrapper.component.html +++ b/src/app/ui/owl-wrapper/owl-wrapper.component.html @@ -10,5 +10,6 @@ [sPlaceholder]="T.DATETIME_SCHEDULE.PLACEHOLDER|translate" [sPressEnterToSubmit]="T.DATETIME_SCHEDULE.PRESS_ENTER_AGAIN|translate" [sTomorrow]="T.DATETIME_SCHEDULE.TOMORROW|translate" + [firstDayOfWeek]="(firstDayOfWeek$|async)" name="owlDate" ngDefaultControl> diff --git a/src/app/ui/owl-wrapper/owl-wrapper.component.ts b/src/app/ui/owl-wrapper/owl-wrapper.component.ts index ab6279362..6431b9b4a 100644 --- a/src/app/ui/owl-wrapper/owl-wrapper.component.ts +++ b/src/app/ui/owl-wrapper/owl-wrapper.component.ts @@ -1,4 +1,7 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map, startWith } from 'rxjs/operators'; +import { GlobalConfigService } from 'src/app/features/config/global-config.service'; import { T } from 'src/app/t.const'; @Component({ @@ -31,7 +34,12 @@ export class OwlWrapperComponent { '23:30', ]; - constructor() { + firstDayOfWeek$: Observable = this._globalConfigService.misc$.pipe( + map(cfg => cfg.firstDayOfWeek), + startWith(0), + ); + + constructor(private _globalConfigService: GlobalConfigService) { } @Input('dateTime') diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 5f50a4d61..c23e9ae27 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -941,7 +941,8 @@ "IS_HIDE_NAV": "Navigation verbergen, bis die Hauptüberschrift angezeigt wird (nur Desktop)", "IS_NOTIFY_WHEN_TIME_ESTIMATE_EXCEEDED": "Benachrichtigen, wenn die geschätzte Zeit überschritten wurde", "IS_TURN_OFF_MARKDOWN": "Deaktivieren Sie das Markdown-Parsing für Notizen", - "TITLE": "Verschiedene Einstellungen" + "TITLE": "Verschiedene Einstellungen", + "FIRST_DAY_OF_WEEK": "Erster Tag der Woche" }, "POMODORO": { "BREAK_DURATION": "Dauer der kurzen Pausen", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 11445de25..2dc66805e 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -957,7 +957,8 @@ "IS_HIDE_NAV": "Hide navigation until main header is hovered (desktop only)", "IS_NOTIFY_WHEN_TIME_ESTIMATE_EXCEEDED": "Notify when time estimate was exceeded", "IS_TURN_OFF_MARKDOWN": "Turn off markdown parsing for notes", - "TITLE": "Misc Settings" + "TITLE": "Misc Settings", + "FIRST_DAY_OF_WEEK": "First day of the week" }, "POMODORO": { "BREAK_DURATION": "Duration of short breaks", From 72db7dc37c277db9fedc19b7885bf47cd7eb0fe6 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 2 Oct 2020 22:22:32 +0200 Subject: [PATCH 018/131] chore: increase wait time for mac travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 873d8d0b8..cbf47356c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,7 +57,7 @@ script: else yarn install && yarn add 7zip-bin-mac yarn run buildAllElectron:noTests - travis_wait 30 yarn dist:mac:dl -p $PUB + travis_wait 33 yarn dist:mac:dl -p $PUB fi # NOTE: disabled until next release of electron builder From 2124711d17b2a42d529fde264f853aa983045da7 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 2 Oct 2020 22:41:16 +0200 Subject: [PATCH 019/131] build: add build --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 72a8486e5..cbbf11662 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "buildAllElectron:prod": "yarn preCheck && yarn buildFrontend:prod && yarn electron:build", "buildAllElectron:stage": "yarn preCheck && yarn buildFrontend:stage && yarn electron:build", "buildAllElectron:noTests": "yarn lint && yarn buildFrontend:prod && yarn electron:build", + "build": "yarn preCheck && yarn buildAllElectron:prod", "buildApp": "yarn preCheck && yarn buildAllElectron:prod && yarn electron-builder", "test": "ng test --watch=false", "test:watch": "ng test --browsers ChromeHeadless", From 70a813a5018c0688d29071a454adc98f5df4f945 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 2 Oct 2020 22:44:00 +0200 Subject: [PATCH 020/131] build: add build.yml for github actions --- .github/workflows/build.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..bdeed5272 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,31 @@ +name: Build/release + +on: push + +jobs: + release: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [macos-latest, ubuntu-latest, windows-latest] + + steps: + - name: Check out Git repository + uses: actions/checkout@v1 + + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v1 + with: + node-version: 12 + + - name: Build/release Electron app + uses: samuelmeuli/action-electron-builder@v1 + with: + # GitHub token, automatically provided to the action + # (No need to define this secret in the repo settings) + github_token: ${{ secrets.github_token }} + + # If the commit is tagged with a version (e.g. "v1.0.0"), + # release the app after building + release: ${{ startsWith(github.ref, 'refs/tags/v') }} From 6b9c5e72692367cbb50f51e0e2a8fd94572be0d4 Mon Sep 17 00:00:00 2001 From: Philipp Korn Date: Fri, 2 Oct 2020 23:25:01 +0200 Subject: [PATCH 021/131] feat: set first day of week in DateAdapter --- src/app/core/language/language.service.ts | 13 +++++++++++++ .../config/form-cfgs/misc-settings-form.const.ts | 1 - 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/app/core/language/language.service.ts b/src/app/core/language/language.service.ts index a546d533b..0cfdcd1f9 100644 --- a/src/app/core/language/language.service.ts +++ b/src/app/core/language/language.service.ts @@ -5,6 +5,9 @@ import { DateAdapter } from '@angular/material/core'; import * as moment from 'moment'; import { AUTO_SWITCH_LNGS, LanguageCode, LanguageCodeMomentMap, RTL_LANGUAGES } from '../../app.constants'; import { BehaviorSubject, Observable } from 'rxjs'; +import { GlobalConfigService } from 'src/app/features/config/global-config.service'; +import { map, startWith } from 'rxjs/operators'; +import { DEFAULT_GLOBAL_CONFIG } from 'src/app/features/config/default-global-config.const'; @Injectable({providedIn: 'root'}) export class LanguageService { @@ -19,6 +22,7 @@ export class LanguageService { private _translateService: TranslateService, private _dateTimeAdapter: DateTimeAdapter, private _dateAdapter: DateAdapter, + private _globalConfigService: GlobalConfigService, ) { } @@ -32,6 +36,15 @@ export class LanguageService { setDefault(lng: LanguageCode) { this._translateService.setDefaultLang(lng); + + let firstDayOfWeek = DEFAULT_GLOBAL_CONFIG.misc.firstDayOfWeek; + this._globalConfigService.misc$.pipe( + map(cfg => cfg.firstDayOfWeek), + startWith(0), + ).subscribe((_firstDayOfWeek: number) => { + firstDayOfWeek = _firstDayOfWeek; + }); + this._dateAdapter.getFirstDayOfWeek = () => firstDayOfWeek; } setFromBrowserLngIfAutoSwitchLng() { diff --git a/src/app/features/config/form-cfgs/misc-settings-form.const.ts b/src/app/features/config/form-cfgs/misc-settings-form.const.ts index 038646186..d63cd2d0c 100644 --- a/src/app/features/config/form-cfgs/misc-settings-form.const.ts +++ b/src/app/features/config/form-cfgs/misc-settings-form.const.ts @@ -75,7 +75,6 @@ export const MISC_SETTINGS_FORM_CFG: ConfigFormSection = { type: 'select', templateOptions: { label: T.GCF.MISC.FIRST_DAY_OF_WEEK, - required: true, options: [ {label: T.F.TASK_REPEAT.F.SUNDAY, value: 0}, {label: T.F.TASK_REPEAT.F.MONDAY, value: 1}, From 648c67bdd28a235e73775ea2b54144924b8608d4 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 12:35:21 +0200 Subject: [PATCH 022/131] build: add build:noTest --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index cbbf11662..a64cd18f7 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "buildAllElectron:stage": "yarn preCheck && yarn buildFrontend:stage && yarn electron:build", "buildAllElectron:noTests": "yarn lint && yarn buildFrontend:prod && yarn electron:build", "build": "yarn preCheck && yarn buildAllElectron:prod", + "build:noTest": "yarn lint && yarn buildAllElectron:prod", "buildApp": "yarn preCheck && yarn buildAllElectron:prod && yarn electron-builder", "test": "ng test --watch=false", "test:watch": "ng test --browsers ChromeHeadless", From 288d32a7e8f30a64fe9d44921d35963682cf1938 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 12:36:42 +0200 Subject: [PATCH 023/131] build: complete github actions script --- .github/workflows/build.yml | 75 ++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bdeed5272..10b40160d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,14 +1,11 @@ -name: Build/release - on: push jobs: release: runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [macos-latest, ubuntu-latest, windows-latest] + + linux-bin-and-snap-release: + runs-on: ubuntu-latest steps: - name: Check out Git repository @@ -29,3 +26,69 @@ jobs: # If the commit is tagged with a version (e.g. "v1.0.0"), # release the app after building release: ${{ startsWith(github.ref, 'refs/tags/v') }} + + - name: Install Snapcraft + uses: samuelmeuli/action-snapcraft@v1 + # Only install Snapcraft on Ubuntu + if: startsWith(matrix.os, 'ubuntu') + with: + # Log in to Snap Store + snapcraft_token: ${{ secrets.snapcraft_token }} + + mac-bin: + runs-on: macos-latest + steps: + - name: Check out Git repository + uses: actions/checkout@v1 + + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v1 + with: + node-version: 12 + - name: Prepare for app notarization + if: startsWith(matrix.os, 'macos') + # Import Apple API key for app notarization on macOS + run: | + mkdir -p ~/private_keys/ + echo '${{ secrets.mac_api_key }}' > ~/private_keys/AuthKey_${{ secrets.mac_api_key_id }}.p8 + + - name: Build/release Electron app + uses: samuelmeuli/action-electron-builder@v1 + with: + # GitHub token, automatically provided to the action + # (No need to define this secret in the repo settings) + github_token: ${{ secrets.github_token }} + mac_certs: ${{ secrets.mac_certs }} + mac_certs_password: ${{ secrets.mac_certs_password }} + + # If the commit is tagged with a version (e.g. "v1.0.0"), + # release the app after building + release: ${{ startsWith(github.ref, 'refs/tags/v') }} + env: + # macOS notarization API key + API_KEY_ID: ${{ secrets.mac_api_key_id }} + API_KEY_ISSUER_ID: ${{ secrets.mac_api_key_issuer_id }} + + windows-bin: + runs-on: windows-latest + + steps: + - name: Check out Git repository + uses: actions/checkout@v1 + + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v1 + with: + node-version: 12 + + - name: Build/release Electron app + uses: samuelmeuli/action-electron-builder@v1 + with: + build_script_name: build:noTest + # GitHub token, automatically provided to the action + # (No need to define this secret in the repo settings) + github_token: ${{ secrets.github_token }} + + # If the commit is tagged with a version (e.g. "v1.0.0"), + # release the app after building + release: ${{ startsWith(github.ref, 'refs/tags/v') }} From a701cd2584a354aeec43a363d1ce67df99311e21 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 17:31:48 +0200 Subject: [PATCH 024/131] build: add lint and test pr git action --- .github/workflows/lint-and-test-pr.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/lint-and-test-pr.yml diff --git a/.github/workflows/lint-and-test-pr.yml b/.github/workflows/lint-and-test-pr.yml new file mode 100644 index 000000000..8be4b35b9 --- /dev/null +++ b/.github/workflows/lint-and-test-pr.yml @@ -0,0 +1,25 @@ +name: "Lint & Test PRs" + +on: + pull_request: + # The branches below must be a subset of the branches above + branches: [master] + +jobs: + test-on-linux: + runs-on: ubuntu-latest + + steps: + - name: Check out Git repository + uses: actions/checkout@v1 + + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v1 + with: + node-version: 12 + + - run: yarn lint + - run: yarn test + - run: yarn e2e + + From 96ecb551b82180adb22dace98cee40153264cbd0 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 17:43:25 +0200 Subject: [PATCH 025/131] build: improve lint and test pr --- .github/workflows/lint-and-test-pr.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/lint-and-test-pr.yml b/.github/workflows/lint-and-test-pr.yml index 8be4b35b9..6cb1347e8 100644 --- a/.github/workflows/lint-and-test-pr.yml +++ b/.github/workflows/lint-and-test-pr.yml @@ -1,6 +1,9 @@ name: "Lint & Test PRs" on: + push: + branches: [master, test/git-actions] + pull_request: # The branches below must be a subset of the branches above branches: [master] @@ -18,6 +21,9 @@ jobs: with: node-version: 12 + - name: NPM or Yarn install with caching + uses: bahmutov/npm-install@v1.1.0 + - run: yarn lint - run: yarn test - run: yarn e2e From 6fc45ac3a09568bf5038bfc92412c098b37720ec Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 18:06:05 +0200 Subject: [PATCH 026/131] build: update build script --- .github/workflows/build.yml | 97 ++++++++++++++++++++++++++++++++++--- package.json | 2 +- 2 files changed, 90 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bdeed5272..6fdad23eb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,14 +1,12 @@ -name: Build/release +name: Build/Release -on: push +on: + push: + branches: [master, test/git-actions] jobs: - release: - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [macos-latest, ubuntu-latest, windows-latest] + linux-bin-and-snap-release: + runs-on: ubuntu-latest steps: - name: Check out Git repository @@ -19,6 +17,9 @@ jobs: with: node-version: 12 + - name: NPM or Yarn install with caching + uses: bahmutov/npm-install@v1.1.0 + - name: Build/release Electron app uses: samuelmeuli/action-electron-builder@v1 with: @@ -29,3 +30,83 @@ jobs: # If the commit is tagged with a version (e.g. "v1.0.0"), # release the app after building release: ${{ startsWith(github.ref, 'refs/tags/v') }} + + - name: Install Snapcraft + uses: samuelmeuli/action-snapcraft@v1 + with: + # Log in to Snap Store + snapcraft_token: ${{ secrets.snapcraft_token }} + # Release to edge if no tag and to candidate if tag + - run: snapcraft push app-builds/superProductivity*.snap --release edge + if: {{ github.ref != 'ref/head/v*' }} + - run: snapcraft push app-builds/superProductivity*.snap --release candidate + if: {{ github.ref == 'ref/head/v*' }} + + + mac-bin: + runs-on: macos-latest + if: {{ github.ref == 'ref/head/v*' }} + + steps: + - name: Check out Git repository + uses: actions/checkout@v1 + + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v1 + with: + node-version: 12 + + - name: NPM or Yarn install with caching + uses: bahmutov/npm-install@v1.1.0 + + - name: Prepare for app notarization + if: startsWith(matrix.os, 'macos') + # Import Apple API key for app notarization on macOS + run: | + mkdir -p ~/private_keys/ + echo '${{ secrets.mac_api_key }}' > ~/private_keys/AuthKey_${{ secrets.mac_api_key_id }}.p8 + + - name: Build/release Electron app + uses: samuelmeuli/action-electron-builder@v1 + with: + # GitHub token, automatically provided to the action + # (No need to define this secret in the repo settings) + github_token: ${{ secrets.github_token }} + mac_certs: ${{ secrets.mac_certs }} + mac_certs_password: ${{ secrets.mac_certs_password }} + + # If the commit is tagged with a version (e.g. "v1.0.0"), + # release the app after building + release: ${{ startsWith(github.ref, 'refs/tags/v') }} + env: + # macOS notarization API key + API_KEY_ID: ${{ secrets.mac_api_key_id }} + API_KEY_ISSUER_ID: ${{ secrets.mac_api_key_issuer_id }} + + windows-bin: + runs-on: windows-latest + if: {{ github.ref == 'ref/head/v*' }} + + steps: + - name: Check out Git repository + uses: actions/checkout@v1 + + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v1 + with: + node-version: 12 + + - name: NPM or Yarn install with caching + uses: bahmutov/npm-install@v1.1.0 + + - name: Build/release Electron app + uses: samuelmeuli/action-electron-builder@v1 + with: + build_script_name: build:noTest + # GitHub token, automatically provided to the action + # (No need to define this secret in the repo settings) + github_token: ${{ secrets.github_token }} + + # If the commit is tagged with a version (e.g. "v1.0.0"), + # release the app after building + release: ${{ startsWith(github.ref, 'refs/tags/v') }} diff --git a/package.json b/package.json index a64cd18f7..b0b8f0a9c 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "buildAllElectron:stage": "yarn preCheck && yarn buildFrontend:stage && yarn electron:build", "buildAllElectron:noTests": "yarn lint && yarn buildFrontend:prod && yarn electron:build", "build": "yarn preCheck && yarn buildAllElectron:prod", - "build:noTest": "yarn lint && yarn buildAllElectron:prod", + "build:noTest": "yarn lint && yarn buildAllElectron:prod", "buildApp": "yarn preCheck && yarn buildAllElectron:prod && yarn electron-builder", "test": "ng test --watch=false", "test:watch": "ng test --browsers ChromeHeadless", From a5ae586e31fc4970b2734de30f33c13ec58d9326 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 18:18:52 +0200 Subject: [PATCH 027/131] build: update build script --- .github/workflows/build.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6fdad23eb..408233443 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,14 +38,13 @@ jobs: snapcraft_token: ${{ secrets.snapcraft_token }} # Release to edge if no tag and to candidate if tag - run: snapcraft push app-builds/superProductivity*.snap --release edge - if: {{ github.ref != 'ref/head/v*' }} + if: !startsWith(github.ref, 'refs/tags/v') - run: snapcraft push app-builds/superProductivity*.snap --release candidate - if: {{ github.ref == 'ref/head/v*' }} + if: startsWith(github.ref, 'refs/tags/v') mac-bin: runs-on: macos-latest - if: {{ github.ref == 'ref/head/v*' }} steps: - name: Check out Git repository @@ -85,7 +84,6 @@ jobs: windows-bin: runs-on: windows-latest - if: {{ github.ref == 'ref/head/v*' }} steps: - name: Check out Git repository From c33ae6ca04c6d7207f452d9eaeecb37de34843a4 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 19:05:32 +0200 Subject: [PATCH 028/131] build: update build script --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 408233443..bcab2c45e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Build/Release +name: Build & Release on: push: From 28779e6290a78e5a8ce454e0c9ca700d3067a7f9 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 19:07:22 +0200 Subject: [PATCH 029/131] build: update build script --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bcab2c45e..b9fcde51e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: snapcraft_token: ${{ secrets.snapcraft_token }} # Release to edge if no tag and to candidate if tag - run: snapcraft push app-builds/superProductivity*.snap --release edge - if: !startsWith(github.ref, 'refs/tags/v') + if: !(startsWith(github.ref, 'refs/tags/v')) - run: snapcraft push app-builds/superProductivity*.snap --release candidate if: startsWith(github.ref, 'refs/tags/v') From da3ac76d5ed7e1502230b6199e8e0dfc85a68efb Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 19:10:08 +0200 Subject: [PATCH 030/131] build: update build script --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b9fcde51e..28b7a1909 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: snapcraft_token: ${{ secrets.snapcraft_token }} # Release to edge if no tag and to candidate if tag - run: snapcraft push app-builds/superProductivity*.snap --release edge - if: !(startsWith(github.ref, 'refs/tags/v')) + if: false == startsWith(github.ref, 'refs/tags/v') - run: snapcraft push app-builds/superProductivity*.snap --release candidate if: startsWith(github.ref, 'refs/tags/v') From 30689046f9d9f29b9770eb935112c8f70a1dc835 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 19:22:37 +0200 Subject: [PATCH 031/131] build: remove legacy travis stuff --- .travis.yml | 116 ---------------------------------- build/docker/Dockerfile | 42 ------------ build/docker/run-linux-win.sh | 22 ------- build/mac-cert.tar.enc | Bin 35344 -> 0 bytes build/scripts/notarize.js | 33 ---------- 5 files changed, 213 deletions(-) delete mode 100644 .travis.yml delete mode 100644 build/docker/Dockerfile delete mode 100644 build/docker/run-linux-win.sh delete mode 100644 build/mac-cert.tar.enc delete mode 100644 build/scripts/notarize.js diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index cbf47356c..000000000 --- a/.travis.yml +++ /dev/null @@ -1,116 +0,0 @@ -sudo: required -language: node_js -node_js: '12' - -matrix: - include: - - os: osx - osx_image: xcode10 - addons: - chrome: stable - before_install: - - openssl aes-256-cbc -K $encrypted_527645209bb0_key -iv $encrypted_527645209bb0_iv -in build/mac-cert.tar.enc -out mac-cert.tar -d - - tar xvf mac-cert.tar - - - os: linux - dist: xenial - language: generic - services: - - docker -# before_install: -# - sudo snap install snapcraft --classic -# - export CHROME_BIN=chromium-browser -# - export DISPLAY=:99.0 -# - sh -e /etc/init.d/xvfb start - -addons: - ssh_known_hosts: - - the-front-end.de - - frs.sourceforge.net - apt: - packages: - - sshpass - -env: - global: - - ELECTRON_CACHE=$HOME/.cache/electron - - ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder - -cache: - yarn: true - directories: - - node_modules - - $HOME/.cache/electron - - $HOME/.cache/electron-builder - - $HOME/.npm/_prebuilds - -script: - - | - if [ -n "$TRAVIS_TAG" ]; then - PUB=always - else - PUB=never - fi - if [ "$TRAVIS_OS_NAME" == "linux" ]; then - echo '____RUNNING DOCKER____' - bash ${TRAVIS_BUILD_DIR}/build/docker/run-linux-win.sh ${PUB} - else - yarn install && yarn add 7zip-bin-mac - yarn run buildAllElectron:noTests - travis_wait 33 yarn dist:mac:dl -p $PUB - fi - -# NOTE: disabled until next release of electron builder -# if [ -n "$TRAVIS_TAG" ]; then -# yarn dist:mac:mas -# fi - - -deploy: - # Snap Deployment - - on: - condition: $TRAVIS_OS_NAME = linux - tags: false - branch: master - provider: snap - snap: ./app-builds/*.snap - channel: edge - skip_cleanup: true - # we use edge because of this: https://travis-ci.community/t/snap-deployment-stopped-working-out-of-nowhere/6908/2 - edge: true - - on: - condition: $TRAVIS_OS_NAME = linux - tags: true - branch: master - provider: snap - snap: ./app-builds/*.snap - channel: candidate - skip_cleanup: true - # we use edge because of this: https://travis-ci.community/t/snap-deployment-stopped-working-out-of-nowhere/6908/2 - edge: true - # Web deployment - - on: - condition: $TRAVIS_OS_NAME = linux - tags: true - branch: master - provider: script - script: sshpass -p "$DEPLOY_PASS" rsync -avz ./dist $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH - skip_cleanup: true -# NOTE: disabled until next release of electron builder and until electron works with osx again -# - on: -# branch: master -# condition: $TRAVIS_OS_NAME = osx -# tags: true -# provider: script -# script: xcrun altool --upload-app -f app-builds/mas/superProductivity-*.pkg -u "${APPLEID}" -p "${APPLEIDPASS}" -# skip_cleanup: true - - -# NOTE: this would only work, if we could and wanted to auto publish the github draft -# - provider: script -# script: brew update && brew install vitorgalvao/tiny-scripts/cask-repair && openssl aes-256-cbc -K $encrypted_c04542ca1075_key -iv $encrypted_c04542ca1075_iv -in build/hub.enc -out ~/.config/hub -d && cask-repair -b -v $TRAVIS_TAG superproductivity -# skip_cleanup: true -# on: -# branch: master -# condition: $TRAVIS_OS_NAME = osx -# tags: true diff --git a/build/docker/Dockerfile b/build/docker/Dockerfile deleted file mode 100644 index a4ba07061..000000000 --- a/build/docker/Dockerfile +++ /dev/null @@ -1,42 +0,0 @@ -FROM electronuserland/builder:wine - -ENV DEBIAN_FRONTEND=noninteractive - -# install google chrome -RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \ - echo "deb http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list && \ - apt-get update -y && apt-get install -y --no-install-recommends xvfb google-chrome-stable libgconf-2-4 && \ - # clean - apt-get clean && rm -rf /var/lib/apt/lists/* - -# replace shell with bash so we can source files -RUN rm /bin/sh && ln -s /bin/bash /bin/sh - -# add yarn repo -RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - -RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list - -# install yarn and clean up -RUN apt-get update && apt-get install -y yarn && apt-get clean && rm -rf /var/lib/apt/lists/* - -ENV NVM_DIR /usr/local/nvm -ENV NODE_VERSION 12.14.1 - -RUN mkdir $NVM_DIR -p - -# install nvm with node and npm -RUN curl -sS -o- https://raw.githubusercontent.com/creationix/nvm/v0.35.2/install.sh | bash - -# install node and npm -RUN source $NVM_DIR/nvm.sh \ - && nvm install $NODE_VERSION \ - && nvm alias default $NODE_VERSION \ - && nvm use default - -# add node and npm to path so the commands are available -ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules -ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH - -# confirm installation -RUN node -v -RUN yarn -v diff --git a/build/docker/run-linux-win.sh b/build/docker/run-linux-win.sh deleted file mode 100644 index 30177e302..000000000 --- a/build/docker/run-linux-win.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - -PWD2=$PWD -# read as arg -PUB=$1 - -cd "$(dirname "$0")" - -echo PUB $PUB -google-chrome --version - -docker run $ENVS --rm \ - $(env | \ - grep -Eo '^[^\s=]*(_TOKEN|_KEY)[^\s=]*' | \ - sed '/^$/d;s/^/-e /' | \ - paste -sd ' ' \ - ) \ - -v ${PWD2}:/project \ - -v ~/.cache/electron:/root/.cache/electron \ - -v ~/.cache/electron-builder:/root/.cache/electron-builder \ - $(docker image build -q .) \ - /bin/bash -c "echo '____DOCKER_INNER_START____' && echo $PUB && node -v && npm -v && yarn -v && ls -l && yarn --link-duplicates --pure-lockfile && yarn run dist:linuxAndWin -p ${PUB} && ls -l ./dist" diff --git a/build/mac-cert.tar.enc b/build/mac-cert.tar.enc deleted file mode 100644 index 368f019ace5cc0ecf4e38e7e1c82771ff3195107..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35344 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®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 Date: Sat, 3 Oct 2020 19:32:41 +0200 Subject: [PATCH 032/131] build: make windows build work --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index b0b8f0a9c..6bc660c68 100644 --- a/package.json +++ b/package.json @@ -27,9 +27,9 @@ "buildFrontend:prod:watch": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --aot --prod --watch", "buildAllElectron:prod": "yarn preCheck && yarn buildFrontend:prod && yarn electron:build", "buildAllElectron:stage": "yarn preCheck && yarn buildFrontend:stage && yarn electron:build", - "buildAllElectron:noTests": "yarn lint && yarn buildFrontend:prod && yarn electron:build", + "buildAllElectron:noTests:prod": "yarn lint && yarn buildFrontend:prod && yarn electron:build", "build": "yarn preCheck && yarn buildAllElectron:prod", - "build:noTest": "yarn lint && yarn buildAllElectron:prod", + "build:noTest": "yarn lint && yarn buildAllElectron:noTests:prod", "buildApp": "yarn preCheck && yarn buildAllElectron:prod && yarn electron-builder", "test": "ng test --watch=false", "test:watch": "ng test --browsers ChromeHeadless", @@ -50,7 +50,7 @@ "dist": "yarn buildAllElectron:prod && electron-builder", "dist:only": "electron-builder", "dist:linuxAndWin": "yarn buildAllElectron:prod && electron-builder --linux --win", - "dist:win": "yarn buildAllElectron:noTests && electron-builder --win", + "dist:win": "yarn buildAllElectron:noTests:prod && electron-builder --win", "dist:win:only": "electron-builder --win", "dist:win:appx": "yarn buildAllElectron:prod && electron-builder --win --config=build/electron-builder.appx.yaml", "dist:win:store": "git pull && yarn && copy electron-builder.win-store.yaml electron-builder.yaml && yarn dist:win && git checkout electron-builder.yaml || git checkout electron-builder.yaml", From 409c92a2b2cc8fd45e9f0e3466918b26a5d8645c Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 19:36:17 +0200 Subject: [PATCH 033/131] build: don't execute tests for mac --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 28b7a1909..578f7396e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -68,6 +68,7 @@ jobs: - name: Build/release Electron app uses: samuelmeuli/action-electron-builder@v1 with: + build_script_name: build:noTest # GitHub token, automatically provided to the action # (No need to define this secret in the repo settings) github_token: ${{ secrets.github_token }} From 4ba0d4acd011931111f037e2ca2314b055afbd6e Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 20:14:24 +0200 Subject: [PATCH 034/131] build: add provision profile for mac --- .github/workflows/build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 578f7396e..061229002 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,6 +58,11 @@ jobs: - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 + - run: 'echo "$PROVISION_PROFILE" > embedded.provisionprofile' + shell: bash + env: + PROVISION_PROFILE: ${{secrets.dl_provision_profile}} + - name: Prepare for app notarization if: startsWith(matrix.os, 'macos') # Import Apple API key for app notarization on macOS From 482ede2a4994b6bbe0621f9c03161fc716747697 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 21:05:06 +0200 Subject: [PATCH 035/131] build: make provision profile work for mac --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 061229002..9bd703814 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,7 +58,7 @@ jobs: - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 - - run: 'echo "$PROVISION_PROFILE" > embedded.provisionprofile' + - run: 'echo "$PROVISION_PROFILE" | base64 --decode > embedded.provisionprofile' shell: bash env: PROVISION_PROFILE: ${{secrets.dl_provision_profile}} From 267684441d7f6a385851330f88c69b3c4c878fb9 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 21:08:57 +0200 Subject: [PATCH 036/131] build: re-add notarize script --- build/scripts/notarize.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 build/scripts/notarize.js diff --git a/build/scripts/notarize.js b/build/scripts/notarize.js new file mode 100644 index 000000000..6042d6112 --- /dev/null +++ b/build/scripts/notarize.js @@ -0,0 +1,33 @@ +require('dotenv').config(); +const {notarize} = require('electron-notarize'); +const fs = require('fs'); + +exports.default = async function notarizing(context) { + const {electronPlatformName, appOutDir} = context; + if (electronPlatformName !== 'darwin') { + return; + } + + const appName = context.packager.appInfo.productFilename; + const appBundleId = context.packager.appInfo.macBundleIdentifier; + const appPath = `${appOutDir}/${appName}.app`; + if (!fs.existsSync(appPath)) { + throw new Error(`Cannot find application at: ${appPath}`); + } + + try { + let envBefore = process.env.DEBUG; + process.env.DEBUG = 'electron-notarize'; + await notarize({ + appBundleId, + appPath, + appleId: process.env.APPLEID, + appleIdPassword: process.env.APPLEIDPASS, + }); + process.env.DEBUG = envBefore; + } catch (e) { + console.error(e); + throw new Error(e); + } + console.log(`Notarizing DONE`); +}; From 83e98f067bf6314796e2ffa52d568142717d4232 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 21:33:37 +0200 Subject: [PATCH 037/131] build: remove custom notarize again --- .github/workflows/build.yml | 1 - build/scripts/notarize.js | 33 --------------------------------- electron-builder.yaml | 1 - 3 files changed, 35 deletions(-) delete mode 100644 build/scripts/notarize.js diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9bd703814..0dd0237a8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -64,7 +64,6 @@ jobs: PROVISION_PROFILE: ${{secrets.dl_provision_profile}} - name: Prepare for app notarization - if: startsWith(matrix.os, 'macos') # Import Apple API key for app notarization on macOS run: | mkdir -p ~/private_keys/ diff --git a/build/scripts/notarize.js b/build/scripts/notarize.js deleted file mode 100644 index 6042d6112..000000000 --- a/build/scripts/notarize.js +++ /dev/null @@ -1,33 +0,0 @@ -require('dotenv').config(); -const {notarize} = require('electron-notarize'); -const fs = require('fs'); - -exports.default = async function notarizing(context) { - const {electronPlatformName, appOutDir} = context; - if (electronPlatformName !== 'darwin') { - return; - } - - const appName = context.packager.appInfo.productFilename; - const appBundleId = context.packager.appInfo.macBundleIdentifier; - const appPath = `${appOutDir}/${appName}.app`; - if (!fs.existsSync(appPath)) { - throw new Error(`Cannot find application at: ${appPath}`); - } - - try { - let envBefore = process.env.DEBUG; - process.env.DEBUG = 'electron-notarize'; - await notarize({ - appBundleId, - appPath, - appleId: process.env.APPLEID, - appleIdPassword: process.env.APPLEIDPASS, - }); - process.env.DEBUG = envBefore; - } catch (e) { - console.error(e); - throw new Error(e); - } - console.log(`Notarizing DONE`); -}; diff --git a/electron-builder.yaml b/electron-builder.yaml index 4fed96d44..28f3c1849 100644 --- a/electron-builder.yaml +++ b/electron-builder.yaml @@ -1,5 +1,4 @@ appId: superProductivity -afterSign: build/scripts/notarize.js files: - electron/**/* - "!electron/**/*.ts" From 6e18d1e439071dcd258a8b226a903a0b3c7403c1 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 21:35:36 +0200 Subject: [PATCH 038/131] build: don't run lint and test for test branch --- .github/workflows/lint-and-test-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-and-test-pr.yml b/.github/workflows/lint-and-test-pr.yml index 6cb1347e8..e28f66faf 100644 --- a/.github/workflows/lint-and-test-pr.yml +++ b/.github/workflows/lint-and-test-pr.yml @@ -2,7 +2,7 @@ name: "Lint & Test PRs" on: push: - branches: [master, test/git-actions] + branches: [master] pull_request: # The branches below must be a subset of the branches above From 251cb3f2f8b77d539d5c127014a854989a536be2 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 23:43:54 +0200 Subject: [PATCH 039/131] 5.9.3 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9df4c9d0a..135c577e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [5.9.3](https://github.com/johannesjo/super-productivity/compare/v0.0.1...v5.9.3) (2020-10-03) + + + ## [5.9.2](https://github.com/johannesjo/super-productivity/compare/v5.9.1...v5.9.2) (2020-10-02) diff --git a/package.json b/package.json index 6bc660c68..08eeebb4d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.2", + "version": "5.9.3", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "johannesjo (http://super-productivity.com)", From ae062c339a29ae38a9dc7075678c75ede8689d22 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 00:13:21 +0200 Subject: [PATCH 040/131] build: inform about release --- .github/workflows/build.yml | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0dd0237a8..117ac1290 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: Build & Release on: push: - branches: [master, test/git-actions] + branches: [ master, test/git-actions ] jobs: linux-bin-and-snap-release: @@ -23,12 +23,7 @@ jobs: - name: Build/release Electron app uses: samuelmeuli/action-electron-builder@v1 with: - # GitHub token, automatically provided to the action - # (No need to define this secret in the repo settings) github_token: ${{ secrets.github_token }} - - # If the commit is tagged with a version (e.g. "v1.0.0"), - # release the app after building release: ${{ startsWith(github.ref, 'refs/tags/v') }} - name: Install Snapcraft @@ -47,6 +42,11 @@ jobs: runs-on: macos-latest steps: + - name: Echo is Release + run: echo 'IS_RELEASE $IS_RELEASE, ${{ startsWith(github.ref, 'refs/tags/v') }}' + env: + IS_RELEASE: ${{ startsWith(github.ref, 'refs/tags/v') }} + - name: Check out Git repository uses: actions/checkout@v1 @@ -73,14 +73,9 @@ jobs: uses: samuelmeuli/action-electron-builder@v1 with: build_script_name: build:noTest - # GitHub token, automatically provided to the action - # (No need to define this secret in the repo settings) github_token: ${{ secrets.github_token }} mac_certs: ${{ secrets.mac_certs }} mac_certs_password: ${{ secrets.mac_certs_password }} - - # If the commit is tagged with a version (e.g. "v1.0.0"), - # release the app after building release: ${{ startsWith(github.ref, 'refs/tags/v') }} env: # macOS notarization API key @@ -106,10 +101,5 @@ jobs: uses: samuelmeuli/action-electron-builder@v1 with: build_script_name: build:noTest - # GitHub token, automatically provided to the action - # (No need to define this secret in the repo settings) github_token: ${{ secrets.github_token }} - - # If the commit is tagged with a version (e.g. "v1.0.0"), - # release the app after building release: ${{ startsWith(github.ref, 'refs/tags/v') }} From 813e9f2960bed1230dc8532f19657fae924cf757 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 00:16:19 +0200 Subject: [PATCH 041/131] 5.9.4 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 135c577e0..f06790cc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [5.9.4](https://github.com/johannesjo/super-productivity/compare/v5.9.3...v5.9.4) (2020-10-03) + + + ## [5.9.3](https://github.com/johannesjo/super-productivity/compare/v0.0.1...v5.9.3) (2020-10-03) diff --git a/package.json b/package.json index 08eeebb4d..64d70d5c4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.3", + "version": "5.9.4", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "johannesjo (http://super-productivity.com)", From 82f9e8bfe0c8595d8506f9b31cf2015de222a91f Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 00:25:46 +0200 Subject: [PATCH 042/131] build: exec always on push --- .github/workflows/build.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 117ac1290..aff1428be 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,8 +1,7 @@ name: Build & Release -on: - push: - branches: [ master, test/git-actions ] +on: [push] + jobs: linux-bin-and-snap-release: @@ -43,7 +42,7 @@ jobs: steps: - name: Echo is Release - run: echo 'IS_RELEASE $IS_RELEASE, ${{ startsWith(github.ref, 'refs/tags/v') }}' + run: echo "IS_RELEASE $IS_RELEASE, ${{ startsWith(github.ref, 'refs/tags/v') }}" env: IS_RELEASE: ${{ startsWith(github.ref, 'refs/tags/v') }} From 8a9aa4ed8cf1891f90fd7a9fe3c6836b67b8d4fa Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 00:26:43 +0200 Subject: [PATCH 043/131] 5.9.5 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f06790cc4..9e88e53eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [5.9.5](https://github.com/johannesjo/super-productivity/compare/v5.9.4...v5.9.5) (2020-10-03) + + + ## [5.9.4](https://github.com/johannesjo/super-productivity/compare/v5.9.3...v5.9.4) (2020-10-03) diff --git a/package.json b/package.json index 64d70d5c4..6828b1c0c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.4", + "version": "5.9.5", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "johannesjo (http://super-productivity.com)", From 572127a4a527f6afea4569d635dc63977b1f4642 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 10:44:57 +0200 Subject: [PATCH 044/131] build: rework triggers --- .github/workflows/build.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aff1428be..3fdc74224 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,9 @@ name: Build & Release - -on: [push] +on: + push: + branches: [ master, test/git-actions ] + tags: + - v* jobs: @@ -39,6 +42,7 @@ jobs: mac-bin: runs-on: macos-latest + if: startsWith(github.ref, 'refs/tags/v') steps: - name: Echo is Release @@ -83,6 +87,7 @@ jobs: windows-bin: runs-on: windows-latest + if: startsWith(github.ref, 'refs/tags/v') steps: - name: Check out Git repository From e219bebfa4fd1cf28caae624c3a69fd2b8ac98ed Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 10:59:35 +0200 Subject: [PATCH 045/131] build: execute tests for mac as well --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3fdc74224..723da0cc5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,6 +33,7 @@ jobs: with: # Log in to Snap Store snapcraft_token: ${{ secrets.snapcraft_token }} + # Release to edge if no tag and to candidate if tag - run: snapcraft push app-builds/superProductivity*.snap --release edge if: false == startsWith(github.ref, 'refs/tags/v') @@ -75,7 +76,7 @@ jobs: - name: Build/release Electron app uses: samuelmeuli/action-electron-builder@v1 with: - build_script_name: build:noTest + build_script_name: build github_token: ${{ secrets.github_token }} mac_certs: ${{ secrets.mac_certs }} mac_certs_password: ${{ secrets.mac_certs_password }} From 56f93ade1cd068301045867d1a3683f3dc8cb774 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 11:21:19 +0200 Subject: [PATCH 046/131] build: add notarization again --- electron-builder.yaml | 1 + package.json | 1 + yarn.lock | 19 ++++++++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/electron-builder.yaml b/electron-builder.yaml index 28f3c1849..d6a92692b 100644 --- a/electron-builder.yaml +++ b/electron-builder.yaml @@ -1,4 +1,5 @@ appId: superProductivity +afterSign: electron-builder-notarize files: - electron/**/* - "!electron/**/*.ts" diff --git a/package.json b/package.json index 6828b1c0c..dc8d16768 100644 --- a/package.json +++ b/package.json @@ -142,6 +142,7 @@ "cross-env": "^7.0.2", "electron": "^10.1.2", "electron-builder": "^22.7.0", + "electron-builder-notarize": "^1.2.0", "electron-notarize": "^1.0.0", "electron-reload": "^1.2.5", "file-saver": "^2.0.2", diff --git a/yarn.lock b/yarn.lock index a9af57e3f..2ab72f63a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4452,6 +4452,15 @@ ejs@^3.1.3: dependencies: jake "^10.6.1" +electron-builder-notarize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/electron-builder-notarize/-/electron-builder-notarize-1.2.0.tgz#6db86173601513bcb667074f80322f8622e24ff9" + integrity sha512-mSU5CSjydNlO5oFSOimJvzKQ4m/whUUBoE3i2xSAOF7+T2ZIzSfsGCT1SJvqsiHYf2xvTb2RpFoHWE6Oc9Cvgg== + dependencies: + electron-notarize "^0.2.0" + js-yaml "^3.14.0" + read-pkg-up "^7.0.0" + electron-builder@^22.7.0: version "22.7.0" resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.7.0.tgz#a42d08a1654ffc2f7d9e2860829d3cc55d4a0c81" @@ -4501,6 +4510,14 @@ electron-log@^4.2.2: resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-4.2.2.tgz#b358dc6d1e4772465609ee3d8ad9f594d9e742c8" integrity sha512-lBpLh1Q8qayrTxFIrTPcNjSHsosvUfOYyZ8glhiLcx7zCNPDGuj8+nXlEaaSS6LRiQQbLgLG+wKpuvztNzBIrA== +electron-notarize@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/electron-notarize/-/electron-notarize-0.2.1.tgz#759e8006decae19134f82996ed910db26d9192cc" + integrity sha512-oZ6/NhKeXmEKNROiFmRNfytqu3cxqC95sjooG7kBXQVEUSQkZnbiAhxVh5jXngL881G197pbwpeVPJyM7Ikmxw== + dependencies: + debug "^4.1.1" + fs-extra "^8.1.0" + electron-notarize@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/electron-notarize/-/electron-notarize-1.0.0.tgz#bc925b1ccc3f79e58e029e8c4706572b01a9fd8f" @@ -10076,7 +10093,7 @@ read-pkg-up@^3.0.0: find-up "^2.0.0" read-pkg "^3.0.0" -read-pkg-up@^7.0.1: +read-pkg-up@^7.0.0, read-pkg-up@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== From f0ad16a059c0c0c84d6d053921bb7c146946535e Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 11:22:23 +0200 Subject: [PATCH 047/131] 5.9.6 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e88e53eb..5fc98f08b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [5.9.6](https://github.com/johannesjo/super-productivity/compare/v5.9.5...v5.9.6) (2020-10-04) + + + ## [5.9.5](https://github.com/johannesjo/super-productivity/compare/v5.9.4...v5.9.5) (2020-10-03) diff --git a/package.json b/package.json index dc8d16768..96fc815ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.5", + "version": "5.9.6", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "johannesjo (http://super-productivity.com)", From 51a854c9e900a039105fb59cae15e304cf2969a5 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 11:33:01 +0200 Subject: [PATCH 048/131] build: remove entitlement for mas --- build/entitlements.mas.plist | 2 -- 1 file changed, 2 deletions(-) diff --git a/build/entitlements.mas.plist b/build/entitlements.mas.plist index 65e40f863..38da9a976 100644 --- a/build/entitlements.mas.plist +++ b/build/entitlements.mas.plist @@ -8,7 +8,5 @@ com.apple.security.files.user-selected.read-write - com.apple.security.cs.allow-unsigned-executable-memory - From 1ce59767af9abafba3a23c0281d07b1dbce22ac5 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 11:49:35 +0200 Subject: [PATCH 049/131] build: separate frontend build --- .github/workflows/build.yml | 20 +++++++++++++++----- package.json | 1 + 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 723da0cc5..a75abf819 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,8 +22,12 @@ jobs: - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 - - name: Build/release Electron app + - name: Build Frontend & Electron + run: yarn build + + - name: Build/Release Electron app uses: samuelmeuli/action-electron-builder@v1 + build_script_name: empty with: github_token: ${{ secrets.github_token }} release: ${{ startsWith(github.ref, 'refs/tags/v') }} @@ -73,10 +77,13 @@ jobs: mkdir -p ~/private_keys/ echo '${{ secrets.mac_api_key }}' > ~/private_keys/AuthKey_${{ secrets.mac_api_key_id }}.p8 - - name: Build/release Electron app + - name: Build Frontend & Electron + run: yarn build + + - name: Build/Release Electron app uses: samuelmeuli/action-electron-builder@v1 with: - build_script_name: build + build_script_name: empty github_token: ${{ secrets.github_token }} mac_certs: ${{ secrets.mac_certs }} mac_certs_password: ${{ secrets.mac_certs_password }} @@ -102,9 +109,12 @@ jobs: - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 - - name: Build/release Electron app + - name: Build Frontend & Electron + run: yarn build:noTest + + - name: Build/Release Electron app uses: samuelmeuli/action-electron-builder@v1 with: - build_script_name: build:noTest + build_script_name: empty github_token: ${{ secrets.github_token }} release: ${{ startsWith(github.ref, 'refs/tags/v') }} diff --git a/package.json b/package.json index 96fc815ff..d2338b807 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "electron:build": "tsc -p electron/tsconfig.electron.json", "electron:watch": "tsc -p electron/tsconfig.electron.json --watch", "electronBuilderOnly": "electron-builder", + "empty": "echo 'EMPTY YEAH'", "pack": "electron-builder --dir", "localInstall": "sudo echo 'Starting local install' && rm -Rf ./dist/ && rm -Rf ./app-builds/ && yarn buildAllElectron:stage && electron-builder --linux deb && sudo dpkg -i app-builds/superProductivity*.deb", "localInstall:prod": "sudo echo 'Starting local install' && rm -Rf ./dist/ && rm -Rf ./app-builds/ && yarn buildAllElectron:prod && electron-builder --linux deb && sudo dpkg -i app-builds/superProductivity*.deb", From 154eab92eed8053eaa14e7dfc5089ed01c9fbe4d Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 11:55:12 +0200 Subject: [PATCH 050/131] build: split up different build steps --- .github/workflows/build.yml | 26 +++++++++++++++++++++++++- package.json | 3 +-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a75abf819..9449a3f7f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,6 +22,15 @@ jobs: - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 + - name: Test Lint + run: yarn lint + + - name: Test Unit + run: yarn test + + - name: Test E2E + run: yarn e2e + - name: Build Frontend & Electron run: yarn build @@ -77,6 +86,15 @@ jobs: mkdir -p ~/private_keys/ echo '${{ secrets.mac_api_key }}' > ~/private_keys/AuthKey_${{ secrets.mac_api_key_id }}.p8 + - name: Test Lint + run: yarn lint + + - name: Test Unit + run: yarn test + + - name: Test E2E + run: yarn e2e + - name: Build Frontend & Electron run: yarn build @@ -109,8 +127,14 @@ jobs: - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 + - name: Test Lint + run: yarn lint + + - name: Test Unit + run: yarn test + - name: Build Frontend & Electron - run: yarn build:noTest + run: yarn build - name: Build/Release Electron app uses: samuelmeuli/action-electron-builder@v1 diff --git a/package.json b/package.json index d2338b807..779143dac 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,7 @@ "buildAllElectron:prod": "yarn preCheck && yarn buildFrontend:prod && yarn electron:build", "buildAllElectron:stage": "yarn preCheck && yarn buildFrontend:stage && yarn electron:build", "buildAllElectron:noTests:prod": "yarn lint && yarn buildFrontend:prod && yarn electron:build", - "build": "yarn preCheck && yarn buildAllElectron:prod", - "build:noTest": "yarn lint && yarn buildAllElectron:noTests:prod", + "build": "yarn buildAllElectron:prod", "buildApp": "yarn preCheck && yarn buildAllElectron:prod && yarn electron-builder", "test": "ng test --watch=false", "test:watch": "ng test --browsers ChromeHeadless", From 4450a1a50ec1c3312fac307ca7fb9bf87f53ab4a Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 11:56:56 +0200 Subject: [PATCH 051/131] build: fix syntax error --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9449a3f7f..afae6fb3a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,8 +36,8 @@ jobs: - name: Build/Release Electron app uses: samuelmeuli/action-electron-builder@v1 - build_script_name: empty with: + build_script_name: empty github_token: ${{ secrets.github_token }} release: ${{ startsWith(github.ref, 'refs/tags/v') }} From 70062e2a400d9c52bdb9f24d8c90fdf6c8fbd08a Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 11:58:45 +0200 Subject: [PATCH 052/131] build: fix naming --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index afae6fb3a..042c966f4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ jobs: - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 - - name: Test Lint + - name: Lint run: yarn lint - name: Test Unit @@ -86,7 +86,7 @@ jobs: mkdir -p ~/private_keys/ echo '${{ secrets.mac_api_key }}' > ~/private_keys/AuthKey_${{ secrets.mac_api_key_id }}.p8 - - name: Test Lint + - name: Lint run: yarn lint - name: Test Unit @@ -127,7 +127,7 @@ jobs: - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 - - name: Test Lint + - name: Lint run: yarn lint - name: Test Unit From 7594c0d0b4d829669ebc94240e24bad1adf34519 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 12:11:24 +0200 Subject: [PATCH 053/131] 5.9.7 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fc98f08b..f2f7b6884 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [5.9.7](https://github.com/johannesjo/super-productivity/compare/v5.9.6...v5.9.7) (2020-10-04) + + + ## [5.9.6](https://github.com/johannesjo/super-productivity/compare/v5.9.5...v5.9.6) (2020-10-04) diff --git a/package.json b/package.json index 779143dac..de60d88b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.6", + "version": "5.9.7", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "johannesjo (http://super-productivity.com)", From da08e7cf31f8246295e4d04eb894a825676f32ea Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 12:32:53 +0200 Subject: [PATCH 054/131] build: fix test & lint running twice --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index de60d88b8..1d3f6ab4d 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,8 @@ "buildAllElectron:prod": "yarn preCheck && yarn buildFrontend:prod && yarn electron:build", "buildAllElectron:stage": "yarn preCheck && yarn buildFrontend:stage && yarn electron:build", "buildAllElectron:noTests:prod": "yarn lint && yarn buildFrontend:prod && yarn electron:build", - "build": "yarn buildAllElectron:prod", - "buildApp": "yarn preCheck && yarn buildAllElectron:prod && yarn electron-builder", + "build": "yarn buildAllElectron:noTests:prod", + "buildApp": "yarn preCheck && yarn buildAllElectron:noTests:prod && yarn electron-builder", "test": "ng test --watch=false", "test:watch": "ng test --browsers ChromeHeadless", "lint": "ng lint", From 23be7fc01bc6c2a10f0fd800d47bc3b98661c89f Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 12:32:57 +0200 Subject: [PATCH 055/131] 5.9.8 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2f7b6884..04315003e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [5.9.8](https://github.com/johannesjo/super-productivity/compare/v5.9.7...v5.9.8) (2020-10-04) + + + ## [5.9.7](https://github.com/johannesjo/super-productivity/compare/v5.9.6...v5.9.7) (2020-10-04) diff --git a/package.json b/package.json index 1d3f6ab4d..82953720a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.7", + "version": "5.9.8", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "johannesjo (http://super-productivity.com)", From e14e3b1114374705ef5e0d9f5ef7b31324399729 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 13:22:52 +0200 Subject: [PATCH 056/131] build: add github action for automated webapp deploy after release --- .../build-update-web-app-on-release.yml | 42 +++++++++++++++++++ package.json | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/build-update-web-app-on-release.yml diff --git a/.github/workflows/build-update-web-app-on-release.yml b/.github/workflows/build-update-web-app-on-release.yml new file mode 100644 index 000000000..5e32ebdd3 --- /dev/null +++ b/.github/workflows/build-update-web-app-on-release.yml @@ -0,0 +1,42 @@ +name: Update Web App after Release +on: + release: + types: [released] + +jobs: + upload-to-app-super-productivity: + runs-on: ubuntu-latest + steps: + - name: Check out Git repository + uses: actions/checkout@v1 + + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v1 + with: + node-version: 12 + + - name: NPM or Yarn install with caching + uses: bahmutov/npm-install@v1.1.0 + + - name: Lint + run: yarn lint + + - name: Test Unit + run: yarn test + + - name: Test E2E + run: yarn e2e + + - name: Build Frontend & Electron + run: yarn buildFrontend:prodWeb + + - name: Deploy to Web Server + uses: easingthemes/ssh-deploy@v2.1.5 + env: + SSH_PRIVATE_KEY: ${{ secrets.WEB_SERVER_SSH_KEY }} + ARGS: "-rltgoDzvO --delete" + SOURCE: "dist/" + REMOTE_HOST: ${{ secrets.WEB_REMOTE_HOST }} + REMOTE_USER: ${{ secrets.WEB_REMOTE_USER }} + TARGET: ${{ secrets.WEB_REMOTE_TARGET }} + diff --git a/package.json b/package.json index 82953720a..73f20b18b 100644 --- a/package.json +++ b/package.json @@ -23,13 +23,13 @@ "startFrontend": "ng serve", "serveProd": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng serve --prod", "buildFrontend:prod": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --aot --prod", + "buildFrontend:prodWeb": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --aot --prod --configuration productionWeb", "buildFrontend:stage": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --aot --prod --configuration stage", "buildFrontend:prod:watch": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --aot --prod --watch", "buildAllElectron:prod": "yarn preCheck && yarn buildFrontend:prod && yarn electron:build", "buildAllElectron:stage": "yarn preCheck && yarn buildFrontend:stage && yarn electron:build", "buildAllElectron:noTests:prod": "yarn lint && yarn buildFrontend:prod && yarn electron:build", "build": "yarn buildAllElectron:noTests:prod", - "buildApp": "yarn preCheck && yarn buildAllElectron:noTests:prod && yarn electron-builder", "test": "ng test --watch=false", "test:watch": "ng test --browsers ChromeHeadless", "lint": "ng lint", From f772fb0ac2ba86f6b87c541975cfeb1f06f3bc29 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 13:23:59 +0200 Subject: [PATCH 057/131] build: fix automated webapp deploy after release --- .../build-update-web-app-on-release.yml | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/.github/workflows/build-update-web-app-on-release.yml b/.github/workflows/build-update-web-app-on-release.yml index 5e32ebdd3..4dd818adc 100644 --- a/.github/workflows/build-update-web-app-on-release.yml +++ b/.github/workflows/build-update-web-app-on-release.yml @@ -5,38 +5,40 @@ on: jobs: upload-to-app-super-productivity: + runs-on: ubuntu-latest - steps: - - name: Check out Git repository - uses: actions/checkout@v1 - - name: Install Node.js, NPM and Yarn - uses: actions/setup-node@v1 - with: - node-version: 12 + steps: + - name: Check out Git repository + uses: actions/checkout@v1 - - name: NPM or Yarn install with caching - uses: bahmutov/npm-install@v1.1.0 + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v1 + with: + node-version: 12 - - name: Lint - run: yarn lint + - name: NPM or Yarn install with caching + uses: bahmutov/npm-install@v1.1.0 - - name: Test Unit - run: yarn test + - name: Lint + run: yarn lint - - name: Test E2E - run: yarn e2e + - name: Test Unit + run: yarn test - - name: Build Frontend & Electron - run: yarn buildFrontend:prodWeb + - name: Test E2E + run: yarn e2e - - name: Deploy to Web Server - uses: easingthemes/ssh-deploy@v2.1.5 - env: - SSH_PRIVATE_KEY: ${{ secrets.WEB_SERVER_SSH_KEY }} - ARGS: "-rltgoDzvO --delete" - SOURCE: "dist/" - REMOTE_HOST: ${{ secrets.WEB_REMOTE_HOST }} - REMOTE_USER: ${{ secrets.WEB_REMOTE_USER }} - TARGET: ${{ secrets.WEB_REMOTE_TARGET }} + - name: Build Frontend & Electron + run: yarn buildFrontend:prodWeb + + - name: Deploy to Web Server + uses: easingthemes/ssh-deploy@v2.1.5 + env: + SSH_PRIVATE_KEY: ${{ secrets.WEB_SERVER_SSH_KEY }} + ARGS: "-rltgoDzvO --delete" + SOURCE: "dist/" + REMOTE_HOST: ${{ secrets.WEB_REMOTE_HOST }} + REMOTE_USER: ${{ secrets.WEB_REMOTE_USER }} + TARGET: ${{ secrets.WEB_REMOTE_TARGET }} From c2e3ff9681c45a6d00b563c93fcb07f5fc0339ac Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 14:25:26 +0200 Subject: [PATCH 058/131] build: add windows store artifact script --- .../build-create-windows-store-on-release.yml | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 .github/workflows/build-create-windows-store-on-release.yml diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml new file mode 100644 index 000000000..5ab5b34d7 --- /dev/null +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -0,0 +1,48 @@ +name: Create Win Store Release File on Release +on: + release: + types: [ released ] + +jobs: + + windows-store-artifact: + runs-on: windows-latest + + steps: + - name: Check out Git repository + uses: actions/checkout@v1 + + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v1 + with: + node-version: 12 + + - name: Load Electron Builder Config + run: 'echo "WIN_STORE_ELECTRON_BUILDER_YML" | base64 --decode > electron-builder.win-store.yaml' + shell: bash + env: + WIN_STORE_ELECTRON_BUILDER_YML: ${{secrets.WIN_STORE_ELECTRON_BUILDER_YML}} + + - name: NPM or Yarn install with caching + uses: bahmutov/npm-install@v1.1.0 + + - name: Lint + run: yarn lint + + - name: Test Unit + run: yarn test + + - name: Build Frontend & Electron + run: yarn dist:win:store + + - name: Build/Release Electron app + uses: samuelmeuli/action-electron-builder@v1 + with: + build_script_name: empty + release: false + + - name: 'Upload Artifact' + uses: actions/upload-artifact@v2 + with: + name: WinStoreReleas + path: app-builds/*.appx From a0e57e096fa8177d77101cc4b5dc25cada38e389 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 14:29:50 +0200 Subject: [PATCH 059/131] build: add custom dispatch for windows store artifact script --- .github/workflows/build-create-windows-store-on-release.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 5ab5b34d7..06d065784 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -1,5 +1,8 @@ name: Create Win Store Release File on Release on: + workflow_dispatch: + inputs: null + release: types: [ released ] From fef89b3be77025a5c22ff020348c82d832c43f07 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 14:31:21 +0200 Subject: [PATCH 060/131] build: add custom dispatch for web app release --- .github/workflows/build-update-web-app-on-release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-update-web-app-on-release.yml b/.github/workflows/build-update-web-app-on-release.yml index 4dd818adc..a9947d816 100644 --- a/.github/workflows/build-update-web-app-on-release.yml +++ b/.github/workflows/build-update-web-app-on-release.yml @@ -2,6 +2,8 @@ name: Update Web App after Release on: release: types: [released] + workflow_dispatch: + inputs: null jobs: upload-to-app-super-productivity: From 63fe26f27320a9dca237e91c22c3e40a74eed0af Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 14:33:22 +0200 Subject: [PATCH 061/131] build: fix windows store release --- .github/workflows/build-create-windows-store-on-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 06d065784..26afc8dac 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -21,7 +21,7 @@ jobs: node-version: 12 - name: Load Electron Builder Config - run: 'echo "WIN_STORE_ELECTRON_BUILDER_YML" | base64 --decode > electron-builder.win-store.yaml' + run: 'echo $WIN_STORE_ELECTRON_BUILDER_YML | base64 --decode > electron-builder.win-store.yaml' shell: bash env: WIN_STORE_ELECTRON_BUILDER_YML: ${{secrets.WIN_STORE_ELECTRON_BUILDER_YML}} From aeaa680836ea9470a75efadf475c1402bacc4ebd Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 14:42:56 +0200 Subject: [PATCH 062/131] build: fix windows store release --- .github/workflows/build-create-windows-store-on-release.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 26afc8dac..21856c2a2 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -21,10 +21,7 @@ jobs: node-version: 12 - name: Load Electron Builder Config - run: 'echo $WIN_STORE_ELECTRON_BUILDER_YML | base64 --decode > electron-builder.win-store.yaml' - shell: bash - env: - WIN_STORE_ELECTRON_BUILDER_YML: ${{secrets.WIN_STORE_ELECTRON_BUILDER_YML}} + run: echo ${{secrets.WIN_STORE_ELECTRON_BUILDER_YML}} | base64 --decode > electron-builder.win-store.yaml - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 From caa77e93d10f998b6ced7529f4e65dd8770032a4 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 14:48:36 +0200 Subject: [PATCH 063/131] build: fix windows store release --- .github/workflows/build-create-windows-store-on-release.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 21856c2a2..2b3148211 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -21,7 +21,9 @@ jobs: node-version: 12 - name: Load Electron Builder Config - run: echo ${{secrets.WIN_STORE_ELECTRON_BUILDER_YML}} | base64 --decode > electron-builder.win-store.yaml + run: echo $WIN_STORE_ELECTRON_BUILDER_YML | base64 --decode > electron-builder.win-store.yaml + env: + WIN_STORE_ELECTRON_BUILDER_YML: ${{secrets.WIN_STORE_ELECTRON_BUILDER_YML}} - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 From 3433d84c2a26b6603feef4a6f5038d6a0af0bda8 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 14:50:14 +0200 Subject: [PATCH 064/131] build: fix mac store release --- build/electron-builder.mas.yaml | 2 +- package.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/electron-builder.mas.yaml b/build/electron-builder.mas.yaml index 56c0e0a14..f455142d7 100644 --- a/build/electron-builder.mas.yaml +++ b/build/electron-builder.mas.yaml @@ -1,5 +1,5 @@ appId: com.super-productivity.app -#afterSign: build/scripts/notarize.js +afterSign: electron-builder-notarize files: - electron/**/* - "!electron/**/*.ts" diff --git a/package.json b/package.json index 73f20b18b..83943642f 100644 --- a/package.json +++ b/package.json @@ -54,9 +54,9 @@ "dist:win:only": "electron-builder --win", "dist:win:appx": "yarn buildAllElectron:prod && electron-builder --win --config=build/electron-builder.appx.yaml", "dist:win:store": "git pull && yarn && copy electron-builder.win-store.yaml electron-builder.yaml && yarn dist:win && git checkout electron-builder.yaml || git checkout electron-builder.yaml", - "dist:mac:dl": "cp dl.provisionprofile embedded.provisionprofile && electron-builder --mac", - "dist:mac:mas": "cp mas.provisionprofile embedded.provisionprofile; electron-builder --mac mas --config=build/electron-builder.mas.yaml", - "dist:mac:mas:dev": "cp mas-dev.provisionprofile embedded.provisionprofile; electron-builder --mac mas-dev --config=build/electron-builder.mas-dev.yaml", + "dist:mac:dl": "cp tools/mac-profiles/dl.provisionprofile embedded.provisionprofile && electron-builder --mac", + "dist:mac:mas": "cp tools/mac-profiles/mas.provisionprofile embedded.provisionprofile; electron-builder --mac mas --config=build/electron-builder.mas.yaml", + "dist:mac:mas:dev": "cp tools/mac-profiles/mas-dev.provisionprofile embedded.provisionprofile; electron-builder --mac mas-dev --config=build/electron-builder.mas-dev.yaml", "release": "yarn release.changelog && yarn dist", "release.changelog": "conventional-changelog -i CHANGELOG.md -s -p angular", "version": "yarn release.changelog && git add -A", From fb3dd42f029457b2814b61194bbd3f573df80b69 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 15:52:15 +0200 Subject: [PATCH 065/131] build: disable service worker for production --- angular.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/angular.json b/angular.json index c01b95438..705f1e600 100644 --- a/angular.json +++ b/angular.json @@ -66,7 +66,7 @@ "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true, - "serviceWorker": true + "serviceWorker": false }, "productionWeb": { "baseHref": "", From 4a8d4428eddb04d5544a57a02d045b432f25398d Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 15:53:18 +0200 Subject: [PATCH 066/131] build: disable service worker for production and stage --- angular.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/angular.json b/angular.json index 705f1e600..99d1dd763 100644 --- a/angular.json +++ b/angular.json @@ -115,7 +115,7 @@ "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true, - "serviceWorker": true + "serviceWorker": false } } }, From c3f5b1853530e463faaf35c115c6f79f37d0f83a Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 15:54:19 +0200 Subject: [PATCH 067/131] build: add stageWeb target --- angular.json | 24 ++++++++++++++++++++++++ package.json | 1 + 2 files changed, 25 insertions(+) diff --git a/angular.json b/angular.json index 99d1dd763..225f57c4b 100644 --- a/angular.json +++ b/angular.json @@ -116,6 +116,30 @@ "vendorChunk": false, "buildOptimizer": true, "serviceWorker": false + }, + "stageWeb": { + "budgets": [ + { + "type": "anyComponentStyle", + "maximumWarning": "6kb" + } + ], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "optimization": true, + "outputHashing": "all", + "sourceMap": true, + "extractCss": true, + "namedChunks": false, + "aot": true, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "serviceWorker": true } } }, diff --git a/package.json b/package.json index 83943642f..c8ffd55b1 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "buildFrontend:prod": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --aot --prod", "buildFrontend:prodWeb": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --aot --prod --configuration productionWeb", "buildFrontend:stage": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --aot --prod --configuration stage", + "buildFrontend:stageWeb": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --aot --prod --configuration stageWeb", "buildFrontend:prod:watch": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --aot --prod --watch", "buildAllElectron:prod": "yarn preCheck && yarn buildFrontend:prod && yarn electron:build", "buildAllElectron:stage": "yarn preCheck && yarn buildFrontend:stage && yarn electron:build", From 4fc74723613932cae01cefcbb80bbb74693facdd Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 16:09:51 +0200 Subject: [PATCH 068/131] build: fix windows store release --- .github/workflows/build-create-windows-store-on-release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 2b3148211..dac6ce5f4 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -42,6 +42,7 @@ jobs: with: build_script_name: empty release: false + github_token: ${{ secrets.github_token }} - name: 'Upload Artifact' uses: actions/upload-artifact@v2 From b70d9abc68561da41608e8e807806a33866ab1a4 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 16:31:26 +0200 Subject: [PATCH 069/131] build: fix on release scripts --- .../workflows/build-create-windows-store-on-release.yml | 8 ++++---- .github/workflows/build-update-web-app-on-release.yml | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index dac6ce5f4..9b540f482 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -1,16 +1,16 @@ name: Create Win Store Release File on Release on: + release: + types: [published] workflow_dispatch: inputs: null - release: - types: [ released ] - jobs: - windows-store-artifact: runs-on: windows-latest + if: "!github.event.release.prerelease" + steps: - name: Check out Git repository uses: actions/checkout@v1 diff --git a/.github/workflows/build-update-web-app-on-release.yml b/.github/workflows/build-update-web-app-on-release.yml index a9947d816..c3c8bf8f9 100644 --- a/.github/workflows/build-update-web-app-on-release.yml +++ b/.github/workflows/build-update-web-app-on-release.yml @@ -1,15 +1,16 @@ name: Update Web App after Release on: release: - types: [released] + types: [published] workflow_dispatch: inputs: null jobs: upload-to-app-super-productivity: - runs-on: ubuntu-latest + if: "!github.event.release.prerelease" + steps: - name: Check out Git repository uses: actions/checkout@v1 From 27c6dbc042aad182888cd65b35065bf1ff2884c9 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 16:33:15 +0200 Subject: [PATCH 070/131] build: fix windows store release script --- .../build-create-windows-store-on-release.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 9b540f482..e83e66970 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -15,16 +15,16 @@ jobs: - name: Check out Git repository uses: actions/checkout@v1 + - name: Load Electron Builder Windows Sotre Config + run: echo $WIN_STORE_ELECTRON_BUILDER_YML | base64 --decode > electron-builder.yaml + env: + WIN_STORE_ELECTRON_BUILDER_YML: ${{secrets.WIN_STORE_ELECTRON_BUILDER_YML}} + - name: Install Node.js, NPM and Yarn uses: actions/setup-node@v1 with: node-version: 12 - - name: Load Electron Builder Config - run: echo $WIN_STORE_ELECTRON_BUILDER_YML | base64 --decode > electron-builder.win-store.yaml - env: - WIN_STORE_ELECTRON_BUILDER_YML: ${{secrets.WIN_STORE_ELECTRON_BUILDER_YML}} - - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 @@ -35,7 +35,7 @@ jobs: run: yarn test - name: Build Frontend & Electron - run: yarn dist:win:store + run: yarn build - name: Build/Release Electron app uses: samuelmeuli/action-electron-builder@v1 From d932ca000a8f0983052feca6cb802b08466c0c34 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 16:35:59 +0200 Subject: [PATCH 071/131] build: execute lint and test only for PRs --- .github/workflows/lint-and-test-pr.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/lint-and-test-pr.yml b/.github/workflows/lint-and-test-pr.yml index e28f66faf..8d4dcc773 100644 --- a/.github/workflows/lint-and-test-pr.yml +++ b/.github/workflows/lint-and-test-pr.yml @@ -1,12 +1,6 @@ name: "Lint & Test PRs" -on: - push: - branches: [master] - - pull_request: - # The branches below must be a subset of the branches above - branches: [master] +on: [pull_request] jobs: test-on-linux: From ef21e82fbf4e193d0433acde10f94fbf38a0b9bc Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 16:53:06 +0200 Subject: [PATCH 072/131] docs: add better issue templates --- .../bug_report.md} | 13 ++++++---- .github/ISSUE_TEMPLATE/feature_request.md | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) rename .github/{ISSUE_TEMPLATE.md => ISSUE_TEMPLATE/bug_report.md} (75%) create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/bug_report.md similarity index 75% rename from .github/ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE/bug_report.md index d362cd2e9..0f5731525 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,5 +1,10 @@ +--- +name: Bug Report +labels: bug +--- + +!!! Please search the issues before creating one !!! --> ### Your Environment @@ -9,12 +14,10 @@ Please search the issues before creating one. --> * Browser Name and version: ### Expected Behavior - - + ### Current Behavior - - + ### Steps to Reproduce (for bugs) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..3038fb330 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,25 @@ +--- +name: Feature request +labels: enhancement +--- + + +## Problem Statement + +A clear and concise description of what the problem is. E.g. I'm always frustrated when [...] + +## :grey_question: Possible Solution + +A clear and concise description of what you want to happen. + +## :arrow_heading_up: Describe alternatives you've considered + +A clear and concise description of any alternative solutions or features you've considered. + +## :heavy_plus_sign: Additional context + +Add any other context about the problem here. e.g. related issues or existing pull requests. From 14347297ef45b3be3fe4c069135c500ffe3f985d Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 16:54:35 +0200 Subject: [PATCH 073/131] docs: make comment work for feature request --- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 3038fb330..4b49cf934 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Feature request labels: enhancement --- - Date: Sun, 4 Oct 2020 16:55:16 +0200 Subject: [PATCH 074/131] docs: make comment work for feature request --- .github/ISSUE_TEMPLATE/feature_request.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 4b49cf934..63386fa5f 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -9,17 +9,21 @@ Please also make sure that there is no similar feature already opened up! --> ## Problem Statement - + ## :grey_question: Possible Solution - + ## :arrow_heading_up: Describe alternatives you've considered - + ## :heavy_plus_sign: Additional context - + From 82ba2ace7981aae988db5ebe5b24bc8a406d65ee Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 16:58:32 +0200 Subject: [PATCH 075/131] docs: make feature request work --- .github/ISSUE_TEMPLATE/{bug_report.md => BUG_REPORT.md} | 0 .../ISSUE_TEMPLATE/{feature_request.md => FEATURE_REQUEST.md} | 4 ++++ 2 files changed, 4 insertions(+) rename .github/ISSUE_TEMPLATE/{bug_report.md => BUG_REPORT.md} (100%) rename .github/ISSUE_TEMPLATE/{feature_request.md => FEATURE_REQUEST.md} (90%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md similarity index 100% rename from .github/ISSUE_TEMPLATE/bug_report.md rename to .github/ISSUE_TEMPLATE/BUG_REPORT.md diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md similarity index 90% rename from .github/ISSUE_TEMPLATE/feature_request.md rename to .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md index 63386fa5f..d51489203 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md @@ -1,5 +1,9 @@ --- name: Feature request +about: Suggest an idea for this project +title: '' +labels: Feature Request +assignees: '' labels: enhancement --- -## :grey_question: Possible Solution - From d55e37e9a6e3055e9ae772f190cb7d3025daeeb6 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 17:23:12 +0200 Subject: [PATCH 077/131] build: fix windows store script? --- .../workflows/build-create-windows-store-on-release.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index e83e66970..5923a9b30 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -15,11 +15,18 @@ jobs: - name: Check out Git repository uses: actions/checkout@v1 - - name: Load Electron Builder Windows Sotre Config + - name: Load Electron Builder Windows Store Config run: echo $WIN_STORE_ELECTRON_BUILDER_YML | base64 --decode > electron-builder.yaml env: WIN_STORE_ELECTRON_BUILDER_YML: ${{secrets.WIN_STORE_ELECTRON_BUILDER_YML}} + - name: Load Electron Builder Windows Store Config + id: write_file + uses: timheuer/base64-to-file@v1.0.3 + with: + fileName: electron-builder.yaml + encodedString: ${{ secrets.WIN_STORE_ELECTRON_BUILDER_YML }} + - name: Install Node.js, NPM and Yarn uses: actions/setup-node@v1 with: From e66d7d3b1d27adc5a9d9726e0996e2437aecbf9f Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 17:35:13 +0200 Subject: [PATCH 078/131] build: implement custom cache for windows store script --- .../build-create-windows-store-on-release.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 5923a9b30..013470f11 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -27,13 +27,14 @@ jobs: fileName: electron-builder.yaml encodedString: ${{ secrets.WIN_STORE_ELECTRON_BUILDER_YML }} - - name: Install Node.js, NPM and Yarn - uses: actions/setup-node@v1 + - uses: actions/cache@v2 with: - node-version: 12 + path: '**/node_modules' + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - - name: NPM or Yarn install with caching - uses: bahmutov/npm-install@v1.1.0 + - name: Install yarn packages + if: steps.yarn-cache.outputs.cache-hit != 'true' + run: yarn install - name: Lint run: yarn lint From eaa4351d4c2667297d331abd32a3bf8722aa1847 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 17:45:27 +0200 Subject: [PATCH 079/131] build: manually cache everything --- .../build-create-windows-store-on-release.yml | 2 +- .../build-update-web-app-on-release.yml | 10 +++++-- .github/workflows/build.yml | 30 +++++++++++++------ .github/workflows/lint-and-test-pr.yml | 10 +++++-- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 013470f11..30be57d82 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -32,7 +32,7 @@ jobs: path: '**/node_modules' key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - - name: Install yarn packages + - name: Install Yarn Packages if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn install diff --git a/.github/workflows/build-update-web-app-on-release.yml b/.github/workflows/build-update-web-app-on-release.yml index c3c8bf8f9..e4b655938 100644 --- a/.github/workflows/build-update-web-app-on-release.yml +++ b/.github/workflows/build-update-web-app-on-release.yml @@ -20,8 +20,14 @@ jobs: with: node-version: 12 - - name: NPM or Yarn install with caching - uses: bahmutov/npm-install@v1.1.0 + - uses: actions/cache@v2 + with: + path: '**/node_modules' + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + + - name: Install Yarn Packages + if: steps.yarn-cache.outputs.cache-hit != 'true' + run: yarn install - name: Lint run: yarn lint diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 042c966f4..c736a22d3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,10 +14,14 @@ jobs: - name: Check out Git repository uses: actions/checkout@v1 - - name: Install Node.js, NPM and Yarn - uses: actions/setup-node@v1 + - uses: actions/cache@v2 with: - node-version: 12 + path: '**/node_modules' + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + + - name: Install Yarn Packages + if: steps.yarn-cache.outputs.cache-hit != 'true' + run: yarn install - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 @@ -67,10 +71,14 @@ jobs: - name: Check out Git repository uses: actions/checkout@v1 - - name: Install Node.js, NPM and Yarn - uses: actions/setup-node@v1 + - uses: actions/cache@v2 with: - node-version: 12 + path: '**/node_modules' + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + + - name: Install Yarn Packages + if: steps.yarn-cache.outputs.cache-hit != 'true' + run: yarn install - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 @@ -119,10 +127,14 @@ jobs: - name: Check out Git repository uses: actions/checkout@v1 - - name: Install Node.js, NPM and Yarn - uses: actions/setup-node@v1 + - uses: actions/cache@v2 with: - node-version: 12 + path: '**/node_modules' + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + + - name: Install Yarn Packages + if: steps.yarn-cache.outputs.cache-hit != 'true' + run: yarn install - name: NPM or Yarn install with caching uses: bahmutov/npm-install@v1.1.0 diff --git a/.github/workflows/lint-and-test-pr.yml b/.github/workflows/lint-and-test-pr.yml index 8d4dcc773..f4e24f2c9 100644 --- a/.github/workflows/lint-and-test-pr.yml +++ b/.github/workflows/lint-and-test-pr.yml @@ -15,8 +15,14 @@ jobs: with: node-version: 12 - - name: NPM or Yarn install with caching - uses: bahmutov/npm-install@v1.1.0 + - uses: actions/cache@v2 + with: + path: '**/node_modules' + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + + - name: Install Yarn Packages + if: steps.yarn-cache.outputs.cache-hit != 'true' + run: yarn install - run: yarn lint - run: yarn test From a8bbc3a5da945f284f39bba0d925a773946b1ed7 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 17:56:12 +0200 Subject: [PATCH 080/131] build: remove pre build stuff for now --- .../build-create-windows-store-on-release.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 30be57d82..6cec5e8e4 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -36,14 +36,14 @@ jobs: if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn install - - name: Lint - run: yarn lint - - - name: Test Unit - run: yarn test - - - name: Build Frontend & Electron - run: yarn build +# - name: Lint +# run: yarn lint +# +# - name: Test Unit +# run: yarn test +# +# - name: Build Frontend & Electron +# run: yarn build - name: Build/Release Electron app uses: samuelmeuli/action-electron-builder@v1 From 01a14ba88d057ee5dc6c2b626f43900a96cd4342 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 17:57:50 +0200 Subject: [PATCH 081/131] 5.9.9 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04315003e..dd710018d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [5.9.9](https://github.com/johannesjo/super-productivity/compare/v5.9.8...v5.9.9) (2020-10-04) + + + ## [5.9.8](https://github.com/johannesjo/super-productivity/compare/v5.9.7...v5.9.8) (2020-10-04) diff --git a/package.json b/package.json index c8ffd55b1..8de93e5ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.8", + "version": "5.9.9", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "johannesjo (http://super-productivity.com)", From 39eacc0843e7abc4d31700484b4a8cc752388257 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 19:23:35 +0200 Subject: [PATCH 082/131] build: add new decode --- .../workflows/build-create-windows-store-on-release.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 6cec5e8e4..801338de9 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -16,17 +16,10 @@ jobs: uses: actions/checkout@v1 - name: Load Electron Builder Windows Store Config - run: echo $WIN_STORE_ELECTRON_BUILDER_YML | base64 --decode > electron-builder.yaml + run: del /f electron-builder.yaml && (echo %WIN_STORE_ELECTRON_BUILDER_YML%) > out && certutil -decode out electron-builder.yaml env: WIN_STORE_ELECTRON_BUILDER_YML: ${{secrets.WIN_STORE_ELECTRON_BUILDER_YML}} - - name: Load Electron Builder Windows Store Config - id: write_file - uses: timheuer/base64-to-file@v1.0.3 - with: - fileName: electron-builder.yaml - encodedString: ${{ secrets.WIN_STORE_ELECTRON_BUILDER_YML }} - - uses: actions/cache@v2 with: path: '**/node_modules' From 0ffa1c05227bf698f92ca8c919ea6d7d6b3891dd Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 19:30:44 +0200 Subject: [PATCH 083/131] build: windows next attempt --- .github/workflows/build-create-windows-store-on-release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 801338de9..a23abfb80 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -16,7 +16,8 @@ jobs: uses: actions/checkout@v1 - name: Load Electron Builder Windows Store Config - run: del /f electron-builder.yaml && (echo %WIN_STORE_ELECTRON_BUILDER_YML%) > out && certutil -decode out electron-builder.yaml + run: echo $WIN_STORE_ELECTRON_BUILDER_YML | base64 --decode > electron-builder.yaml + shell: bash env: WIN_STORE_ELECTRON_BUILDER_YML: ${{secrets.WIN_STORE_ELECTRON_BUILDER_YML}} From b43cbeca2c907337ac5effee1394cb3de2e78b26 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 19:48:58 +0200 Subject: [PATCH 084/131] build: windows next attempt 2 --- .github/workflows/build-create-windows-store-on-release.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index a23abfb80..cca0b7e00 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -39,6 +39,9 @@ jobs: # - name: Build Frontend & Electron # run: yarn build + - name: Build Frontend & Electron + run: yarn build + - name: Build/Release Electron app uses: samuelmeuli/action-electron-builder@v1 with: From 70daed4f0079ebd164be10b3a4363ad91b772f3a Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 19:52:34 +0200 Subject: [PATCH 085/131] build: improve naming --- .github/workflows/build-create-windows-store-on-release.yml | 2 +- .github/workflows/build-update-web-app-on-release.yml | 2 +- .github/workflows/build.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index cca0b7e00..0821070ac 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -1,4 +1,4 @@ -name: Create Win Store Release File on Release +name: Win Store File on Release on: release: types: [published] diff --git a/.github/workflows/build-update-web-app-on-release.yml b/.github/workflows/build-update-web-app-on-release.yml index e4b655938..4f67b9c88 100644 --- a/.github/workflows/build-update-web-app-on-release.yml +++ b/.github/workflows/build-update-web-app-on-release.yml @@ -1,4 +1,4 @@ -name: Update Web App after Release +name: Web App on Release on: release: types: [published] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c736a22d3..e491391ae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Build & Release +name: Build All & Release on: push: branches: [ master, test/git-actions ] From e121641492b4801d86fd40038797d75cf757a567 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 20:02:21 +0200 Subject: [PATCH 086/131] build: remove duplicate depdency install --- .github/workflows/build.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e491391ae..6e8524157 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,9 +23,6 @@ jobs: if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn install - - name: NPM or Yarn install with caching - uses: bahmutov/npm-install@v1.1.0 - - name: Lint run: yarn lint @@ -80,9 +77,6 @@ jobs: if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn install - - name: NPM or Yarn install with caching - uses: bahmutov/npm-install@v1.1.0 - - run: 'echo "$PROVISION_PROFILE" | base64 --decode > embedded.provisionprofile' shell: bash env: @@ -136,9 +130,6 @@ jobs: if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn install - - name: NPM or Yarn install with caching - uses: bahmutov/npm-install@v1.1.0 - - name: Lint run: yarn lint From 269839255e35cf00ce7cd249ef34541084faa680 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 20:12:25 +0200 Subject: [PATCH 087/131] build: install only --- .../build-create-windows-store-on-release.yml | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 0821070ac..0a7683a20 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -30,27 +30,27 @@ jobs: if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn install -# - name: Lint -# run: yarn lint -# -# - name: Test Unit -# run: yarn test +## - name: Lint +## run: yarn lint +## +## - name: Test Unit +## run: yarn test +## +## - name: Build Frontend & Electron +## run: yarn build # # - name: Build Frontend & Electron # run: yarn build - - - name: Build Frontend & Electron - run: yarn build - - - name: Build/Release Electron app - uses: samuelmeuli/action-electron-builder@v1 - with: - build_script_name: empty - release: false - github_token: ${{ secrets.github_token }} - - - name: 'Upload Artifact' - uses: actions/upload-artifact@v2 - with: - name: WinStoreReleas - path: app-builds/*.appx +# +# - name: Build/Release Electron app +# uses: samuelmeuli/action-electron-builder@v1 +# with: +# build_script_name: empty +# release: false +# github_token: ${{ secrets.github_token }} +# +# - name: 'Upload Artifact' +# uses: actions/upload-artifact@v2 +# with: +# name: WinStoreReleas +# path: app-builds/*.appx From 3da8f375ef2f1ea2bb10e27290be2543141c3b15 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 20:15:00 +0200 Subject: [PATCH 088/131] build: windows store relase again again --- .../build-create-windows-store-on-release.yml | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 0a7683a20..0821070ac 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -30,27 +30,27 @@ jobs: if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn install -## - name: Lint -## run: yarn lint -## -## - name: Test Unit -## run: yarn test -## -## - name: Build Frontend & Electron -## run: yarn build +# - name: Lint +# run: yarn lint +# +# - name: Test Unit +# run: yarn test # # - name: Build Frontend & Electron # run: yarn build -# -# - name: Build/Release Electron app -# uses: samuelmeuli/action-electron-builder@v1 -# with: -# build_script_name: empty -# release: false -# github_token: ${{ secrets.github_token }} -# -# - name: 'Upload Artifact' -# uses: actions/upload-artifact@v2 -# with: -# name: WinStoreReleas -# path: app-builds/*.appx + + - name: Build Frontend & Electron + run: yarn build + + - name: Build/Release Electron app + uses: samuelmeuli/action-electron-builder@v1 + with: + build_script_name: empty + release: false + github_token: ${{ secrets.github_token }} + + - name: 'Upload Artifact' + uses: actions/upload-artifact@v2 + with: + name: WinStoreReleas + path: app-builds/*.appx From ac66dd0431ea145d2fadc4a5dd96dded2852bfa0 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 20:16:12 +0200 Subject: [PATCH 089/131] build: add mac store release script --- .../build-publish-to-mac-store-on-release.yml | 62 +++++++++++++++++++ package.json | 1 + 2 files changed, 63 insertions(+) create mode 100644 .github/workflows/build-publish-to-mac-store-on-release.yml diff --git a/.github/workflows/build-publish-to-mac-store-on-release.yml b/.github/workflows/build-publish-to-mac-store-on-release.yml new file mode 100644 index 000000000..753dc01a5 --- /dev/null +++ b/.github/workflows/build-publish-to-mac-store-on-release.yml @@ -0,0 +1,62 @@ +name: Mac Store Release on Release +on: + release: + types: [ published ] + workflow_dispatch: + inputs: null + +jobs: + windows-store-artifact: + runs-on: windows-latest + + if: "!github.event.release.prerelease" + + steps: + - name: Echo is Release + run: echo "IS_RELEASE $IS_RELEASE, ${{ startsWith(github.ref, 'refs/tags/v') }}" + env: + IS_RELEASE: ${{ startsWith(github.ref, 'refs/tags/v') }} + + - name: Check out Git repository + uses: actions/checkout@v1 + + - uses: actions/cache@v2 + with: + path: '**/node_modules' + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + + - name: Install Yarn Packages + if: steps.yarn-cache.outputs.cache-hit != 'true' + run: yarn install + + - run: 'echo "$PROVISION_PROFILE" | base64 --decode > embedded.provisionprofile' + shell: bash + env: + PROVISION_PROFILE: ${{secrets.mas_provision_profile}} + + - name: Lint + run: yarn lint + + - name: Test Unit + run: yarn test + + - name: Test E2E + run: yarn e2e + + - name: Build Frontend & Electron + run: yarn build + + - name: Build Electron app + run: dist:mac:mas:buildOnly + + - name: Validate App + run: xcrun altool --validate-app -f app-builds/mas/superProductivity-*.pkg -u $APPLEID -p APPLEIDPASS + env: + APPLEID: ${{secrets.APPLEID}} + APPLEIDPASS: ${{secrets.APPLEIDPASS}} + + - name: Push to Store + run: xcrun altool --upload-app -f app-builds/mas/superProductivity-*.pkg -u $APPLEID -p APPLEIDPASS + env: + APPLEID: ${{secrets.APPLEID}} + APPLEIDPASS: ${{secrets.APPLEIDPASS}} diff --git a/package.json b/package.json index 8de93e5ac..801408149 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "dist:win:store": "git pull && yarn && copy electron-builder.win-store.yaml electron-builder.yaml && yarn dist:win && git checkout electron-builder.yaml || git checkout electron-builder.yaml", "dist:mac:dl": "cp tools/mac-profiles/dl.provisionprofile embedded.provisionprofile && electron-builder --mac", "dist:mac:mas": "cp tools/mac-profiles/mas.provisionprofile embedded.provisionprofile; electron-builder --mac mas --config=build/electron-builder.mas.yaml", + "dist:mac:mas:buildOnly": "electron-builder --mac mas --config=build/electron-builder.mas.yaml", "dist:mac:mas:dev": "cp tools/mac-profiles/mas-dev.provisionprofile embedded.provisionprofile; electron-builder --mac mas-dev --config=build/electron-builder.mas-dev.yaml", "release": "yarn release.changelog && yarn dist", "release.changelog": "conventional-changelog -i CHANGELOG.md -s -p angular", From 32bf1ccc66ca62f1a5d6ab5d62fbfa01a1256bfb Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 20:17:04 +0200 Subject: [PATCH 090/131] build: fix mac store release script --- .github/workflows/build-publish-to-mac-store-on-release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-publish-to-mac-store-on-release.yml b/.github/workflows/build-publish-to-mac-store-on-release.yml index 753dc01a5..0a3943563 100644 --- a/.github/workflows/build-publish-to-mac-store-on-release.yml +++ b/.github/workflows/build-publish-to-mac-store-on-release.yml @@ -13,9 +13,9 @@ jobs: steps: - name: Echo is Release - run: echo "IS_RELEASE $IS_RELEASE, ${{ startsWith(github.ref, 'refs/tags/v') }}" - env: - IS_RELEASE: ${{ startsWith(github.ref, 'refs/tags/v') }} + run: echo "IS_RELEASE $IS_RELEASE, ${{ startsWith(github.ref, 'refs/tags/v') }}" + env: + IS_RELEASE: ${{ startsWith(github.ref, 'refs/tags/v') }} - name: Check out Git repository uses: actions/checkout@v1 From 24f943d2c70805cee326a75ca027d5ab61c030b1 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 20:35:47 +0200 Subject: [PATCH 091/131] build: adjust mac release script for install only --- .../build-publish-to-mac-store-on-release.yml | 69 +++++++++---------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/.github/workflows/build-publish-to-mac-store-on-release.yml b/.github/workflows/build-publish-to-mac-store-on-release.yml index 0a3943563..34b11bf74 100644 --- a/.github/workflows/build-publish-to-mac-store-on-release.yml +++ b/.github/workflows/build-publish-to-mac-store-on-release.yml @@ -6,17 +6,12 @@ on: inputs: null jobs: - windows-store-artifact: + mac-store-release: runs-on: windows-latest if: "!github.event.release.prerelease" steps: - - name: Echo is Release - run: echo "IS_RELEASE $IS_RELEASE, ${{ startsWith(github.ref, 'refs/tags/v') }}" - env: - IS_RELEASE: ${{ startsWith(github.ref, 'refs/tags/v') }} - - name: Check out Git repository uses: actions/checkout@v1 @@ -29,34 +24,34 @@ jobs: if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn install - - run: 'echo "$PROVISION_PROFILE" | base64 --decode > embedded.provisionprofile' - shell: bash - env: - PROVISION_PROFILE: ${{secrets.mas_provision_profile}} - - - name: Lint - run: yarn lint - - - name: Test Unit - run: yarn test - - - name: Test E2E - run: yarn e2e - - - name: Build Frontend & Electron - run: yarn build - - - name: Build Electron app - run: dist:mac:mas:buildOnly - - - name: Validate App - run: xcrun altool --validate-app -f app-builds/mas/superProductivity-*.pkg -u $APPLEID -p APPLEIDPASS - env: - APPLEID: ${{secrets.APPLEID}} - APPLEIDPASS: ${{secrets.APPLEIDPASS}} - - - name: Push to Store - run: xcrun altool --upload-app -f app-builds/mas/superProductivity-*.pkg -u $APPLEID -p APPLEIDPASS - env: - APPLEID: ${{secrets.APPLEID}} - APPLEIDPASS: ${{secrets.APPLEIDPASS}} +# - run: 'echo "$PROVISION_PROFILE" | base64 --decode > embedded.provisionprofile' +# shell: bash +# env: +# PROVISION_PROFILE: ${{secrets.mas_provision_profile}} +# +# - name: Lint +# run: yarn lint +# +# - name: Test Unit +# run: yarn test +# +## - name: Test E2E +## run: yarn e2e +# +# - name: Build Frontend & Electron +# run: yarn build +# +# - name: Build Electron app +# run: dist:mac:mas:buildOnly +# +# - name: Validate App +# run: xcrun altool --validate-app -f app-builds/mas/superProductivity-*.pkg -u $APPLEID -p APPLEIDPASS +# env: +# APPLEID: ${{secrets.APPLEID}} +# APPLEIDPASS: ${{secrets.APPLEIDPASS}} +# +# - name: Push to Store +# run: xcrun altool --upload-app -f app-builds/mas/superProductivity-*.pkg -u $APPLEID -p APPLEIDPASS +# env: +# APPLEID: ${{secrets.APPLEID}} +# APPLEIDPASS: ${{secrets.APPLEIDPASS}} From 85f09c073844d703d46160088a663623b25cf4e0 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 20:39:10 +0200 Subject: [PATCH 092/131] build: adjust mac release script --- .../build-publish-to-mac-store-on-release.yml | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/.github/workflows/build-publish-to-mac-store-on-release.yml b/.github/workflows/build-publish-to-mac-store-on-release.yml index 34b11bf74..b8ba268a8 100644 --- a/.github/workflows/build-publish-to-mac-store-on-release.yml +++ b/.github/workflows/build-publish-to-mac-store-on-release.yml @@ -24,34 +24,34 @@ jobs: if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn install -# - run: 'echo "$PROVISION_PROFILE" | base64 --decode > embedded.provisionprofile' -# shell: bash -# env: -# PROVISION_PROFILE: ${{secrets.mas_provision_profile}} -# -# - name: Lint -# run: yarn lint -# -# - name: Test Unit -# run: yarn test -# -## - name: Test E2E -## run: yarn e2e -# -# - name: Build Frontend & Electron -# run: yarn build -# -# - name: Build Electron app -# run: dist:mac:mas:buildOnly -# -# - name: Validate App -# run: xcrun altool --validate-app -f app-builds/mas/superProductivity-*.pkg -u $APPLEID -p APPLEIDPASS -# env: -# APPLEID: ${{secrets.APPLEID}} -# APPLEIDPASS: ${{secrets.APPLEIDPASS}} -# -# - name: Push to Store -# run: xcrun altool --upload-app -f app-builds/mas/superProductivity-*.pkg -u $APPLEID -p APPLEIDPASS -# env: -# APPLEID: ${{secrets.APPLEID}} -# APPLEIDPASS: ${{secrets.APPLEIDPASS}} + - run: 'echo "$PROVISION_PROFILE" | base64 --decode > embedded.provisionprofile' + shell: bash + env: + PROVISION_PROFILE: ${{secrets.mas_provision_profile}} + + - name: Lint + run: yarn lint + + - name: Test Unit + run: yarn test + +# - name: Test E2E +# run: yarn e2e + + - name: Build Frontend & Electron + run: yarn build + + - name: Build Electron app + run: dist:mac:mas:buildOnly + + - name: Validate App + run: xcrun altool --validate-app -f app-builds/mas/superProductivity-*.pkg -u $APPLEID -p APPLEIDPASS + env: + APPLEID: ${{secrets.APPLEID}} + APPLEIDPASS: ${{secrets.APPLEIDPASS}} + + - name: Push to Store + run: xcrun altool --upload-app -f app-builds/mas/superProductivity-*.pkg -u $APPLEID -p APPLEIDPASS + env: + APPLEID: ${{secrets.APPLEID}} + APPLEIDPASS: ${{secrets.APPLEIDPASS}} From 7380f09f49838a454387ebadad9ac69f1010ba00 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 20:42:29 +0200 Subject: [PATCH 093/131] build: fix typo --- .github/workflows/build-create-windows-store-on-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 0821070ac..9021cafb1 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -52,5 +52,5 @@ jobs: - name: 'Upload Artifact' uses: actions/upload-artifact@v2 with: - name: WinStoreReleas + name: WinStoreRelease path: app-builds/*.appx From 6283953d4b0b2a74b9c56f8ee51d156300130189 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 20:46:30 +0200 Subject: [PATCH 094/131] build: re-add lint and test for windows store build --- .../build-create-windows-store-on-release.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index 9021cafb1..82f6997db 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -30,14 +30,11 @@ jobs: if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn install -# - name: Lint -# run: yarn lint -# -# - name: Test Unit -# run: yarn test -# -# - name: Build Frontend & Electron -# run: yarn build + - name: Lint + run: yarn lint + + - name: Test Unit + run: yarn test - name: Build Frontend & Electron run: yarn build From 5901f57b86da6acff686a2f574a66cc0e6d11757 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 20:49:05 +0200 Subject: [PATCH 095/131] build: fix mac release script --- .github/workflows/build-publish-to-mac-store-on-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-publish-to-mac-store-on-release.yml b/.github/workflows/build-publish-to-mac-store-on-release.yml index b8ba268a8..3b3ae26d5 100644 --- a/.github/workflows/build-publish-to-mac-store-on-release.yml +++ b/.github/workflows/build-publish-to-mac-store-on-release.yml @@ -42,7 +42,7 @@ jobs: run: yarn build - name: Build Electron app - run: dist:mac:mas:buildOnly + run: yarn dist:mac:mas:buildOnly - name: Validate App run: xcrun altool --validate-app -f app-builds/mas/superProductivity-*.pkg -u $APPLEID -p APPLEIDPASS From 3b45d4528267b1d92eb80d206ba3266cd3c3aea1 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 21:00:10 +0200 Subject: [PATCH 096/131] build: fix wrong platform for mac release script... --- .github/workflows/build-publish-to-mac-store-on-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-publish-to-mac-store-on-release.yml b/.github/workflows/build-publish-to-mac-store-on-release.yml index 3b3ae26d5..17c35a9a8 100644 --- a/.github/workflows/build-publish-to-mac-store-on-release.yml +++ b/.github/workflows/build-publish-to-mac-store-on-release.yml @@ -7,7 +7,7 @@ on: jobs: mac-store-release: - runs-on: windows-latest + runs-on: macos-latest if: "!github.event.release.prerelease" From 8bb6115435a9759b88c0da55fa899732736e0c31 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 21:20:39 +0200 Subject: [PATCH 097/131] build: add certificates for mac release script... --- .github/workflows/build-publish-to-mac-store-on-release.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build-publish-to-mac-store-on-release.yml b/.github/workflows/build-publish-to-mac-store-on-release.yml index 17c35a9a8..1533643c0 100644 --- a/.github/workflows/build-publish-to-mac-store-on-release.yml +++ b/.github/workflows/build-publish-to-mac-store-on-release.yml @@ -41,6 +41,11 @@ jobs: - name: Build Frontend & Electron run: yarn build + - uses: apple-actions/import-codesign-certs@v1 + with: + p12-file-base64: ${{ secrets.mac_certs }} + p12-password: ${{ secrets.mac_certs_password }} + - name: Build Electron app run: yarn dist:mac:mas:buildOnly From 19600eaed4d29db8323937671a6193fc5bfecc2e Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 21:38:46 +0200 Subject: [PATCH 098/131] build: provide secrets differently --- .github/workflows/build-publish-to-mac-store-on-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-publish-to-mac-store-on-release.yml b/.github/workflows/build-publish-to-mac-store-on-release.yml index 1533643c0..2715af230 100644 --- a/.github/workflows/build-publish-to-mac-store-on-release.yml +++ b/.github/workflows/build-publish-to-mac-store-on-release.yml @@ -50,13 +50,13 @@ jobs: run: yarn dist:mac:mas:buildOnly - name: Validate App - run: xcrun altool --validate-app -f app-builds/mas/superProductivity-*.pkg -u $APPLEID -p APPLEIDPASS + run: xcrun altool --validate-app -f app-builds/mas/superProductivity-*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} env: APPLEID: ${{secrets.APPLEID}} APPLEIDPASS: ${{secrets.APPLEIDPASS}} - name: Push to Store - run: xcrun altool --upload-app -f app-builds/mas/superProductivity-*.pkg -u $APPLEID -p APPLEIDPASS + run: xcrun altool --upload-app -f app-builds/mas/superProductivity-*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} env: APPLEID: ${{secrets.APPLEID}} APPLEIDPASS: ${{secrets.APPLEIDPASS}} From e4a209dcf703b49395ac8fcafbba67923afb1208 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 22:21:32 +0200 Subject: [PATCH 099/131] 5.9.10 --- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd710018d..64b863397 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## [5.9.10](https://github.com/johannesjo/super-productivity/compare/v5.9.2...v5.9.10) (2020-10-04) + + +### Features + +* set first day of the week [#528](https://github.com/johannesjo/super-productivity/issues/528) ([b83bfea](https://github.com/johannesjo/super-productivity/commit/b83bfeafc6fd1c8258da9b7a040815f578d2dbc7)) +* set first day of week in DateAdapter ([6b9c5e7](https://github.com/johannesjo/super-productivity/commit/6b9c5e72692367cbb50f51e0e2a8fd94572be0d4)) + + + ## [5.9.9](https://github.com/johannesjo/super-productivity/compare/v5.9.8...v5.9.9) (2020-10-04) diff --git a/package.json b/package.json index 801408149..f105b22bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.9", + "version": "5.9.10", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "johannesjo (http://super-productivity.com)", From 7d00652eb9212a80b4a48c487f91623a41fdd11d Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sat, 3 Oct 2020 21:25:11 +0200 Subject: [PATCH 100/131] feat(autoBackupRestore): outline #553 --- electron/backup.ts | 15 +++-- electron/better-ipc.ts | 55 +++++++++++++++++++ electron/main.ts | 6 +- src/app/core/electron/electron.service.ts | 47 ++++++++++++++++ .../imex/local-backup/local-backup.service.ts | 11 ++++ 5 files changed, 127 insertions(+), 7 deletions(-) create mode 100644 electron/better-ipc.ts diff --git a/electron/backup.ts b/electron/backup.ts index 61f19fc7e..87a29773a 100644 --- a/electron/backup.ts +++ b/electron/backup.ts @@ -1,10 +1,17 @@ -import { app } from 'electron'; +import { app, ipcMain } from 'electron'; import { existsSync, mkdirSync, writeFileSync } from 'fs'; +import { IPC } from './ipc-events.const'; -export const BACKUP_DIR = `${app.getPath('userData')}/backups`; -console.log('Saving backups to', BACKUP_DIR); +let BACKUP_DIR = `${app.getPath('userData')}/backups`; -export function backupData(ev, data) { +export function initBackupAdapter(backupDir: string) { + BACKUP_DIR = backupDir; + console.log('Saving backups to', BACKUP_DIR); + + ipcMain.on(IPC.BACKUP, backupData); +} + +function backupData(ev, data) { if (!existsSync(BACKUP_DIR)) { mkdirSync(BACKUP_DIR); } diff --git a/electron/better-ipc.ts b/electron/better-ipc.ts new file mode 100644 index 000000000..921252e71 --- /dev/null +++ b/electron/better-ipc.ts @@ -0,0 +1,55 @@ +import { BrowserWindow, ipcMain, IpcMainEvent } from 'electron'; + +// TODO make available for both +const getSendChannel = channel => `%better-ipc-send-channel-${channel}`; + +// TODO add all typing +export const answerRenderer = (browserWindowOrChannel, channelOrCallback, callbackOrNothing?) => { + let window; + let channel; + let callback; + + if (callbackOrNothing === undefined) { + channel = browserWindowOrChannel; + callback = channelOrCallback; + } else { + window = browserWindowOrChannel; + channel = channelOrCallback; + callback = callbackOrNothing; + + if (!window) { + throw new Error('Browser window required'); + } + } + + const sendChannel = getSendChannel(channel); + + const listener = async (event: IpcMainEvent, data) => { + const browserWindow: BrowserWindow | null = BrowserWindow.fromWebContents(event.sender); + + if (window && window.id !== browserWindow?.id) { + return; + } + + const send = (channelI, dataI) => { + if (!(browserWindow && browserWindow.isDestroyed())) { + event.sender.send(channelI, dataI); + } + }; + + const {dataChannel, errorChannel, userData} = data; + + try { + send(dataChannel, await callback(userData, browserWindow)); + } catch (error) { + // send(errorChannel, serializeError(error)); + send(errorChannel, error); + } + }; + + ipcMain.on(sendChannel, listener); + + return () => { + ipcMain.off(sendChannel, listener); + }; +}; diff --git a/electron/main.ts b/electron/main.ts index 041150658..e6f332441 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -14,7 +14,7 @@ import { initGoogleAuth } from './google-auth'; import { errorHandler } from './error-handler'; import { initDebug } from './debug'; import { IPC } from './ipc-events.const'; -import { backupData } from './backup'; +import { initBackupAdapter } from './backup'; import { JiraCfg } from '../src/app/features/issue/providers/jira/jira.model'; import { KeyboardConfig } from '../src/app/features/config/global-config.model'; import lockscreen from './lockscreen'; @@ -51,6 +51,7 @@ process.argv.forEach((val) => { isShowDevTools = true; } }); +const BACKUP_DIR = `${app.getPath('userData')}/backups`; interface MyApp extends App { isQuiting?: boolean; @@ -100,6 +101,7 @@ appIN.on('certificate-error', (event, webContents, url, error, certificate, call // ------------------- appIN.on('ready', createMainWin); appIN.on('ready', createIndicator); +appIN.on('ready', () => initBackupAdapter(BACKUP_DIR)); appIN.on('activate', () => { // On OS X it's common to re-create a window in the app when the @@ -195,8 +197,6 @@ ipcMain.on(IPC.SHUTDOWN_NOW, quitAppNow); ipcMain.on(IPC.EXEC, exec); -ipcMain.on(IPC.BACKUP, backupData); - ipcMain.on(IPC.LOCK_SCREEN, () => { if (isLocked) { return; diff --git a/src/app/core/electron/electron.service.ts b/src/app/core/electron/electron.service.ts index 543ed0fcc..21d7ab5ba 100644 --- a/src/app/core/electron/electron.service.ts +++ b/src/app/core/electron/electron.service.ts @@ -6,6 +6,20 @@ import { IS_ELECTRON } from '../../app.constants'; import { getElectron } from '../../util/get-electron'; import * as ElectronRenderer from 'electron/renderer'; +// TODO make available for both +export const getSendChannel = (channel: string) => `%better-ipc-send-channel-${channel}`; +const getUniqueId = () => `${Date.now()}-${Math.random()}`; + +// const getRendererSendChannel = (windowId, channel) => `%better-ipc-send-channel-${windowId}-${channel}`; +const getResponseChannels = (channel: string) => { + const id = getUniqueId(); + return { + sendChannel: getSendChannel(channel), + dataChannel: `%better-ipc-response-data-channel-${channel}-${id}`, + errorChannel: `%better-ipc-response-error-channel-${channel}-${id}` + }; +}; + @Injectable({providedIn: 'root'}) export class ElectronService { ipcRenderer?: typeof ipcRenderer; @@ -57,4 +71,37 @@ export class ElectronService { public get process(): any { return this.remote ? this.remote.process : null; } + + public callMain(channel: string, data: unknown) { + return new Promise((resolve, reject) => { + const {sendChannel, dataChannel, errorChannel} = getResponseChannels(channel); + + const cleanup = () => { + (this.ipcRenderer as typeof ipcRenderer).off(dataChannel, onData); + (this.ipcRenderer as typeof ipcRenderer).off(errorChannel, onError); + }; + + const onData = (event: unknown, result: unknown) => { + cleanup(); + resolve(result); + }; + + const onError = (event: unknown, error: unknown) => { + cleanup(); + // reject(deserializeError(error)); + reject(error); + }; + + (this.ipcRenderer as typeof ipcRenderer).once(dataChannel, onData); + (this.ipcRenderer as typeof ipcRenderer).once(errorChannel, onError); + + const completeData = { + dataChannel, + errorChannel, + userData: data + }; + + (this.ipcRenderer as typeof ipcRenderer).send(sendChannel, completeData); + }); + } } diff --git a/src/app/imex/local-backup/local-backup.service.ts b/src/app/imex/local-backup/local-backup.service.ts index 4ea6fedcd..3a08ae938 100644 --- a/src/app/imex/local-backup/local-backup.service.ts +++ b/src/app/imex/local-backup/local-backup.service.ts @@ -32,6 +32,17 @@ export class LocalBackupService { this._triggerBackups.subscribe(); } + // TODO return backup info + isBackupAvailable(): Promise { + // return this._electronService.callMain(IPC.DB_SAVE, {key, data: JSON.stringify(dataIn)} as any); + return Promise.resolve(true); + } + + restoreBackup(): void { + // return this._electronService.callMain(IPC.DB_SAVE, {key, data: JSON.stringify(dataIn)} as any); + + } + private async _backup() { const data = await this._dataImportService.getCompleteSyncData(); (this._electronService.ipcRenderer as typeof ipcRenderer).send(IPC.BACKUP, data); From bdd3cbc49649a6e8d6e7dee613932d9fd4dbe688 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 22:20:09 +0200 Subject: [PATCH 101/131] =?UTF-8?q?feat(autoBackupRestore):=20implement=20?= =?UTF-8?q?most=20basic=20variant=20=E2=80=93=20circular=20dependency=20#5?= =?UTF-8?q?53?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron/backup.ts | 35 +++++++++++++++++-- electron/ipc-events.const.ts | 3 ++ src/app/core/data-init/data-init.service.ts | 24 +++++++++++++ src/app/features/reminder/reminder.module.ts | 24 ++++++++++--- src/app/features/reminder/reminder.service.ts | 25 ++++--------- .../imex/local-backup/local-backup.model.ts | 5 +++ .../imex/local-backup/local-backup.service.ts | 17 +++++---- 7 files changed, 100 insertions(+), 33 deletions(-) create mode 100644 src/app/imex/local-backup/local-backup.model.ts diff --git a/electron/backup.ts b/electron/backup.ts index 87a29773a..ea62e1181 100644 --- a/electron/backup.ts +++ b/electron/backup.ts @@ -1,14 +1,45 @@ import { app, ipcMain } from 'electron'; -import { existsSync, mkdirSync, writeFileSync } from 'fs'; +import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'fs'; import { IPC } from './ipc-events.const'; +import { answerRenderer } from './better-ipc'; +import { LocalBackupMeta } from '../src/app/imex/local-backup/local-backup.model'; +import * as path from 'path'; -let BACKUP_DIR = `${app.getPath('userData')}/backups`; +let BACKUP_DIR: string = `${app.getPath('userData')}/backups`; export function initBackupAdapter(backupDir: string) { BACKUP_DIR = backupDir; console.log('Saving backups to', BACKUP_DIR); + // BACKUP ipcMain.on(IPC.BACKUP, backupData); + + // IS_BACKUP_AVAILABLE + answerRenderer(IPC.BACKUP_IS_AVAILABLE, (): LocalBackupMeta | false => { + if (!existsSync(BACKUP_DIR)) { + return false; + } + + const files = readdirSync(BACKUP_DIR); + if (!files.length) { + return false; + } + const filesWithMeta: LocalBackupMeta[] = files.map((fileName: string): LocalBackupMeta => ({ + path: path.join(BACKUP_DIR, fileName), + folder: BACKUP_DIR, + created: statSync(path.join(BACKUP_DIR, fileName)).mtime.getTime() + })); + + filesWithMeta.sort((a: LocalBackupMeta, b: LocalBackupMeta) => a.created - b.created); + console.log('Avilable Backup Files: ', filesWithMeta); + return filesWithMeta.reverse()[0]; + }); + + // RESTORE_BACKUP + answerRenderer(IPC.BACKUP_RESTORE, (backupPath): string => { + console.log('Reading backup file: ', backupPath); + return readFileSync(backupPath, {encoding: 'utf8'}); + }); } function backupData(ev, data) { diff --git a/electron/ipc-events.const.ts b/electron/ipc-events.const.ts index 972976845..1d5adfcce 100644 --- a/electron/ipc-events.const.ts +++ b/electron/ipc-events.const.ts @@ -35,6 +35,9 @@ export enum IPC { EXEC = 'EXEC', BACKUP = 'BACKUP_APP_DATA', + BACKUP_IS_AVAILABLE = 'BACKUP_IS_AVAILABLE', + BACKUP_RESTORE = 'BACKUP_RESTORE', + SET_PROGRESS_BAR = 'SET_PROGRESS_BAR', NOTIFY_ON_CLOSE = 'NOTIFY_ON_CLOSE', diff --git a/src/app/core/data-init/data-init.service.ts b/src/app/core/data-init/data-init.service.ts index 0f8c369bc..8a6e650b0 100644 --- a/src/app/core/data-init/data-init.service.ts +++ b/src/app/core/data-init/data-init.service.ts @@ -11,6 +11,9 @@ import { MigrationService } from '../migration/migration.service'; import { loadAllData } from '../../root-store/meta/load-all-data.action'; import { isValidAppData } from '../../imex/sync/is-valid-app-data.util'; import { DataRepairService } from '../data-repair/data-repair.service'; +import { LocalBackupService } from '../../imex/local-backup/local-backup.service'; +import { IS_ELECTRON } from '../../app.constants'; +import { AppDataComplete } from '../../imex/sync/sync.model'; @Injectable({providedIn: 'root'}) export class DataInitService { @@ -36,6 +39,8 @@ export class DataInitService { private _workContextService: WorkContextService, private _store$: Store, private _dataRepairService: DataRepairService, + // private _dataImportService: DataImportService, + private _localBackupService: LocalBackupService, ) { // TODO better construction than this this.isAllDataLoadedInitially$.pipe( @@ -53,6 +58,7 @@ export class DataInitService { const isValid = isValidAppData(appDataComplete); if (isValid) { this._store$.dispatch(loadAllData({appDataComplete, isOmitTokens})); + this._checkForBackupIfEmpty(appDataComplete); } else { if (this._dataRepairService.isRepairPossibleAndConfirmed(appDataComplete)) { const fixedData = this._dataRepairService.repairData(appDataComplete); @@ -63,4 +69,22 @@ export class DataInitService { } } } + + private async _checkForBackupIfEmpty(appDataComplete: AppDataComplete) { + console.log(IS_ELECTRON, appDataComplete); + + if (IS_ELECTRON) { + if (appDataComplete.task.ids.length === 0 && appDataComplete.taskArchive.ids.length === 0) { + const r = await this._localBackupService.isBackupAvailable(); + if (r) { + console.log(r); + if (confirm('NO TASK DATA IMPORT BACKUP FROM?' + r.path)) { + const d = await this._localBackupService.loadBackup(r.path); + console.log(d); + // await this._dataImportService.importCompleteSyncData(JSON.parse(d)); + } + } + } + } + } } diff --git a/src/app/features/reminder/reminder.module.ts b/src/app/features/reminder/reminder.module.ts index baf9705fc..b6816d91b 100644 --- a/src/app/features/reminder/reminder.module.ts +++ b/src/app/features/reminder/reminder.module.ts @@ -5,7 +5,7 @@ import { NoteModule } from '../note/note.module'; import { MatDialog } from '@angular/material/dialog'; import { IS_ELECTRON } from '../../app.constants'; import { TasksModule } from '../tasks/tasks.module'; -import { filter } from 'rxjs/operators'; +import { concatMap, filter, first } from 'rxjs/operators'; import { Reminder } from './reminder.model'; import { UiHelperService } from '../ui-helper/ui-helper.service'; import { NotifyService } from '../../core/notify/notify.service'; @@ -13,6 +13,10 @@ import { DialogViewNoteReminderComponent } from '../note/dialog-view-note-remind import { DialogViewTaskRemindersComponent } from '../tasks/dialog-view-task-reminders/dialog-view-task-reminders.component'; import { DataInitService } from '../../core/data-init/data-init.service'; import { throttle } from 'helpful-decorators'; +import { merge, timer } from 'rxjs'; +import { SyncService } from '../../imex/sync/sync.service'; + +const MAX_WAIT_FOR_INITIAL_SYNC = 25000; @NgModule({ declarations: [], @@ -29,10 +33,22 @@ export class ReminderModule { private readonly _uiHelperService: UiHelperService, private readonly _notifyService: NotifyService, private readonly _dataInitService: DataInitService, + private readonly _syncService: SyncService, ) { - this._dataInitService.isAllDataLoadedInitially$.subscribe(() => { - _reminderService.init(); - }); + + this._dataInitService.isAllDataLoadedInitially$.pipe(concatMap(() => + + // we do this to wait for syncing and the like + merge( + this._syncService.afterInitialSyncDoneAndDataLoadedInitially$, + timer(MAX_WAIT_FOR_INITIAL_SYNC), + ).pipe( + first(), + ))) + .subscribe(async () => { + _reminderService.init(); + }); + this._reminderService.onRemindersActive$.pipe( // NOTE: we simply filter for open dialogs, as reminders are re-queried quite often filter((reminder) => this._matDialog.openDialogs.length === 0 && !!reminder && reminder.length > 0), diff --git a/src/app/features/reminder/reminder.service.ts b/src/app/features/reminder/reminder.service.ts index df2067279..60b32a712 100644 --- a/src/app/features/reminder/reminder.service.ts +++ b/src/app/features/reminder/reminder.service.ts @@ -3,7 +3,7 @@ import { PersistenceService } from '../../core/persistence/persistence.service'; import { RecurringConfig, Reminder, ReminderCopy, ReminderType } from './reminder.model'; import { SnackService } from '../../core/snack/snack.service'; import * as shortid from 'shortid'; -import { BehaviorSubject, merge, Observable, ReplaySubject, Subject, timer } from 'rxjs'; +import { BehaviorSubject, Observable, ReplaySubject, Subject } from 'rxjs'; import { dirtyDeepCopy } from '../../util/dirtyDeepCopy'; import { ImexMetaService } from '../../imex/imex-meta/imex-meta.service'; import { TaskService } from '../tasks/task.service'; @@ -11,14 +11,12 @@ import { Note } from '../note/note.model'; import { Task } from '../tasks/task.model'; import { NoteService } from '../note/note.service'; import { T } from '../../t.const'; -import { SyncService } from '../../imex/sync/sync.service'; -import { filter, first, map, skipUntil } from 'rxjs/operators'; +import { filter, map, skipUntil } from 'rxjs/operators'; import { migrateReminders } from './migrate-reminder.util'; import { WorkContextService } from '../work-context/work-context.service'; import { devError } from '../../util/dev-error'; import { WorkContextType } from '../work-context/work-context.model'; -const MAX_WAIT_FOR_INITIAL_SYNC = 25000; @Injectable({ providedIn: 'root', @@ -45,7 +43,6 @@ export class ReminderService { constructor( private readonly _workContextService: WorkContextService, - private readonly _syncService: SyncService, private readonly _persistenceService: PersistenceService, private readonly _snackService: SnackService, private readonly _taskService: TaskService, @@ -67,19 +64,11 @@ export class ReminderService { }); } - init() { - // we do this to wait for syncing and the like - merge( - this._syncService.afterInitialSyncDoneAndDataLoadedInitially$, - timer(MAX_WAIT_FOR_INITIAL_SYNC), - ).pipe( - first(), - ).subscribe(async () => { - this._w.addEventListener('message', this._onReminderActivated.bind(this)); - this._w.addEventListener('error', this._handleError.bind(this)); - await this.reloadFromDatabase(); - this._isRemindersLoaded$.next(true); - }); + async init() { + this._w.addEventListener('message', this._onReminderActivated.bind(this)); + this._w.addEventListener('error', this._handleError.bind(this)); + await this.reloadFromDatabase(); + this._isRemindersLoaded$.next(true); } async reloadFromDatabase() { diff --git a/src/app/imex/local-backup/local-backup.model.ts b/src/app/imex/local-backup/local-backup.model.ts new file mode 100644 index 000000000..2ba7efd1d --- /dev/null +++ b/src/app/imex/local-backup/local-backup.model.ts @@ -0,0 +1,5 @@ +export interface LocalBackupMeta { + folder: string; + path: string; + created: number; +} diff --git a/src/app/imex/local-backup/local-backup.service.ts b/src/app/imex/local-backup/local-backup.service.ts index 3a08ae938..43eae90a8 100644 --- a/src/app/imex/local-backup/local-backup.service.ts +++ b/src/app/imex/local-backup/local-backup.service.ts @@ -3,10 +3,11 @@ import { GlobalConfigService } from '../../features/config/global-config.service import { interval, Observable } from 'rxjs'; import { LocalBackupConfig } from '../../features/config/global-config.model'; import { filter, map, switchMap, tap } from 'rxjs/operators'; -import { DataImportService } from '../sync/data-import.service'; import { IPC } from '../../../../electron/ipc-events.const'; import { ElectronService } from '../../core/electron/electron.service'; import { ipcRenderer } from 'electron'; +import { PersistenceService } from '../../core/persistence/persistence.service'; +import { LocalBackupMeta } from './local-backup.model'; const DEFAULT_BACKUP_INTERVAL = 2 * 60 * 1000; @@ -23,7 +24,7 @@ export class LocalBackupService { constructor( private _configService: GlobalConfigService, - private _dataImportService: DataImportService, + private _persistenceService: PersistenceService, private _electronService: ElectronService, ) { } @@ -33,18 +34,16 @@ export class LocalBackupService { } // TODO return backup info - isBackupAvailable(): Promise { - // return this._electronService.callMain(IPC.DB_SAVE, {key, data: JSON.stringify(dataIn)} as any); - return Promise.resolve(true); + isBackupAvailable(): Promise { + return this._electronService.callMain(IPC.BACKUP_IS_AVAILABLE, null) as Promise; } - restoreBackup(): void { - // return this._electronService.callMain(IPC.DB_SAVE, {key, data: JSON.stringify(dataIn)} as any); - + loadBackup(backupPath: string): Promise { + return this._electronService.callMain(IPC.BACKUP_IS_AVAILABLE, backupPath) as Promise; } private async _backup() { - const data = await this._dataImportService.getCompleteSyncData(); + const data = await this._persistenceService.loadComplete(); (this._electronService.ipcRenderer as typeof ipcRenderer).send(IPC.BACKUP, data); } } From a54711d9651d19a0f15b66f0e2f6b4d97f7a3e83 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 22:40:53 +0200 Subject: [PATCH 102/131] feat(autoBackupRestore): make it work #553 --- electron/backup.ts | 2 +- electron/ipc-events.const.ts | 2 +- src/app/core/data-init/data-init.service.ts | 23 --------- .../local-backup/local-backup.effects.spec.ts | 25 ++++++++++ .../imex/local-backup/local-backup.effects.ts | 47 +++++++++++++++++++ .../imex/local-backup/local-backup.module.ts | 5 ++ .../imex/local-backup/local-backup.service.ts | 3 +- 7 files changed, 80 insertions(+), 27 deletions(-) create mode 100644 src/app/imex/local-backup/local-backup.effects.spec.ts create mode 100644 src/app/imex/local-backup/local-backup.effects.ts diff --git a/electron/backup.ts b/electron/backup.ts index ea62e1181..4ea8a5587 100644 --- a/electron/backup.ts +++ b/electron/backup.ts @@ -36,7 +36,7 @@ export function initBackupAdapter(backupDir: string) { }); // RESTORE_BACKUP - answerRenderer(IPC.BACKUP_RESTORE, (backupPath): string => { + answerRenderer(IPC.BACKUP_LOAD_DATA, (backupPath): string => { console.log('Reading backup file: ', backupPath); return readFileSync(backupPath, {encoding: 'utf8'}); }); diff --git a/electron/ipc-events.const.ts b/electron/ipc-events.const.ts index 1d5adfcce..8d8a1e180 100644 --- a/electron/ipc-events.const.ts +++ b/electron/ipc-events.const.ts @@ -36,7 +36,7 @@ export enum IPC { BACKUP = 'BACKUP_APP_DATA', BACKUP_IS_AVAILABLE = 'BACKUP_IS_AVAILABLE', - BACKUP_RESTORE = 'BACKUP_RESTORE', + BACKUP_LOAD_DATA = 'BACKUP_LOAD_DATA', SET_PROGRESS_BAR = 'SET_PROGRESS_BAR', diff --git a/src/app/core/data-init/data-init.service.ts b/src/app/core/data-init/data-init.service.ts index 8a6e650b0..3c3b79186 100644 --- a/src/app/core/data-init/data-init.service.ts +++ b/src/app/core/data-init/data-init.service.ts @@ -11,9 +11,6 @@ import { MigrationService } from '../migration/migration.service'; import { loadAllData } from '../../root-store/meta/load-all-data.action'; import { isValidAppData } from '../../imex/sync/is-valid-app-data.util'; import { DataRepairService } from '../data-repair/data-repair.service'; -import { LocalBackupService } from '../../imex/local-backup/local-backup.service'; -import { IS_ELECTRON } from '../../app.constants'; -import { AppDataComplete } from '../../imex/sync/sync.model'; @Injectable({providedIn: 'root'}) export class DataInitService { @@ -39,8 +36,6 @@ export class DataInitService { private _workContextService: WorkContextService, private _store$: Store, private _dataRepairService: DataRepairService, - // private _dataImportService: DataImportService, - private _localBackupService: LocalBackupService, ) { // TODO better construction than this this.isAllDataLoadedInitially$.pipe( @@ -58,7 +53,6 @@ export class DataInitService { const isValid = isValidAppData(appDataComplete); if (isValid) { this._store$.dispatch(loadAllData({appDataComplete, isOmitTokens})); - this._checkForBackupIfEmpty(appDataComplete); } else { if (this._dataRepairService.isRepairPossibleAndConfirmed(appDataComplete)) { const fixedData = this._dataRepairService.repairData(appDataComplete); @@ -70,21 +64,4 @@ export class DataInitService { } } - private async _checkForBackupIfEmpty(appDataComplete: AppDataComplete) { - console.log(IS_ELECTRON, appDataComplete); - - if (IS_ELECTRON) { - if (appDataComplete.task.ids.length === 0 && appDataComplete.taskArchive.ids.length === 0) { - const r = await this._localBackupService.isBackupAvailable(); - if (r) { - console.log(r); - if (confirm('NO TASK DATA IMPORT BACKUP FROM?' + r.path)) { - const d = await this._localBackupService.loadBackup(r.path); - console.log(d); - // await this._dataImportService.importCompleteSyncData(JSON.parse(d)); - } - } - } - } - } } diff --git a/src/app/imex/local-backup/local-backup.effects.spec.ts b/src/app/imex/local-backup/local-backup.effects.spec.ts new file mode 100644 index 000000000..12df6b60c --- /dev/null +++ b/src/app/imex/local-backup/local-backup.effects.spec.ts @@ -0,0 +1,25 @@ +// import { TestBed } from '@angular/core/testing'; +// import { provideMockActions } from '@ngrx/effects/testing'; +// import { Observable } from 'rxjs'; +// +// import { LocalBackupEffects } from './local-backup.effects'; +// +// describe('LocalBackupEffects', () => { +// let actions$: Observable; +// let effects: LocalBackupEffects; +// +// beforeEach(() => { +// TestBed.configureTestingModule({ +// providers: [ +// LocalBackupEffects, +// provideMockActions(() => actions$) +// ] +// }); +// +// effects = TestBed.inject(LocalBackupEffects); +// }); +// +// it('should be created', () => { +// expect(effects).toBeTruthy(); +// }); +// }); diff --git a/src/app/imex/local-backup/local-backup.effects.ts b/src/app/imex/local-backup/local-backup.effects.ts new file mode 100644 index 000000000..b9024a846 --- /dev/null +++ b/src/app/imex/local-backup/local-backup.effects.ts @@ -0,0 +1,47 @@ +import { Injectable } from '@angular/core'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; +import { take, tap } from 'rxjs/operators'; +import { loadAllData } from '../../root-store/meta/load-all-data.action'; +import { AppDataComplete } from '../sync/sync.model'; +import { IS_ELECTRON } from '../../app.constants'; +import { LocalBackupService } from './local-backup.service'; +import { DataImportService } from '../sync/data-import.service'; + +@Injectable() +export class LocalBackupEffects { + + checkForBackupIfNoTasks$: any = createEffect(() => this._actions$.pipe( + ofType( + loadAllData + ), + take(1), + tap(({appDataComplete}) => { + console.log(appDataComplete); + this._checkForBackupIfEmpty(appDataComplete); + }) + ), {dispatch: false}); + + constructor( + private _actions$: Actions, + private _localBackupService: LocalBackupService, + private _dataImportService: DataImportService, + ) { + } + + private async _checkForBackupIfEmpty(appDataComplete: AppDataComplete) { + console.log(IS_ELECTRON, appDataComplete); + if (IS_ELECTRON) { + if (appDataComplete.task.ids.length === 0 && appDataComplete.taskArchive.ids.length === 0) { + const backupMeta = await this._localBackupService.isBackupAvailable(); + if (backupMeta) { + console.log('backupMeta', backupMeta); + if (confirm('NO TASK DATA IMPORT BACKUP FROM?' + backupMeta.path)) { + const backupData = await this._localBackupService.loadBackup(backupMeta.path); + console.log('backupData', backupData); + await this._dataImportService.importCompleteSyncData(JSON.parse(backupData)); + } + } + } + } + } +} diff --git a/src/app/imex/local-backup/local-backup.module.ts b/src/app/imex/local-backup/local-backup.module.ts index 6ea334519..4e18b2ef3 100644 --- a/src/app/imex/local-backup/local-backup.module.ts +++ b/src/app/imex/local-backup/local-backup.module.ts @@ -1,9 +1,12 @@ import { NgModule } from '@angular/core'; import { LocalBackupService } from './local-backup.service'; import { IS_ELECTRON } from '../../app.constants'; +import { EffectsModule } from '@ngrx/effects'; +import { LocalBackupEffects } from './local-backup.effects'; @NgModule({ providers: [LocalBackupService], + imports: [EffectsModule.forFeature([LocalBackupEffects])], }) export class LocalBackupModule { constructor(private _localBackupService: LocalBackupService) { @@ -12,4 +15,6 @@ export class LocalBackupModule { } } + + } diff --git a/src/app/imex/local-backup/local-backup.service.ts b/src/app/imex/local-backup/local-backup.service.ts index 43eae90a8..25ac7515d 100644 --- a/src/app/imex/local-backup/local-backup.service.ts +++ b/src/app/imex/local-backup/local-backup.service.ts @@ -33,13 +33,12 @@ export class LocalBackupService { this._triggerBackups.subscribe(); } - // TODO return backup info isBackupAvailable(): Promise { return this._electronService.callMain(IPC.BACKUP_IS_AVAILABLE, null) as Promise; } loadBackup(backupPath: string): Promise { - return this._electronService.callMain(IPC.BACKUP_IS_AVAILABLE, backupPath) as Promise; + return this._electronService.callMain(IPC.BACKUP_LOAD_DATA, backupPath) as Promise; } private async _backup() { From cfeed8de1048c26e69b65ec1b7689a9f8eebb720 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Sun, 4 Oct 2020 23:03:23 +0200 Subject: [PATCH 103/131] feat(autoBackupRestore): add translations #553 --- electron/backup.ts | 1 + src/app/imex/local-backup/local-backup.effects.ts | 13 ++++++++++++- src/app/imex/local-backup/local-backup.model.ts | 1 + src/app/t.const.ts | 5 +++-- src/assets/i18n/en.json | 3 ++- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/electron/backup.ts b/electron/backup.ts index 4ea8a5587..0a334bf31 100644 --- a/electron/backup.ts +++ b/electron/backup.ts @@ -25,6 +25,7 @@ export function initBackupAdapter(backupDir: string) { return false; } const filesWithMeta: LocalBackupMeta[] = files.map((fileName: string): LocalBackupMeta => ({ + name: fileName, path: path.join(BACKUP_DIR, fileName), folder: BACKUP_DIR, created: statSync(path.join(BACKUP_DIR, fileName)).mtime.getTime() diff --git a/src/app/imex/local-backup/local-backup.effects.ts b/src/app/imex/local-backup/local-backup.effects.ts index b9024a846..b044f5a56 100644 --- a/src/app/imex/local-backup/local-backup.effects.ts +++ b/src/app/imex/local-backup/local-backup.effects.ts @@ -6,6 +6,9 @@ import { AppDataComplete } from '../sync/sync.model'; import { IS_ELECTRON } from '../../app.constants'; import { LocalBackupService } from './local-backup.service'; import { DataImportService } from '../sync/data-import.service'; +import { TranslateService } from '@ngx-translate/core'; +import { T } from '../../t.const'; +import * as moment from 'moment'; @Injectable() export class LocalBackupEffects { @@ -25,6 +28,7 @@ export class LocalBackupEffects { private _actions$: Actions, private _localBackupService: LocalBackupService, private _dataImportService: DataImportService, + private _translateService: TranslateService, ) { } @@ -35,7 +39,10 @@ export class LocalBackupEffects { const backupMeta = await this._localBackupService.isBackupAvailable(); if (backupMeta) { console.log('backupMeta', backupMeta); - if (confirm('NO TASK DATA IMPORT BACKUP FROM?' + backupMeta.path)) { + if (confirm(this._translateService.instant(T.CONFIRM.RESTORE_FILE_BACKUP, { + dir: backupMeta.folder, + from: this._formatDate(backupMeta.created), + }))) { const backupData = await this._localBackupService.loadBackup(backupMeta.path); console.log('backupData', backupData); await this._dataImportService.importCompleteSyncData(JSON.parse(backupData)); @@ -44,4 +51,8 @@ export class LocalBackupEffects { } } } + + private _formatDate(date: Date | string | number) { + return moment(date).format('DD-MM-YYYY, hh:mm:ss'); + } } diff --git a/src/app/imex/local-backup/local-backup.model.ts b/src/app/imex/local-backup/local-backup.model.ts index 2ba7efd1d..d4f52a86c 100644 --- a/src/app/imex/local-backup/local-backup.model.ts +++ b/src/app/imex/local-backup/local-backup.model.ts @@ -1,5 +1,6 @@ export interface LocalBackupMeta { folder: string; path: string; + name: string; created: number; } diff --git a/src/app/t.const.ts b/src/app/t.const.ts index b9f2e04bb..d1af8525d 100644 --- a/src/app/t.const.ts +++ b/src/app/t.const.ts @@ -19,7 +19,8 @@ export const T = { 'CONFIRM': { 'AUTO_FIX': 'CONFIRM.AUTO_FIX', 'DELETE_STRAY_BACKUP': 'CONFIRM.DELETE_STRAY_BACKUP', - 'RESTORE_STRAY_BACKUP': 'CONFIRM.RESTORE_STRAY_BACKUP' + 'RESTORE_STRAY_BACKUP': 'CONFIRM.RESTORE_STRAY_BACKUP', + 'RESTORE_FILE_BACKUP': 'CONFIRM.RESTORE_FILE_BACKUP' }, 'DATETIME_INPUT': { 'IN': 'DATETIME_INPUT.IN', @@ -958,7 +959,7 @@ export const T = { 'IS_NOTIFY_WHEN_TIME_ESTIMATE_EXCEEDED': 'GCF.MISC.IS_NOTIFY_WHEN_TIME_ESTIMATE_EXCEEDED', 'IS_TURN_OFF_MARKDOWN': 'GCF.MISC.IS_TURN_OFF_MARKDOWN', 'TITLE': 'GCF.MISC.TITLE', - "FIRST_DAY_OF_WEEK": 'GCF.MISC.FIRST_DAY_OF_WEEK', + 'FIRST_DAY_OF_WEEK': 'GCF.MISC.FIRST_DAY_OF_WEEK' }, 'POMODORO': { 'BREAK_DURATION': 'GCF.POMODORO.BREAK_DURATION', diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 2dc66805e..b48b28989 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -19,7 +19,8 @@ "CONFIRM": { "AUTO_FIX": "Your data seems to be damaged. Do you want to try to automatically fix it? This might result in partial data loss.", "DELETE_STRAY_BACKUP": "Do you want to delete the back to avoid seeing this dialog?", - "RESTORE_STRAY_BACKUP": "During last sync there might have been some error. Do you want to restore the last backup?" + "RESTORE_STRAY_BACKUP": "During last sync there might have been some error. Do you want to restore the last backup?", + "RESTORE_FILE_BACKUP": "There seems to be NO DATA, but there are backups available at \"{{dir}}\". Do you want to restore the latest backup from {{from}}?" }, "DATETIME_INPUT": { "IN": "in {{time}}", From ada4c97db9fb7075419f43d845b4e33606dbeba2 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Mon, 5 Oct 2020 20:34:35 +0200 Subject: [PATCH 104/131] feat(task): make startable tasks work better --- .../work-context/work-context.service.ts | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/app/features/work-context/work-context.service.ts b/src/app/features/work-context/work-context.service.ts index 4d06c069a..b91ed5a63 100644 --- a/src/app/features/work-context/work-context.service.ts +++ b/src/app/features/work-context/work-context.service.ts @@ -226,28 +226,26 @@ export class WorkContextService { map(([today, backlog]) => [...today, ...backlog]) ); - // TODO make it more efficient startableTasks$: Observable = combineLatest([ this.activeWorkContext$, this._store$.pipe( select(selectTaskEntities), ) ]).pipe( - switchMap(([activeContext, entities]) => { - const taskIds = activeContext.taskIds; - return of( - (Object.keys(entities) - .filter((id) => { - const t = entities[id] as Task; - return !t.isDone && ( - (t.parentId) - ? (taskIds.includes(t.parentId)) - : (taskIds.includes(id) && (!t.subTaskIds || t.subTaskIds.length === 0)) - ); - }) - .map(key => entities[key]) as Task[]) - ); - }) + map(([activeContext, entities]) => { + let startableTasks: Task[] = []; + activeContext.taskIds.forEach(id => { + const task: Task | undefined = entities[id]; + if (!task) throw new Error('Task not found'); + + if (task.subTaskIds && task.subTaskIds.length) { + startableTasks = startableTasks.concat(task.subTaskIds.map(sid => entities[sid] as Task)); + } else { + startableTasks.push(task); + } + }); + return startableTasks.filter(task => !task.isDone); + }), ); workingToday$: Observable = this.getTimeWorkedForDay$(getWorklogStr()); From a293f2f736d7a61d87cc792b669864b7c2f5c5e8 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Mon, 5 Oct 2020 21:39:37 +0200 Subject: [PATCH 105/131] fix: not in project context #545 --- src/app/app.component.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index ab8719d09..c45a99e5b 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -40,6 +40,7 @@ import { environment } from '../environments/environment'; import { RouterOutlet } from '@angular/router'; import { ipcRenderer } from 'electron'; import { TrackingReminderService } from './features/time-tracking/tracking-reminder/tracking-reminder.service'; +import { first } from 'rxjs/operators'; const w = window as any; const productivityTip: string[] = w.productivityTips && w.productivityTips[w.randomIndex]; @@ -160,8 +161,11 @@ export class AppComponent implements OnDestroy { ev.preventDefault(); } - @HostListener('document:paste', ['$event']) onPaste(ev: ClipboardEvent) { - this._bookmarkService.createFromPaste(ev); + @HostListener('document:paste', ['$event']) + async onPaste(ev: ClipboardEvent) { + if (await this.workContextService.isActiveWorkContextProject$.pipe(first()).toPromise()) { + this._bookmarkService.createFromPaste(ev); + } } @HostListener('window:beforeinstallprompt', ['$event']) onBeforeInstallPrompt(e: any) { From b389079674e83bc38be4708f6bffe4f09619351a Mon Sep 17 00:00:00 2001 From: rubjo Date: Wed, 7 Oct 2020 12:59:23 +0200 Subject: [PATCH 106/131] =?UTF-8?q?i18n:=20added=20=F0=9F=87=B3?= =?UTF-8?q?=F0=9F=87=B4=20Norwegian=20Bokm=C3=A5l?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/i18n/ar.json | 1 + src/assets/i18n/de.json | 1 + src/assets/i18n/en.json | 1 + src/assets/i18n/es.json | 1 + src/assets/i18n/fa.json | 1 + src/assets/i18n/fr.json | 1 + src/assets/i18n/it.json | 1 + src/assets/i18n/ja.json | 1 + src/assets/i18n/ko.json | 1 + src/assets/i18n/nb.json | 1174 +++++++++++++++++++++++++++++++++++++++ src/assets/i18n/nl.json | 1 + src/assets/i18n/pt.json | 1 + src/assets/i18n/ru.json | 1 + src/assets/i18n/tr.json | 1 + src/assets/i18n/zh.json | 1 + 15 files changed, 1188 insertions(+) create mode 100644 src/assets/i18n/nb.json diff --git a/src/assets/i18n/ar.json b/src/assets/i18n/ar.json index 19d393e34..526d66a02 100644 --- a/src/assets/i18n/ar.json +++ b/src/assets/i18n/ar.json @@ -922,6 +922,7 @@ "JA": "اليابانية", "KO": "الكورية", "LABEL": "يرجى تحديد لغة", + "NB": "النرويجية بوكمال", "NL": "هولندي", "PT": "البرتغالية", "RU": "الروسية", diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index c23e9ae27..86ae82b10 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -922,6 +922,7 @@ "JA": "Japanisch", "KO": "Koreanisch", "LABEL": "Bitte wähle eine Sprache", + "NB": "Norwegischer Bokmål", "NL": "Niederländisch", "PT": "Portugiesisch", "RU": "Russisch", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index b48b28989..24f99af1f 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -939,6 +939,7 @@ "JA": "Japanese", "KO": "Korean", "LABEL": "Please select a language", + "NB": "Norwegian Bokmål", "NL": "Dutch", "PT": "Portuguese", "RU": "Russian", diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index 9ffe18730..aaca2745c 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -922,6 +922,7 @@ "JA": "Japonés", "KO": "Coreano", "LABEL": "Selecciona un idioma", + "NB": "Noruego bokmål", "NL": "Holandés", "PT": "Portugués", "RU": "Ruso", diff --git a/src/assets/i18n/fa.json b/src/assets/i18n/fa.json index fb37ba72a..df81ccb82 100644 --- a/src/assets/i18n/fa.json +++ b/src/assets/i18n/fa.json @@ -922,6 +922,7 @@ "JA": "ژاپنی", "KO": "کره ای", "LABEL": "لطفا یک زبان انتخاب کنید", + "NB": "نروژی", "NL": "هلندی", "PT": "پرتغالی", "RU": "روسی", diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 3018a74ad..307bc12ee 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -922,6 +922,7 @@ "JA": "japonais", "KO": "coréen", "LABEL": "Veuillez sélectionner une langue", + "NB": "Norvégien bokmål", "NL": "Néerlandais", "PT": "Portugais", "RU": "russe", diff --git a/src/assets/i18n/it.json b/src/assets/i18n/it.json index 30e0500dc..679906e67 100644 --- a/src/assets/i18n/it.json +++ b/src/assets/i18n/it.json @@ -922,6 +922,7 @@ "JA": "Giapponese", "KO": "Coreano", "LABEL": "Seleziona la lingua", + "NB": "Norvegese Bokmål", "NL": "Olandese", "PT": "Portoguese", "RU": "Russo", diff --git a/src/assets/i18n/ja.json b/src/assets/i18n/ja.json index 525115add..841031b19 100644 --- a/src/assets/i18n/ja.json +++ b/src/assets/i18n/ja.json @@ -922,6 +922,7 @@ "JA": "日本人", "KO": "韓国語", "LABEL": "言語を選択してください", + "NB": "ノルウェーのブークモール", "NL": "蘭語", "PT": "ポルトガル", "RU": "ロシア", diff --git a/src/assets/i18n/ko.json b/src/assets/i18n/ko.json index 80cb35951..814fa7eb7 100644 --- a/src/assets/i18n/ko.json +++ b/src/assets/i18n/ko.json @@ -922,6 +922,7 @@ "JA": "일본어", "KO": "한국어", "LABEL": "언어를 선택하십시오.", + "NB": "노르웨이 보크 몰", "NL": "네덜란드 사람", "PT": "포르투갈 인", "RU": "러시아인", diff --git a/src/assets/i18n/nb.json b/src/assets/i18n/nb.json new file mode 100644 index 000000000..d5b90d69f --- /dev/null +++ b/src/assets/i18n/nb.json @@ -0,0 +1,1174 @@ +{ + "APP": { + "B_INSTALL": { + "IGNORE": "Overse", + "INSTALL": "Installere", + "MSG": "Vil du installere Super Productivity som en PWA?" + }, + "B_OFFLINE": "Du er koblet fra internett. Synkronisering og å be om data fra leverandører fungerer ikke.", + "D_INITIAL": { + "TITLE": "Velkommen til v {{nr}}" + }, + "UPDATE_MAIN_MODEL": "Super Productivity har fått en stor oppdatering! Noen migrasjoner for dataene dine er påkrevd. Vær oppmerksom på at dette gjør dataene dine uforenlige med eldre versjoner av appen.", + "UPDATE_MAIN_MODEL_NO_UPDATE": "Ingen modelloppdatering valgt. Vær oppmerksom på at du må nedgradere til den siste versjonen, hvis du ikke vil utføre modelloppgraderingen.", + "UPDATE_WEB_APP": "Ny versjon tilgjengelig. Last inn ny versjon?" + }, + "BL": { + "NO_TASKS": "Det er for øyeblikket ingen oppgaver i backloggen" + }, + "CONFIRM": { + "AUTO_FIX": "Dataene dine ser ut til å være skadet. Vil du prøve å fikse det automatisk? Dette kan føre til delvis tap av data.", + "DELETE_STRAY_BACKUP": "Vil du slette sikkerhetskopien for å unngå å se denne dialogen?", + "RESTORE_STRAY_BACKUP": "Under siste synkronisering kan det ha oppstått en feil. Vil du gjenopprette den siste sikkerhetskopien?", + "RESTORE_FILE_BACKUP": "Det ser ut til å være INGEN DATA, men det er sikkerhetskopier tilgjengelig på \"{{dir}}\". Vil du gjenopprette den siste sikkerhetskopien fra {{from}}?" + }, + "DATETIME_INPUT": { + "IN": "om {{time}}", + "TOMORROW": "i morgen {{time}}" + }, + "DATETIME_SCHEDULE": { + "LATER_TODAY": "Senere i dag", + "NEXT_WEEK": "Neste uke", + "PLACEHOLDER": "Velg en dato", + "PRESS_ENTER_AGAIN": "Trykk på Enter igjen for å lagre", + "TOMORROW": "I morgen" + }, + "F": { + "ATTACHMENT": { + "DIALOG_EDIT": { + "ADD_ATTACHMENT": "Legg til vedlegg", + "EDIT_ATTACHMENT": "Rediger vedlegg", + "LABELS": { + "FILE": "Filbane", + "IMG": "Bilde", + "LINK": "Url" + }, + "SELECT_TYPE": "Velg en type", + "TYPES": { + "FILE": "Fil (åpnet av standard systemapp)", + "IMG": "Bilde (vist som miniatyrbilde)", + "LINK": "Link (åpnes i nettleser)" + } + } + }, + "BOOKMARK": { + "BAR": { + "ADD": "Legg til bokmerke", + "DROP": "Slipp her for å legge til et bokmerke", + "EDIT": "Rediger bokmerker", + "NO_BOOKMARKS": "Du har ingen prosjektbokmerker. Legg til en med dra og slipp eller ved å klikke på 'pluss'-knappen." + }, + "DIALOG_EDIT": { + "ADD_BOOKMARK": "Legg til bokmerke", + "EDIT_BOOKMARK": "Rediger bokmerke", + "LABELS": { + "COMMAND": "Kommando", + "FILE": "Filbane", + "IMG": "Bilde", + "LINK": "Url" + }, + "SELECT_ICON": "Velg et ikon", + "SELECT_TYPE": "Velg en type", + "TYPES": { + "COMMAND": "Kommando (tilpasset skallkommando)", + "FILE": "Fil (åpnet som standard systemapp)", + "IMG": "Bilde (vist som miniatyrbilde)", + "LINK": "Link (åpnes i nettleser)" + } + } + }, + "CONFIG": { + "S": { + "UPDATE_SECTION": "Oppdaterte innstillinger for {{sectionKey}}" + } + }, + "DROPBOX": { + "C": { + "EMPTY_SYNC": "Du prøver å synkronisere et tomt dataobjekt. Er dette din aller første synkronisering av en (nesten) ubrukt app?", + "FORCE_IMPORT": "Importere eksterne data uansett?", + "FORCE_UPLOAD": "Last opp lokale data uansett?", + "FORCE_UPLOAD_AFTER_ERROR": "Det oppsto en feil under opplasting av lokale data. Prøve å tvinge oppdateringen?", + "TRY_LOAD_REMOTE_AGAIN": "Prøv å laste inn data fra ekstern igjen?" + }, + "D_CONFLICT": { + "LAST_CHANGE": "siste endring:", + "LAST_SYNC": "siste synkronisering:", + "LOCAL": "lokal", + "LOCAL_REMOTE": "lokal -> ekstern", + "REMOTE": "fjernkontroll", + "TEXT": "

Oppdatering fra Dropbox. Både lokale og eksterne data ser ut til å være endret.

", + "TITLE": "Dropbox: motstridende data", + "USE_LOCAL": "Bruk lokal", + "USE_REMOTE": "Bruk ekstern" + }, + "FORM": { + "B_GENERATE_TOKEN": "Generer token", + "FOLLOW_LINK": "Vennligst åpne følgende lenke og kopier autentiseringskoden som er oppgitt der, inn i inndatafeltet.", + "L_ACCESS_TOKEN": "Access Token (generert fra Auth Code)", + "L_AUTH_CODE": "Autentiseringskode", + "L_ENABLE_SYNCING": "Aktiver Dropbox-synkronisering", + "L_SYNC_INTERVAL": "Synkroniseringsintervall", + "TITLE": "Synkroniser via Dropbox (anbefalt)" + }, + "S": { + "ACCESS_TOKEN_ERROR": "Dropbox: Kan ikke generere Access Token fra Auth Code", + "ACCESS_TOKEN_GENERATED": "Dropbox: Access Token generert fra Auth Code", + "AUTH_ERROR": "Dropbox: Ugyldig tilgangstoken gitt", + "OFFLINE": "Dropbox: Kan ikke synkroniseres, fordi offline", + "SYNC_ERROR": "Dropbox: Feil under synkronisering", + "UNKNOWN_ERROR": "Dropbox: Ukjent feil: {{errorStr}}" + } + }, + "GITHUB": { + "DIALOG_INITIAL": { + "TITLE": "Sett opp Github for Prosjekt" + }, + "FORM": { + "FILTER_USER": "Brukernavn (f.eks. for å filtrere ut endringer selv)", + "IS_AUTO_ADD_TO_BACKLOG": "Legg automatisk uløste problemer fra Github til backloggen", + "IS_AUTO_POLL": "Poll automatisk importerte gitproblemer for endringer", + "IS_SEARCH_ISSUES_FROM_GITHUB": "Vis problemer fra git som forslag når du legger til nye oppgaver", + "REPO": "\"brukernavn / repositoryName\" for git-depotet du vil spore", + "TOKEN": "Tilgangstoken" + }, + "FORM_SECTION": { + "HELP": "

Her kan du konfigurere SuperProductivity til å liste åpne GitHub-problemer for et bestemt repo i oppgavelagerpanelet i den daglige planvisningen. De vil bli oppført som forslag og vil gi en lenke til problemet, samt mer informasjon om det.

I tillegg kan du automatisk legge til og synkronisere alle åpne problemer i oppgaven din.

", + "TITLE": "Github" + }, + "ISSUE_CONTENT": { + "ASSIGNEE": "Oppdragsgiver", + "AT": "på", + "DESCRIPTION": "Beskrivelse", + "LABELS": "Etiketter", + "MARK_AS_CHECKED": "Merk oppdateringer som merket", + "STATUS": "Status", + "SUMMARY": "Sammendrag", + "WRITE_A_COMMENT": "Skriv en kommentar" + }, + "S": { + "ERR_NETWORK": "Github: Forespørselen mislyktes på grunn av en nettverksfeil på klientsiden", + "ERR_NOT_CONFIGURED": "Github: Er ikke riktig konfigurert", + "ERR_UNKNOWN": "Github: Ukjent feil {{statusCode}} {{errorMsg}}. Grensen for api-rate overskredet?", + "IMPORTED_MULTIPLE_ISSUES": "Github: Importerte {{issuesLength}} nye problemer fra git til backlog", + "IMPORTED_SINGLE_ISSUE": "Github: Importert problem \"{{issueText}}\" fra git til backlog", + "ISSUE_DELETED_OR_CLOSED": "Github: Utgaven \"{{issueText}}\" ser ut til å bli slettet eller lukket på git", + "ISSUE_NO_UPDATE_REQUIRED": "Github: Ingen oppdatering nødvendig", + "ISSUE_UPDATE": "Github: Oppdaterte data for \"{{issueText}}\"", + "MANUAL_UPDATE_ISSUE_SUCCESS": "Github: Oppdaterte data for \"{{issueText}}\"", + "MISSING_ISSUE_DATA": "Github: Oppgaver med manglende problemdata funnet. Laster om.", + "NEW_COMMENT": "Github: Ny kommentar til \"{{issueText}}\"", + "POLLING": "Github: Avstemningsendringer for problemer", + "SHOW_ISSUE_BTN": "Vis meg" + } + }, + "GITLAB": { + "DIALOG_INITIAL": { + "TITLE": "Sett opp Gitlab for Project" + }, + "FORM": { + "FILTER_USER": "Brukernavn (f.eks. For å filtrere ut endringer selv)", + "IS_AUTO_ADD_TO_BACKLOG": "Legg automatisk uløste problemer fra Gitlab til backloggen", + "IS_AUTO_POLL": "Poll automatisk importerte gitproblemer for endringer", + "IS_SEARCH_ISSUES_FROM_GITLAB": "Vis problemer fra git som forslag når du legger til nye oppgaver", + "PROJECT": "Full sti eller brukernavn / prosjekt", + "TOKEN": "Tilgangstoken" + }, + "FORM_SECTION": { + "HELP": "

Her kan du konfigurere SuperProductivity til å liste åpne Gitlab-problemer (enten den online-versjonen eller en selvstyrt forekomst) for et bestemt prosjekt i oppgavelagerpanelet i den daglige planvisningen. De vil bli oppført som forslag og vil gi en lenke til problemet, samt mer informasjon om det.

I tillegg kan du automatisk legge til og synkronisere alle åpne problemer i oppgaven din.

", + "TITLE": "Gitlab" + }, + "ISSUE_CONTENT": { + "ASSIGNEE": "Oppdragsgiver", + "AT": "på", + "DESCRIPTION": "Beskrivelse", + "LABELS": "Etiketter", + "MARK_AS_CHECKED": "Merk oppdateringer som merket", + "STATUS": "Status", + "SUMMARY": "Sammendrag", + "WRITE_A_COMMENT": "Skriv en kommentar" + }, + "S": { + "ERR_NETWORK": "Gitlab: Forespørselen mislyktes på grunn av en nettverksfeil på klientsiden", + "ERR_NOT_CONFIGURED": "Gitlab: Er ikke riktig konfigurert", + "ERR_UNKNOWN": "Gitlab: Ukjent feil {{statusCode}} {{errorMsg}}", + "IMPORTED_MULTIPLE_ISSUES": "Gitlab: Importerte {{issuesLength}} nye problemer fra git til backlog", + "IMPORTED_SINGLE_ISSUE": "Gitlab: Importert problem \"{{issueText}}\" fra git til backlog", + "ISSUE_DELETED_OR_CLOSED": "Gitlab: Utgaven \"{{issueText}}\" ser ut til å være slettet eller lukket på git", + "ISSUE_NO_UPDATE_REQUIRED": "Gitlab: Ingen oppdatering nødvendig", + "ISSUE_UPDATE": "Gitlab: Oppdaterte data for \"{{issueText}}\"", + "MANUAL_UPDATE_ISSUE_SUCCESS": "Gitlab: Oppdaterte data for \"{{issueText}}\"", + "MISSING_ISSUE_DATA": "Gitlab: Oppgaver med manglende problemdata funnet. Laster om.", + "NEW_COMMENT": "Gitlab: Ny kommentar til \"{{issueText}}\"", + "POLLING": "Gitlab: Henter endringer for problemer", + "SHOW_ISSUE_BTN": "Vis meg" + } + }, + "GOOGLE": { + "BANNER": { + "AUTH_FAIL": "GoogleApi: Kunne ikke autentisere, prøv å logge på igjen!" + }, + "DIALOG": { + "CREATE_SYNC_FILE": "Google Disk: Ingen fil med navnet "{{fileName}}" ble funnet. Vil du opprette den som synkroniseringsfil på Google Disk?", + "USE_EXISTING_SYNC_FILE": "Google Drive: Bruk eksisterende fil "{{fileName}}" som synkroniseringsfil? Hvis ikke, kan du endre synkroniseringsfilnavnet." + }, + "D_CONFIRM_LOAD": { + "LAST_MOD": "siste modifikasjon:", + "LAST_SYNC": "siste synkronisering", + "LOCAL": "lokal", + "LOCAL_REMOTE": "lokal <=> ekstern", + "OVERWRITE_LOCAL": "Overskriv lokal", + "OVERWRITE_REMOTE": "Overskriv ekstern", + "REMOTE": "ekstern", + "TEXT": "

Oppdatering fra Google Drive Backup. Både lokale og eksterne data ser ut til å være endret. Vil du overskrive ikke-lagrede lokale endringer? All data vil gå tapt for alltid.

", + "TITLE": "Overskrive lokale data med GDrive Update?" + }, + "D_CONFIRM_SAVE": { + "LAST_MOD": "siste modifikasjon:", + "LAST_SYNC": "siste synkronisering", + "LOCAL": "lokal", + "LOCAL_REMOTE": "lokal <=> ekstern", + "OVERWRITE_LOCAL": "Overskriv lokal", + "OVERWRITE_REMOTE": "Overskriv ekstern", + "REMOTE": "ekstern", + "TEXT": "

Det ser ut til å være noen endringer på Google Drive som du ikke har lokalt. Vil du overskrive dem uansett?

", + "TITLE": "Vil du overskrive ikke lagrede data på Google Disk?" + }, + "S": { + "DOWNLOADING_UPDATE": "Google Drive: Det er en ekstern oppdatering! Laster ned ...", + "ERROR": "Google Disk - Feil: {{errTxt}}", + "ERROR_INITIAL_IMPORT": "Google Disk: Feil under forsøk på å importere data i utgangspunktet", + "LOCAL_UP_TO_DATE": "Google Drive: Lokale data er allerede oppdatert", + "MULTIPLE_SYNC_FILES_WITH_SAME_NAME": "Flere filer med navnet \"{{newFileName}}\" funnet. Slett alle unntatt en, eller velg et annet navn.", + "NO_UPDATE_REQUIRED": "Google Drive: Ingen oppdatering nødvendig", + "REMOTE_UP_TO_DATE": "Google Drive: Eksterne data er allerede oppdatert", + "SUCCESS": "Google Drive: Lagret sikkerhetskopi", + "SYNCING": "Google Drive: Synkronisering" + }, + "SYNC_CFG": { + "AUTO_LOGIN": "Automatisk pålogging når du starter appen", + "AUTO_SYNC": "Automatisk synkronisering av data til ekstern", + "BACKUP_NOW": "Sikkerhetskopier nå", + "COMPRESS": "Komprimer data", + "ENABLE": "Aktiver synkronisering via Google Disk", + "LOAD_FROM": "Last fra GDrive", + "LOAD_ON_STARTUP": "Last inn eksterne data ved oppstart", + "NOTIFY": "Varsle når du synkroniserer", + "SYNC_FILE_NAME": "Synkroniser filnavn", + "SYNC_INTERVAL": "Synkroniseringsintervall", + "UPDATE_SYNC_FILE": "Oppdater synkroniseringsfil" + }, + "S_API": { + "ERR": "GoogleApi-feil: {{errStr}}", + "ERR_NO_FILE_ID": "GoogleApi: Ingen fil-ID er spesifisert", + "ERR_NO_FILE_NAME": "GoogleApi: Ingen filnavn er spesifisert", + "SUCCESS_LOGIN": "GoogleApi: Innlogging vellykket" + } + }, + "JIRA": { + "BANNER": { + "BLOCK_ACCESS_MSG": "Jira: For å forhindre at api er stengt, har tilgang blitt blokkert av Super Productivity. Du bør sannsynligvis sjekke Jira-innstillingene dine!", + "BLOCK_ACCESS_UNBLOCK": "Fjern blokkering" + }, + "CFG_CMP": { + "ALWAYS_ASK": "Åpne alltid dialogboksen", + "DONE": "Status for å fullføre oppgaven", + "DO_NOT": "Ikke overgang", + "ENABLE": "Aktiver Jira-integrering", + "ENABLE_TRANSITIONS": "Aktiver overgangshåndtering", + "IN_PROGRESS": "Status for startoppgave", + "LOAD_SUGGESTIONS": "Lastforslag", + "MAP_CUSTOM_FIELDS": "Kartlegg tilpassede felt", + "MAP_CUSTOM_FIELDS_INFO": "Dessverre lagres noen av Jiras data under egendefinerte felt som er forskjellige for hver installasjon. Hvis du vil inkludere disse dataene, må du velge riktig tilpasset felt for det.", + "OPEN": "Status for pauseoppgave", + "SELECT_ISSUE_FOR_TRANSITIONS": "Velg utgave for å laste inn tilgjengelige overganger", + "STORY_POINTS": "Historiepoeng" + }, + "DIALOG_CONFIRM_ASSIGNMENT": { + "MSG": "{{summary}} er for tiden tilordnet {{assignee}} . Vil du tildele det til deg selv?", + "OK": "Gjør det!" + }, + "DIALOG_INITIAL": { + "TITLE": "Sett opp Jira for Project" + }, + "DIALOG_TRANSITION": { + "CHOOSE_STATUS": "Velg status du vil tildele", + "CURRENT_ASSIGNEE": "Nåværende mottaker:", + "CURRENT_STATUS": "Nåværende status:", + "TITLE": "Jira: Oppdater status", + "UPDATE_STATUS": "Oppdater status" + }, + "DIALOG_WORKLOG": { + "CURRENTLY_LOGGED": "Nåværende logget tid:", + "INVALID_DATE": "Den angitte verdien er ikke en dato!", + "SAVE_WORKLOG": "Lagre arbeidsloggen", + "STARTED": "Startet", + "SUBMIT_WORKLOG_FOR": "Send inn en arbeidslogg til Jira for", + "TIME_SPENT": "Tid brukt", + "TITLE": "Jira: Send inn arbeidslogg" + }, + "FORM": { + "IS_AUTO_ADD_TO_BACKLOG": "Legg automatisk uløste problemer fra Github til backloggen", + "IS_AUTO_POLL": "Hent automatisk importerte gitproblemer for endringer", + "IS_SEARCH_ISSUES_FROM_GITHUB": "Vis problemer fra git som forslag når du legger til nye oppgaver", + "REPO": "\"brukernavn / repositoryName\" for git-depotet du vil spore" + }, + "FORM_ADV": { + "AUTO_ADD_BACKLOG_JQL_QUERY": "JQL brukes til å legge til oppgaver automatisk i backloggen", + "IS_ADD_WORKLOG_ON_SUB_TASK_DONE": "Åpne dialogboksen for å sende arbeidsloggen til jira når underoppgaven er fullført", + "IS_AUTO_ADD_TO_BACKLOG": "Legg automatisk til problemer i Jira-backloggen", + "IS_AUTO_POLL_TICKETS": "Sjekk importerte problemer for endringer automatisk og varsle", + "IS_CHECK_TO_RE_ASSIGN_TICKET_ON_TASK_START": "Sjekk om det nåværende arbeidet med problemet er tildelt den nåværende brukeren", + "IS_WORKLOG_ENABLED": "Åpne dialogboksen for å sende arbeidsloggen til Jira når oppgaven er fullført", + "SEARCH_JQL_QUERY": "JQL Query for å begrense søkeoppgaver" + }, + "FORM_CRED": { + "ALLOW_SELF_SIGNED": "Tillat selvsignert sertifikat", + "HOST": "Vert (for eksempel: http://my-host.de:1234)", + "PASSWORD": "Token / passord", + "USER_NAME": "E-post / brukernavn", + "WONKY_COOKIE_MODE": "Wonky Cookie Fallback Authentication (kun desktop-app)" + }, + "FORM_SECTION": { + "ADV_CFG": "Avansert konfigurasjon", + "CREDENTIALS": "Legitimasjonserklæring", + "HELP_ARR": { + "H1": "Grunnleggende konfigurasjon", + "H2": "Innstillinger for arbeidslogg", + "H3": "Standard overganger", + "P1_1": "Oppgi et påloggingsnavn (finner du på profilsiden din) og et API-token eller passord hvis du av en eller annen grunn ikke kan generere et. Vær ikke oppmerksom på at nyere versjoner av Jira noen ganger bare fungerer med tokenet.", + "P1_2": "Du må også spesifisere et JQL-spørsmål som brukes til forslagene for å legge til oppgaver fra Jira. Hvis du trenger hjelp, kan du sjekke ut denne lenken https://confluence.atlassian.com/jirasoftwarecloud/advanced-searching-764478330.html .", + "P1_3": "Du kan også konfigurere, hvis du vil automatisk (f.eks. hver gang du besøker planleggingsvisningen), for å legge til alle nye oppgaver som er spesifisert av et tilpasset JQL-spørsmål i backloggen.", + "P1_4": "Et annet alternativ er \"Sjekk om gjeldende billett er tildelt nåværende bruker\". Hvis aktivert og du starter, vil det bli gjort en sjekk om du for øyeblikket er tildelt den billetten på Jira, hvis ikke en dialogboks vises der du kan velge å tildele billetten til deg selv.", + "P2_1": "Det er flere alternativer for å bestemme når og hvordan du vil sende inn en arbeidslogg. Aktivering av 'Åpne dialogbok for arbeidslogg for å legge til en arbeidslogg til Jira når oppgaven er fullført' åpner en dialogboks for å legge til en arbeidslogg hver gang du merker en Jira-oppgave som ferdig. Så husk at arbeidslogger vil bli lagt til på toppen av alt som er sporet så langt. Så hvis du merker en oppgave som ferdig for andre gang, vil du kanskje ikke sende inn den totale arbeidstiden for oppgaven igjen.", + "P2_2": "'Åpne arbeidslogg-dialogboksen når underoppgaven er ferdig og ikke for oppgaver med underoppgavene selv' åpner en arbeidslogg-dialog hver gang du merker en underoppgave for et Jira-problem som ferdig. Fordi du allerede sporer tiden din via underoppgavene, åpnes ingen dialog når du merker selve Jira-oppgaven.", + "P2_3": "'Send oppdateringer til arbeidsloggen automatisk uten dialog' gjør hva det står. Fordi det å merke en oppgave som utført flere ganger fører til at hele arbeidet spores to ganger, anbefales ikke dette.", + "P3_1": "Her kan du konfigurere standardovergangene dine på nytt. Jira muliggjør en bred konfigurasjon av overganger som vanligvis kommer til handling som forskjellige kolonner på Jira agile-tavle. Vi kan ikke gjøre antakelser om hvor og når du skal overføre oppgavene dine, og du må angi det manuelt." + } + }, + "ISSUE_CONTENT": { + "ASSIGNEE": "Oppdragsgiver", + "AT": "på", + "ATTACHMENTS": "Vedlegg", + "CHANGED": "endret", + "COMMENTS": "Kommentarer", + "COMPONENTS": "Komponenter", + "DESCRIPTION": "Beskrivelse", + "LIST_OF_CHANGES": "Liste over endringer", + "MARK_AS_CHECKED": "Merk oppdateringer som merket", + "ON": "på", + "STATUS": "Status", + "STORY_POINTS": "Historiepoeng", + "SUMMARY": "Sammendrag", + "WORKLOG": "Arbeidslogg", + "WRITE_A_COMMENT": "Skriv en kommentar" + }, + "S": { + "ADDED_WORKLOG_FOR": "Jira: Lagt til arbeidslogg for {{issueKey}}", + "EXTENSION_NOT_LOADED": "Super Productivity Extension ikke lastet inn. Det kan hjelpe å laste siden inn på nytt", + "IMPORTED_MULTIPLE_ISSUES": "Jira: Importerte {{issuesLength}} nye problemer fra Jira til backlog", + "IMPORTED_SINGLE_ISSUE": "Jira: Importert problem \"{{issueText}}\" fra Jira til backlog", + "INSUFFICIENT_SETTINGS": "Utilstrekkelige innstillinger gitt for Jira", + "ISSUE_NO_UPDATE_REQUIRED": "Jira: \"{{issueText}}\" allerede oppdatert", + "ISSUE_UPDATE": "Jira: Oppdaterte data for \"{{issueText}}\"", + "MANUAL_UPDATE_ISSUE_SUCCESS": "Jira: Oppdaterte data for \"{{issueText}}\"", + "MISSING_ISSUE_DATA": "Jira: Oppgaver med manglende problemdata funnet. Laster om.", + "NO_AUTO_IMPORT_JQL": "Jira: Ingen søkeord definert for automatisk import", + "NO_VALID_TRANSITION": "Jira: Ingen gyldig overgang konfigurert", + "POLLING": "Jira: Avstemningsendringer for problemer", + "TIMED_OUT": "Jira: Forespørsel ble tidsavbrutt", + "TRANSITION": "Jira: Sett problemet \"{{issueKey}}\" til \"{{name}}\"", + "TRANSITIONS_LOADED": "Jira: Overganger lastet. Bruk valgene nedenfor for å tildele dem", + "TRANSITION_SUCCESS": "Jira: Sett problemet {{issueKey}} til {{chosenTransition}}", + "UNABLE_TO_REASSIGN": "Jira: Kunne ikke overføre billetten til deg selv, fordi du ikke spesifiserte et brukernavn. Vennligst besøk innstillingene." + }, + "STEPPER": { + "CREDENTIALS": "Innloggingsdetaljer", + "DONE": "Du er nå ferdig.", + "LOGIN_SUCCESS": "Vellykket innlogging!", + "TEST_CREDENTIALS": "Test innlogging", + "WELCOME_USER": "Velkommen {{user}}!" + } + }, + "METRIC": { + "BANNER": { + "CHECK": "Jeg gjorde det!" + }, + "CMP": { + "AVG_BREAKS_PER_DAY": "Gj.sn. pauser per dag", + "AVG_TASKS_PER_DAY_WORKED": "Gj.sn. oppgaver per utført dag", + "AVG_TIME_SPENT_ON_BREAKS": "Gj.sn. tid brukt på pauser", + "AVG_TIME_SPENT_PER_DAY": "Gj.sn. tid brukt per dag", + "AVG_TIME_SPENT_PER_TASK": "Gj.sn. tidsbruk per oppgave", + "COUNTING_SUBTASKS": "(teller deloppgaver)", + "DAYS_WORKED": "Dager jobbet", + "IMPROVEMENT_SELECTION_COUNT": "Antall ganger en forbedringsfaktor ble valgt", + "MOOD_PRODUCTIVITY_OVER_TIME": "Humør og produktivitet over tid", + "NO_ADDITIONAL_DATA_YET": "Ingen ytterligere data samlet inn ennå. Bruk skjemaet i det daglige sammendraget \"Evaluering\" -panel for å gjøre det.", + "OBSTRUCTION_SELECTION_COUNT": "Antall ganger en hindrende faktor ble valgt", + "TASKS_DONE_CREATED": "Oppgaver (ferdig / opprettet)", + "TIME_ESTIMATED": "Anslått tid", + "TIME_SPENT": "Tid brukt" + }, + "EVAL_FORM": { + "ADD_NOTE_FOR_TOMORROW": "Legg til notat for i morgen", + "DISABLE_REPEAT_EVERY_DAY": "Deaktiver gjenta hver dag", + "ENABLE_REPEAT_EVERY_DAY": "Gjenta hver dag", + "HELP_H1": "Hvorfor skal jeg bry meg?", + "HELP_LINK_TXT": "Gå til beregningsdelen", + "HELP_P1": "På tide med litt egenevaluering! Svarene dine her lagres og gir deg litt statistikk om hvordan du jobber i beregningsdelen. Videre vil forslagene til i morgen vises over oppgavelisten din neste dag.", + "HELP_P2": "Dette er ment å være mindre om å beregne nøyaktige beregninger eller bli så effektiv som mulig i alt du gjør enn om å forbedre hvordan du føler deg om arbeidet ditt. Det kan være nyttig å evaluere smertepunkter i den daglige rutinen, så vel som å finne faktorer som hjelper deg. Å være litt systematisk om det hjelper forhåpentligvis å få bedre grep om disse og forbedre det du kan.", + "IMPROVEMENTS": "Hva forbedret produktiviteten din?", + "IMPROVEMENTS_TOMORROW": "Hva kan du gjøre for å forbedre i morgen?", + "MOOD": "Hvordan føler du deg?", + "MOOD_HINT": "1: Forferdelig - 10: Fantastisk", + "NOTES": "Merknader for i morgen", + "OBSTRUCTIONS": "Hva hindret produktiviteten din?", + "PRODUCTIVITY": "Hvor effektiv jobbet du?", + "PRODUCTIVITY_HINT": "1: Har ikke en gang startet - 10: Enormt effektiv" + }, + "S": { + "SAVE_METRIC": "Måling vellykket" + } + }, + "NOTE": { + "ADD_REMINDER": "Legg til påminnelse", + "D_ADD": { + "DATETIME_LABEL": "Datetid for påminnelse (valgfritt)", + "NOTE_LABEL": "Skriv inn litt tekst for å lagre som notat ..." + }, + "D_ADD_REMINDER": { + "E_ENTER_TITLE": "Du må oppgi en tittel", + "L_DATETIME": "Datotid for påminnelse", + "L_TITLE": "Tittel for varsling" + }, + "D_VIEW_REMINDER": { + "SNOOZE": "Slumre", + "TITLE": "Merk" + }, + "EDIT_FULLSCREEN": "Rediger i fullskjerm", + "EDIT_REMINDER": "Rediger påminnelse", + "NOTES_CMP": { + "ADD_BTN": "Legg til en ny kommentar", + "DROP_TO_ADD": "Slipp her for å legge til et nytt notat" + }, + "NOTE_CMP": { + "DISABLE_PARSE": "Deaktiver analysering av markdown", + "ENABLE_PARSE": "Aktiver markdown-analyse" + }, + "REMOVE_REMINDER": "Fjern påminnelse", + "S": { + "ADDED_REMINDER": "Lagt til påminnelse for merknad", + "DELETED_REMINDER": "Slettet påminnelse for notat", + "UPDATED_REMINDER": "Oppdatert påminnelse for merknad" + }, + "UPDATE_REMINDER": "Oppdateringspåminnelse" + }, + "POMODORO": { + "BACK_TO_WORK": "Tilbake til arbeid!", + "BREAK_IS_DONE": "Pausen din er ferdig!", + "ENJOY_YOURSELF": "Kos deg, få deg i bevegelse, kom inn igjen:", + "FINISH_SESSION_X": "Du har fullført økten {{nr}} !", + "NOTIFICATION": { + "BREAK_X_START": "Pomodoro: Pause {{nr}} startet!", + "SESSION_X_START": "Pomodoro: Økten {{nr}} startet!" + }, + "S": { + "SESSION_X_START": "Pomodoro: Økten {{nr}} startet!" + }, + "SKIP_BREAK": "Hopp over pause" + }, + "PROCRASTINATION": { + "BACK_TO_WORK": "Tilbake til arbeid!", + "COMP": { + "INTRO": "Å vise deg selv litt medfølelse er alltid en god idé. Det forbedrer følelsen av egenverd, fremmer positive følelser og kan selvfølgelig hjelpe deg med å overvinne utsettelse. Prøv en liten øvelse:", + "L1": "Sett deg litt og strekk deg, hvis du vil, ro deg litt ned", + "L2": "Prøv å lytte til tankene og følelsene som oppstår", + "L3": "Svarer du på deg selv på en måte som du vil svare på en venn?", + "L4": "Hvis svaret er nei, forestill deg vennen din i din situasjon. Hva vil du si til dem? Hva ville du gjøre for dem?", + "OUTRO": "Flere øvelser finner du her eller på google .", + "TITLE": "Selvmedfølelse" + }, + "CUR": { + "INTRO": "Utsettelse er interessant, ikke sant? Det gir ikke mening å gjøre det. Ikke i din langsiktige interesse i det hele tatt. Men fortsatt gjør alle det. Kos deg og utforsk!", + "L1": "Hvilke følelser vekker fristelsen din til å utsette?", + "L2": "Hvor føler du dem i kroppen din?", + "L3": "Hva minner de deg om?", + "L4": "Hva skjer med tanken på å utsette mens du observerer det? Forsterker det seg? Forsvinne? Får andre følelser til å oppstå?", + "L5": "Hvordan skifter følelsene i kroppen din når du fortsetter å hvile bevisstheten din på dem?", + "TITLE": "Nysgjerrighet" + }, + "H1": "Slapp av litt!", + "P1": "Først av alt slapp av! Alle gjør det en gang i blant. Og hvis du ikke gjør det du burde, bør du i det minste nyte det! Ta en titt på delene nedenfor for å finne noe nyttig.", + "P2": "Hvis du vil vite mer om vitenskapen bak alt her, kan jeg anbefale denne artikkelen som er noen av øvelsene.", + "P3": "Husk: Utsettelse er et følelsesreguleringsproblem, ikke et tidsstyringsproblem.", + "REFRAME": { + "INTRO": "Tenk på hva som kan være positivt med oppgaven til tross for manglene.", + "TITLE": "Omramning", + "TL1": "Hva kan være interessant med det?", + "TL2": "Hva kan du tjene hvis du fullfører det?", + "TL3": "Hvordan vil du ha det med det hvis du fullfører det?" + }, + "SPLIT_UP": { + "INTRO": "Del oppgaven i så mange små biter du kan.", + "OUTRO": "Ferdig? Tenk så på det. Hva ville være - strengt teoretisk - det første du ville gjort hvis du skulle begynne å jobbe med oppgaven? Bare tenk på det...", + "TITLE": "Del den opp!" + } + }, + "PROJECT": { + "D_CREATE": { + "CREATE": "Lag prosjekt", + "EDIT": "Rediger prosjekt", + "SETUP_GIT": "Konfigurer Git-integrasjon", + "SETUP_GITLAB": "Konfigurer Gitlab-integrasjon", + "SETUP_JIRA": "Oppsett Jira Integration" + }, + "FORM_BASIC": { + "L_TITLE": "Prosjektnavn", + "TITLE": "Grunnleggende innstillinger" + }, + "FORM_THEME": { + "D_IS_DARK_THEME": "Vil ikke brukes hvis systemet støtter global mørk modus.", + "HELP": "Temainnstillinger for prosjektet ditt.", + "L_COLOR_ACCENT": "Aksentfarge", + "L_COLOR_PRIMARY": "Primærfarge", + "L_COLOR_WARN": "Advarsel / feilfarge", + "L_HUE_ACCENT": "Terskel for mørk tekst på aksentfargebakgrunn", + "L_HUE_PRIMARY": "Terskel for mørk tekst på primærfargebakgrunn", + "L_HUE_WARN": "Terskel for mørk tekst på advarselfargebakgrunn", + "L_IS_AUTO_CONTRAST": "Sett inn tekstfarger automatisk for best lesbarhet", + "L_IS_DISABLE_BACKGROUND_GRADIENT": "Deaktiver farget bakgrunnsforløpning", + "L_IS_REDUCED_THEME": "Bruk redusert brukergrensesnitt (ingen ruter rundt oppgaver)", + "L_THEME_COLOR": "Temafarge", + "L_TITLE": "Tittel", + "TITLE": "Tema" + }, + "S": { + "ARCHIVED": "Arkivert prosjekt", + "CREATED": "Opprettet prosjekt {{title}} . Du kan velge det fra menyen øverst til venstre.", + "DELETED": "Slettet prosjekt", + "E_EXISTS": "Prosjektet \"{{title}}\" eksisterer allerede", + "E_INVALID_FILE": "Ugyldige data for prosjektfilen", + "ISSUE_PROVIDER_UPDATED": "Oppdaterte prosjektinnstillinger for {{issueProviderKey}}", + "UNARCHIVED": "Ikke arkivert prosjekt", + "UPDATED": "Oppdaterte prosjektinnstillinger" + } + }, + "REMINDER": { + "S_REMINDER_ERR": "Feil for påminnelsesgrensesnitt" + }, + "SIMPLE_COUNTER": { + "D_CONFIRM_REMOVE": { + "MSG": "Slette en enkel teller vil også slette alle tidligere data som er sporet på den. Er du sikker på at du vil fortsette?", + "OK": "Gjør det!" + }, + "D_EDIT": { + "L_COUNTER": "Telle", + "TITLE": "Rediger enkel teller" + }, + "FORM": { + "ADD_NEW": "Legg til enkel teller", + "HELP": "Her kan du konfigurere enkle knapper som vises øverst til høyre. De kan enten være tidtakere eller bare en enkel teller, som telles opp, ved å klikke på den.", + "L_AUTO_COUNT_UP": "Automatisk utløsertelling opp for", + "L_AUTO_SWITCH_OFF": "Automatisk utkobling for", + "L_AUTO_SWITCH_ON": "Automatisk utløserbryter på for", + "L_ICON": "Ikon", + "L_ICON_ON": "Ikon når det er slått på", + "L_IS_ENABLED": "Aktivert", + "L_TITLE": "Tittel", + "L_TYPE": "Type", + "TITLE": "Enkle tellere", + "TYPE_CLICK_COUNTER": "Klikk på teller", + "TYPE_STOPWATCH": "Stoppeklokke" + } + }, + "TAG": { + "D_CREATE": { + "CREATE": "Opprett tag", + "EDIT": "Rediger tag" + }, + "D_DELETE": { + "CONFIRM_MSG": "Vil du virkelig slette koden \"{{tagName}}\"? Det vil bli fjernet fra alle oppgaver. Dette kan ikke angres." + }, + "D_EDIT": { + "ADD": "Legg til koder for \"{{title}}\"", + "EDIT": "Rediger tagger for \"{{title}}\"", + "LABEL": "Merker" + }, + "FORM_BASIC": { + "L_COLOR": "Farge (hvis udefinert primær temafarge brukes)", + "L_ICON": "Ikon", + "L_TITLE": "Merkets navn", + "TITLE": "Grunnleggende innstillinger" + }, + "S": { + "UPDATED": "Tag-innstillinger ble oppdatert" + } + }, + "TASK": { + "ADDITIONAL_INFO": { + "ADD_ATTACHMENT": "Legg til vedlegg", + "ADD_SUB_TASK": "Legg til underoppgave", + "ATTACHMENTS": "Vedlegg ({{nr}})", + "FROM_PARENT": "(fra forelder)", + "LOCAL_ATTACHMENTS": "Lokale vedlegg", + "NOTES": "Merknader", + "PARENT": "Foreldre", + "REMINDER": "Påminnelse", + "REPEAT": "Gjenta", + "SCHEDULE_TASK": "Planlegg oppgave", + "SUB_TASKS": "Underoppgaver ({{nr}})", + "TIME": "Tid" + }, + "ADD_TASK_BAR": { + "ADD_EXISTING_TASK": "Legg til eksisterende oppgave \"{{taskTitle}}\"", + "ADD_ISSUE_TASK": "Legg til utgave nr. {{issueNr}} fra {{issueType}}", + "ADD_TASK": "Legg til oppgave", + "ADD_TASK_TO_BACKLOG": "Legg til oppgave i backloggen", + "CREATE_TASK": "Lag ny oppgave", + "EXAMPLE": "Eksempel: \"Noen oppgavetittel + prosjektnavn #en tag #en annen tag 10m / 3h\"", + "START": "Trykk enter en gang til for å starte" + }, + "B": { + "ADD_HALF_HOUR": "Tilsett 1/2 time", + "ESTIMATE_EXCEEDED": "Tidsestimatet overskredet for \"{{title}}\"" + }, + "CMP": { + "ADD_SUB_TASK": "Legg til underoppgave", + "ADD_TO_MY_DAY": "Legg til dagen min", + "ADD_TO_PROJECT": "Legg til et prosjekt", + "CONVERT_TO_PARENT_TASK": "Konverter til foreldreoppgave", + "DELETE": "Slett oppgave", + "DROP_ATTACHMENT": "Slipp her for å legge ved \"{{title}}\"", + "EDIT_REMINDER": "Rediger påminnelse", + "EDIT_TAGS": "Rediger koder", + "MARK_DONE": "Marker som ferdig", + "MARK_UNDONE": "Merk som ugjort", + "MOVE_TO_BACKLOG": "Gå til backlog", + "MOVE_TO_OTHER_PROJECT": "Gå til et annet prosjekt", + "MOVE_TO_TODAY": "Gå til dagens liste", + "OPEN_ATTACH": "Legg ved fil eller lenke", + "OPEN_ISSUE": "Åpne i nettleseren", + "OPEN_TIME": "Tidssporing", + "REMOVE_FROM_MY_DAY": "Fjern fra Min dag", + "REPEAT_EDIT": "Rediger konfigurasjon for gjentatt oppgave", + "SCHEDULE": "Planlegg oppgaven", + "SHOW_UPDATES": "Vis oppdateringer", + "TOGGLE_ADDITIONAL": "Vis / skjul tilleggsinformasjon", + "TOGGLE_ATTACHMENTS": "Vis / skjul vedlegg", + "TOGGLE_DONE": "Merk som ferdig / angre", + "TOGGLE_SUB_TASK_VISIBILITY": "Bytt synlighet av underoppgave", + "TRACK_TIME": "Begynn å spore tid", + "TRACK_TIME_STOP": "Sett sporingstid på pause", + "UPDATE_ISSUE_DATA": "Oppdater data om problemet" + }, + "D_REMINDER_ADD": { + "DATETIME_FOR": "Datotid for påminnelse", + "EDIT": "Rediger påminnelse", + "MOVE_TO_BACKLOG": "Flytt oppgaven til backlogg helt til planlagt", + "SCHEDULE": "Legg til planlagt", + "UNSCHEDULE": "Fjern fra planlagt" + }, + "D_REMINDER_VIEW": { + "ADD_ALL_TO_TODAY": "Legg alt til i dag", + "ADD_TO_TODAY": "Legg til i dag", + "DISMISS": "Avvis påminnelse", + "DISMISS_ALL": "Avvis alle", + "DUE_TASK": "Forfalt oppgave", + "DUE_TASKS": "Forfalte oppgaver", + "FOR_CURRENT": "Oppgaven skal utføres. Vil du begynne å jobbe med det?", + "FOR_OTHER": "Oppgaven skal utføres. Vil du begynne å jobbe med det?", + "FROM_PROJECT": "Fra prosjekt: \"{{title}}\"", + "FROM_TAG": "Fra tag: \"{{title}}\"", + "SNOOZE": "Slumre", + "SNOOZE_ALL": "Utsett alle", + "SNOOZE_UNTIL_TOMORROW": "Til i morgen", + "START": "Start", + "SWITCH_CONTEXT_START": "Bytt kontekst og start" + }, + "D_TIME": { + "ADD_FOR_OTHER_DAY": "Legg til tid brukt den andre dagen", + "DELETE_FOR": "Slett oppføringen for dagen", + "ESTIMATE": "Anslag", + "TIME_SPENT": "Tid brukt", + "TIME_SPENT_ON": "Tidsbruk {{date}}", + "TITLE": "Tidsbruk / estimater" + }, + "D_TIME_FOR_DAY": { + "ADD_ENTRY_FOR": "Legg til ny oppføring for {{date}}", + "DATE": "Dato for nyoppføring", + "HELP": "Eksempler:
30m => 30 minutter
2t => 2 timer
2t 30m => 2 timer og 30 minutter", + "TINE_SPENT": "Tid brukt", + "TITLE": "Legg til for dagen" + }, + "N": { + "ESTIMATE_EXCEEDED": "Tidsoverslag overskredet!", + "ESTIMATE_EXCEEDED_BODY": "Du overskred beregnet tid for \"{{title}}\"." + }, + "S": { + "DELETED": "Slettet oppgave \"{{title}}\"", + "FOUND_MOVE_FROM_BACKLOG": "Flyttet oppgave {{title}} fra backlog til dagens oppgaveliste", + "FOUND_MOVE_FROM_OTHER_LIST": "Lagt til oppgave {{title}} fra {{contextTitle}} til gjeldende liste", + "FOUND_RESTORE_FROM_ARCHIVE": "Gjenopprettet oppgave {{title}} relatert til utgave fra arkivet", + "LAST_TAG_DELETION_WARNING": "Du prøver å fjerne den siste taggen for en ikke-prosjektoppgave. Dette er ikke tillatt!", + "REMINDER_ADDED": "Planlagt oppgave \"{{title}}\"", + "REMINDER_DELETED": "Slettet påminnelse for oppgaven", + "REMINDER_UPDATED": "Oppdatert påminnelse for oppgaven \"{{title}}\"", + "TASK_CREATED": "Opprettet oppgaven \"{{title}}\"" + }, + "SELECT_OR_CREATE": "Velg eller opprett oppgave", + "SUMMARY_TABLE": { + "ESTIMATE": "anslag", + "SPENT_TODAY": "Brukte i dag", + "SPENT_TOTAL": "Brukte totalt", + "TASK": "Oppgave", + "TOGGLE_DONE": "av- / merk som ferdig" + } + }, + "TASK_REPEAT": { + "D_CONFIRM_REMOVE": { + "MSG": "Hvis du fjerner gjenta konfigurasjonen, konverteres alle tidligere forekomster av denne oppgaven til bare vanlige oppgaver. Er du sikker på at du vil fortsette", + "OK": "Fjern helt" + }, + "D_EDIT": { + "ADD": "Legg til gjenta oppgavekonfigurasjon", + "EDIT": "Rediger gjenta oppgavekonfigurasjon", + "HELP1": "Gjentatte oppgaver er ment for daglige gjøremål, for eksempel: \"Organisasjon\", \"Daglig møte\", \"Kodegjennomgang\", \"Kontrollerer e-post\" eller lignende oppgaver som sannsynligvis vil oppstå igjen og igjen.", + "HELP2": "Når den er konfigurert, blir en gjentatt oppgave gjenskapt hver dag valgt nedenfor så snart du åpner prosjektet, og vil automatisk bli merket som fullført på slutten av dagen. De vil bli håndtert som forskjellige forekomster. Så du kan fritt legge til underoppgaver etc.", + "HELP3": "Oppgaver importert fra Jira eller Git Issues kan ikke gjentas. Alle påminnelser vil også bli slettet på en gjentatt oppgave.", + "TAG_LABEL": "Merker å legge til" + }, + "F": { + "DEFAULT_ESTIMATE": "Standard estimat", + "FRIDAY": "fredag", + "IS_ADD_TO_BOTTOM": "Flytt oppgaven til bunnen av listen", + "MONDAY": "mandag", + "SATURDAY": "lørdag", + "SUNDAY": "søndag", + "THURSDAY": "Torsdag", + "TITLE": "Tittel for oppgave", + "TUESDAY": "tirsdag", + "WEDNESDAY": "onsdag" + } + }, + "TIME_TRACKING": { + "B": { + "ALREADY_DID": "Det gjorde jeg allerede", + "SNOOZE": "Utsett {{time}}" + }, + "B_TTR": { + "ADD_TO_TASK": "Legg til oppgave", + "MSG": "Du har ikke sporet tid for {{time}}" + }, + "D_IDLE": { + "BREAK": "Pause", + "CREATE_AND_TRACK": "Opprette og spore til", + "IDLE_FOR": "Du har vært inaktiv for:", + "SKIP": "Hopp over", + "TASK": "Oppgave", + "TASK_BREAK": "Oppgave + pause", + "TRACK_TO": "Spor til" + }, + "D_TRACKING_REMINDER": { + "UNTRACKED_TIME": "Usporet tid:", + "TRACK_TO": "Spor til:", + "CREATE_AND_TRACK": "Opprette og spore til", + "IDLE_FOR": "Du har vært inaktiv for:", + "TASK": "Oppgave" + } + }, + "WORKLOG": { + "CMP": { + "DAYS_WORKED": "Dager, jobbet:", + "MONTH_WORKED": "Arbeidet måned:", + "REPEATING_TASK": "Gjenta oppgaven", + "RESTORE_TASK_FROM_ARCHIVE": "Gjenopprett oppgave fra arkiv", + "TASKS": "Oppgaver", + "TOTAL_TIME": "Totalt brukt tid:", + "WEEK_NR": "Uke {{nr}}", + "WORKED": "Jobbet" + }, + "D_CONFIRM_RESTORE": "Er du sikker på at du vil flytte oppgaven "{{title}}" til dagens oppgaveliste?", + "D_EXPORT_TITLE": "Eksporter arbeidslogg {{start}} - {{end}}", + "D_EXPORT_TITLE_SINGLE": "Eksporter arbeidslogg {{day}}", + "EXPORT": { + "ADD_COL": "Legg til kolonne", + "COPY_TO_CLIPBOARD": "Kopiere til utklippstavle", + "DONT_ROUND": "ikke rund av", + "EDIT_COL": "Rediger kolonne", + "GROUP_BY": "Gruppe av", + "O": { + "DATE": "Dato", + "ENDED_WORKING": "Sluttet å jobbe", + "ESTIMATE_AS_CLOCK": "Beregn som klokke (f.eks. 5:23)", + "ESTIMATE_AS_MILLISECONDS": "Beregn som millisekunder", + "ESTIMATE_AS_STRING": "Anslag som streng (f.eks. 5t 23m)", + "FULL_HALF_HOURS": "hele halvtimen", + "FULL_HOURS": "hele timer", + "FULL_QUARTERS": "hele kvartalet", + "PARENT_TASK": "Foreldreoppgave", + "PARENT_TASK_TITLES_ONLY": "Bare foreldreoppgavetitler", + "STARTED_WORKING": "Begynte å jobbe", + "TASK_SUBTASK": "Oppgave / deloppgave", + "TIME_AS_CLOCK": "Tid som klokke (f.eks. 5:23)", + "TIME_AS_MILLISECONDS": "Tid som millisekunder", + "TIME_AS_STRING": "Tid som streng (f.eks. 5t 23m)", + "TITLES_AND_SUB_TASK_TITLES": "Titler og underoppgavetitler", + "WORKLOG": "Arbeidslogg" + }, + "OPTIONS": "Alternativer", + "ROUND_END_TIME_TO": "Rund sluttid til", + "ROUND_START_TIME_TO": "Rund starttid til", + "ROUND_TIME_WORKED_TO": "Rundtiden jobbet til", + "SAVE_TO_FILE": "Lagre som fil", + "SEPARATE_TASKS_BY": "Skille oppgaver med", + "SHOW_AS_TEXT": "Vis som tekst" + }, + "WEEK": { + "EXPORT": "Eksporter ukedata", + "NO_DATA": "Ingen oppgaver denne uken ennå.", + "TITLE": "Tittel" + } + } + }, + "FILE_IMEX": { + "EXPORT_DATA": "Eksporter data", + "IMPORT_FROM_FILE": "Importer fra fil", + "S_ERR_INVALID_DATA": "Import mislyktes: Ugyldig JSON" + }, + "G": { + "CANCEL": "Avbryt", + "CLICK_TO_EDIT": "klikk for å redigere", + "CLOSE": "Lukk", + "DELETE": "Slett", + "DISMISS": "Avvis", + "DO_IT": "Gjør det!", + "EDIT": "Redigere", + "EXTENSION_INFO": "Last ned chrome-utvidelsen for å tillate kommunikasjon med Jira Api og Idle Time Handling. Merk at dette ikke fungerer for mobil.", + "LOGIN": "Logg Inn", + "LOGOUT": "Logg ut", + "MINUTES": "{{m}} minutter", + "NEXT": "Neste", + "NONE": "Ingen", + "NO_CON": "Du er for øyeblikket frakoblet. Koble til Internett på nytt.", + "OK": "Ok", + "PREVIOUS": "Tidligere", + "REMOVE": "Ta vekk", + "RESET": "Nullstille", + "SAVE": "Lagre", + "TITLE": "Tittel", + "UNDO": "Angre", + "UPDATE": "Oppdater", + "WITHOUT_PROJECT": "Uten prosjekt" + }, + "GCF": { + "AUTO_BACKUPS": { + "HELP": "Lagre alle data automatisk i appmappen din for å ha den klar i tilfelle noe går galt.", + "LABEL_IS_ENABLED": "Aktiver automatiske sikkerhetskopier", + "LOCATION_INFO": "Sikkerhetskopier lagres i:", + "TITLE": "Automatiske sikkerhetskopier" + }, + "EVALUATION": { + "IS_HIDE_EVALUATION_SHEET": "Skjul evalueringsark på daglig sammendrag", + "TITLE": "Evaluering og beregninger" + }, + "GOOGLE_DRIVE_SYNC": { + "HELP": "Her kan du konfigurere appen din til automatisk å synkronisere til og fra en enkelt Google Drive-fil. Alle data lagres ukryptert, så pass på at du ikke ved en feiltakelse deler denne filen med noen.", + "TITLE": "Synkroniser via Google Disk" + }, + "IDLE": { + "HELP": "

Når håndtering av inaktiv tid er aktivert, åpnes en dialog etter en spesifisert tid for å sjekke om og på hvilken oppgave du vil spore tiden din, når du har vært inaktiv.

", + "IS_ENABLE_IDLE_TIME_TRACKING": "Aktiver håndtering av inaktiv tid", + "IS_ONLY_OPEN_IDLE_WHEN_CURRENT_TASK": "Bare utløs tomgangsdialog når en aktuell oppgave er valgt", + "IS_UN_TRACKED_IDLE_RESETS_BREAK_TIMER": "Usporet inaktiv tid tilbakestiller 'ta en pause'-timer", + "MIN_IDLE_TIME": "Utløser tomgang etter X", + "TITLE": "Tomgangshåndtering" + }, + "IMEX": { + "HELP": "

Her kan du eksportere alle dataene dine som en JSON for sikkerhetskopiering, men også for å bruke dem i en annen kontekst (f.eks. Vil du kanskje eksportere prosjektene dine i nettleseren og importere dem til desktopversjonen).

Importen forventer at gyldig JSON kopieres til tekstområdet. MERKNAD: Når du trykker på importknappen, overskrives alle dine nåværende innstillinger og data!

", + "TITLE": "Import Eksport" + }, + "KEYBOARD": { + "ADD_NEW_NOTE": "Legg til et nytt notat", + "ADD_NEW_TASK": "Legg til ny oppgave", + "APP_WIDE_SHORTCUTS": "Globale snarveier (applikasjonsbredt)", + "COLLAPSE_SUB_TASKS": "Skjul underoppgaver", + "EXPAND_SUB_TASKS": "Utvid underoppgaver", + "GLOBAL_ADD_NOTE": "Legg til et nytt notat", + "GLOBAL_ADD_TASK": "Legg til en ny oppgave", + "GLOBAL_SHOW_HIDE": "Vis / skjul Super Productivity", + "GLOBAL_TOGGLE_TASK_START": "Bytt tidssporing for siste aktive oppgave", + "GO_TO_DAILY_AGENDA": "Gå til Agenda", + "GO_TO_FOCUS_MODE": "Gå til Fokusmodus", + "GO_TO_SETTINGS": "Gå til Innstillinger", + "GO_TO_WORK_VIEW": "Gå til arbeidsvisning", + "HELP": "

Her kan du konfigurere alle hurtigtaster.

Klikk på tekstinntastingen og skriv inn ønsket tastaturkombinasjon. Trykk på Enter for å lagre og Escape for å avbryte.

Det er tre typer snarveier:

  • Globale snarveier: Når appen kjører, vil den utløse handlingen fra alle andre applikasjoner.
  • Snarveier på applikasjonsnivå: Utløses fra alle skjermbilder i applikasjonen, men ikke hvis du for øyeblikket redigerer et tekstfelt.
  • Snarveier på oppgavennivå: De utløses bare hvis du har valgt en oppgave via mus eller tastatur og vanligvis utløser en handling spesifikt relatert til den ene oppgaven.
", + "MOVE_TASK_DOWN": "Flytt Oppgave ned i Liste", + "MOVE_TASK_UP": "Flytt oppgaven oppover i listen", + "MOVE_TO_BACKLOG": "Flytt oppgave til oppgavestandard", + "MOVE_TO_TODAYS_TASKS": "Flytt oppgave til dagens oppgaveliste", + "OPEN_PROJECT_NOTES": "Vis / skjul prosjektnotater", + "SELECT_NEXT_TASK": "Velg neste oppgave", + "SELECT_PREVIOUS_TASK": "Velg forrige oppgave", + "SYSTEM_SHORTCUTS": "Globale snarveier (hele systemet)", + "TASK_ADD_SUB_TASK": "Legg til underoppgave", + "TASK_DELETE": "Slett oppgave", + "TASK_EDIT_TITLE": "Rediger tittel", + "TASK_MOVE_TO_PROJECT": "Åpne flytt oppgave til prosjektmeny", + "TASK_OPEN_ESTIMATION_DIALOG": "Rediger estimering / tid brukt", + "TASK_SCHEDULE": "Planlegg oppgave", + "TASK_SHORTCUTS": "Oppgaver", + "TASK_SHORTCUTS_INFO": "Følgende snarveier gjelder for den valgte oppgaven (valgt via fane eller mus).", + "TASK_TOGGLE_ADDITIONAL_INFO_OPEN": "Vis / skjul tilleggsinformasjon", + "TASK_TOGGLE_DONE": "Slå på Ferdig", + "TITLE": "Tastatursnarveier", + "TOGGLE_BACKLOG": "Vis / skjul oppgavestand", + "TOGGLE_BOOKMARKS": "Vis / skjul bokmerkefelt", + "TOGGLE_PLAY": "Start / stopp oppgave", + "ZOOM_DEFAULT": "Zoomstandard (bare skrivebord)", + "ZOOM_IN": "Zoom inn (bare skrivebordet)", + "ZOOM_OUT": "Zoom ut (bare skrivebordet)" + }, + "LANG": { + "AR": "Arabisk", + "DE": "Tysk", + "EN": "Engelsk", + "ES": "Spansk", + "FA": "Farsi", + "FR": "Fransk", + "IT": "Italiensk", + "JA": "Japansk", + "KO": "Koreansk", + "LABEL": "Velg et språk", + "NB":"Norsk Bokmål", + "NL": "Nederlandsk", + "PT": "Portugisisk", + "RU": "Russisk", + "TITLE": "Språk", + "TR": "Tyrkisk", + "ZH": "Kinesisk" + }, + "MISC": { + "DEFAULT_PROJECT": "Standard prosjekt som skal brukes til oppgaver hvis ingen er spesifisert", + "HELP": "

Ser du ikke skrivebordsvarsler? For Windows vil du kanskje sjekke System> Varsler og handlinger og sjekke om de nødvendige varslene er aktivert.

", + "IS_AUTO_ADD_WORKED_ON_TO_TODAY": "Legg til dagens tag automatisk for å jobbe med oppgaver", + "IS_AUTO_MARK_PARENT_AS_DONE": "Merk foreldreoppgaven som ferdig når alle underoppgaver er utført", + "IS_AUTO_START_NEXT_TASK": "Begynn å spore neste oppgave når du merker nåværende som ferdig", + "IS_CONFIRM_BEFORE_EXIT": "Bekreft før du avslutter appen", + "IS_DARK_MODE": "Mørk modus", + "IS_DISABLE_INITIAL_DIALOG": "Deaktiver innledende infodialog (du kan gå glipp av viktige oppdateringer!)", + "IS_HIDE_NAV": "Skjul navigasjonen til hovedoverskriften er svevet (kun på skrivebordet)", + "IS_NOTIFY_WHEN_TIME_ESTIMATE_EXCEEDED": "Gi beskjed når tidsestimatet ble overskredet", + "IS_TURN_OFF_MARKDOWN": "Slå av Markdown-parsering for notater", + "TITLE": "Diverse innstillinger", + "FIRST_DAY_OF_WEEK": "Første ukedag" + }, + "POMODORO": { + "BREAK_DURATION": "Varighet av korte pauser", + "CYCLES_BEFORE_LONGER_BREAK": "Start lengre pause etter X-arbeidsøkter", + "DURATION": "Varigheten av arbeidsøktene", + "HELP": "

Pomodoro-timeren kan konfigureres via et par innstillinger. Varigheten av hver arbeidsøkt, varigheten av normale pauser, antall arbeidsøkter som skal kjøres før en lengre pause startes og varigheten av denne lengre pausen.

Du kan også angi om du vil vise distraksjoner i pomodoro-pausene dine.

Innstilling av "Pause tidssporing på pomodoro pause" vil også spore pausene dine som arbeidstid brukt på en oppgave.

Aktivering av "Pause pomodoro-økt midlertidig når ingen aktiv oppgave er aktivert" vil også pomodoro-økten pause når du setter en oppgave på pause.

", + "IS_ENABLED": "Aktiver pomodoro", + "IS_MANUAL_CONTINUE": "Bekreft manuelt start av neste pomodoro-økt", + "IS_PLAY_SOUND": "Spill lyd når økten er ferdig", + "IS_PLAY_SOUND_AFTER_BREAK": "Spill lyd når pause er ferdig", + "IS_PLAY_TICK": "Spill av krysslyd hvert sekund", + "IS_STOP_TRACKING_ON_BREAK": "Stopp tidsporing for oppgave på pause", + "LONGER_BREAK_DURATION": "Varighet av lengre pauser", + "TITLE": "Pomodoro Timer" + }, + "SOUND": { + "DONE_SOUND": "Oppgavelyd", + "IS_INCREASE_DONE_PITCH": "Øk tonehøyde for hver oppgave", + "IS_PLAY_DONE_SOUND": "Spill lyd når oppgaven er merket som ferdig", + "TITLE": "Lyd", + "VOLUME": "Volum" + }, + "TAKE_A_BREAK": { + "HELP": "

Lar deg konfigurere en påminnelse som kommer igjen når du har jobbet i en spesifisert tid uten å ta en pause.

Du kan endre meldingen som vises. $ {duration} blir erstattet med tiden brukt uten pause.

", + "IS_ENABLED": "Aktiver påminnelse om å ta en pause", + "IS_FOCUS_WINDOW": "Fokuser appvinduet når påminnelsen er aktiv (kun på skrivebordet)", + "IS_LOCK_SCREEN": "Låseskjerm når en pause er forfalt (kun på skrivebordet)", + "MESSAGE": "Ta en pause-melding", + "MIN_WORKING_TIME": "Trigger ta en pause varsel etter X arbeider uten en", + "MOTIVATIONAL_IMG": "Motiverende bilde (nettadresse)", + "TITLE": "Pausepåminnelse" + }, + "TRACKING_REMINDER": { + "HELP": "Konfigurer et banner for å vises i tilfelle du glemte å starte tidssporing.", + "TITLE": "Påminnelse om tidssporing", + "L_IS_ENABLED": "Aktivert", + "L_IS_SHOW_ON_MOBILE": "Vis på mobilappen", + "L_MIN_TIME": "Tid til å vente før du viser Banner" + } + }, + "GLOBAL_SNACK": { + "COPY_TO_CLIPPBOARD": "Kopiert til utklippstavlen", + "ERR_COMPRESSION": "Feil for kompresjonsgrensesnitt", + "PERSISTENCE_DISALLOWED": "Data vil ikke vedvares permanent. Vær oppmerksom på at dette kan føre til tap av data !!", + "RUNNING_X": "Kjører \"{{str}}\".", + "SHORTCUT_WARN_OPEN_BOOKMARKS_FROM_TAG": "{{keyCombo}} ble trykket, men åpne bokmerkesnarvei er bare tilgjengelig i prosjektsammenheng.", + "SHORTCUT_WARN_OPEN_NOTES_FROM_TAG": "{{keyCombo}} ble trykket, men snarveien til åpne notater er bare tilgjengelig i prosjektsammenheng." + }, + "GPB": { + "ASSETS": "Laster inn ressurser ...", + "DBX_DOWNLOAD": "Dropbox: Last ned fil ...", + "DBX_GEN_TOKEN": "Dropbox: Generer token ...", + "DBX_META": "Dropbox: Få metadata om fil ...", + "DBX_UPLOAD": "Dropbox: Last opp fil ...", + "GDRIVE_DOWNLOAD": "Google Drive: Last ned fil ...", + "GDRIVE_UPLOAD": "Google Drive: Last opp fil ...", + "GITHUB_LOAD_ISSUE": "Github: Last problemdata ...", + "JIRA_LOAD_ISSUE": "Jira: Last inn data ..." + }, + "MH": { + "ADD_NEW_TASK": "Legg til ny oppgave", + "CREATE_PROJECT": "Lag prosjekt", + "CREATE_TAG": "Opprett tag", + "DELETE_TAG": "Slett tag", + "GO_TO_TASK_LIST": "Gå til oppgavelisten", + "MANAGE_PROJECTS": "Administrer prosjekter", + "METRICS": "Beregninger", + "NOTES": "Merknader", + "PROCRASTINATE": "Utsette", + "PROJECTS": "Prosjekter", + "PROJECT_MENU": "Prosjektmeny", + "PROJECT_SETTINGS": "Prosjektinnstillinger", + "SCHEDULED": "Planlagt", + "SETTINGS": "Innstillinger", + "TAGS": "Merker", + "TASKS": "Oppgaver", + "TASK_LIST": "Oppgaveliste", + "TOGGLE_SHOW_BOOKMARKS": "Vis / skjul bokmerker", + "TOGGLE_SHOW_NOTES": "Vis / skjul prosjektnotater", + "TOGGLE_TRACK_TIME": "Start / stopp sporingstid", + "WORKLOG": "Arbeidslogg" + }, + "PDS": { + "BACK": "Vent, jeg glemte noe!", + "BREAK_LABEL": "Pause (nr / tid)", + "CELEBRATE": "Ta deg tid til å feire!", + "CLEAR_ALL_CONTINUE": "Fjern alt ferdig og fortsett", + "D_CONFIRM_APP_CLOSE": { + "CANCEL": "Nei, bare fjern oppgavene", + "MSG": "Arbeidet ditt er gjort. På tide å gå hjem!", + "OK": "Jepp! Skru av!" + }, + "EVALUATION": "Evaluering", + "EXPORT_TASK_LIST": "Eksporter oppgaveliste", + "NO_TASKS": "Det er ingen oppgaver for denne dagen", + "PLAN": "Plan", + "ROUND_15M": "Avrund alle oppgavene til 15 minutter", + "ROUND_30M": "Avrund alle oppgavene til 30 minutter", + "ROUND_5M": "Avrund alle oppgavene til 5 minutter", + "ROUND_TIME_SPENT": "Avrund tid brukt", + "ROUND_TIME_SPENT_TITLE": "Avrund tid brukt på alle oppgaver. Vær forsiktig! Du kan ikke angre dette!", + "ROUND_TIME_WARNING": "!!! Vær forsiktig, dette kan ikke angres !!!", + "ROUND_UP_15M": "Avrund opp alle oppgavene til 15 minutter", + "ROUND_UP_30M": "Avrund opp alle oppgavene til 30 minutter", + "ROUND_UP_5M": "Avrund opp alle oppgavene til 5 minutter", + "SAVE_AND_GO_HOME": "Lagre og dra hjem", + "START_END": "Start - Slutt", + "SUMMARY_FOR": "Daglig sammendrag for {{dayStr}}", + "TASKS_COMPLETED": "Oppgaver fullført", + "TASK_LIST": "Oppgaveliste", + "TIME_SPENT_AND_ESTIMATE_LABEL": "Tid brukt / estimert", + "TIME_SPENT_ESTIMATE_TITLE": "Tidsbruk: Total tid brukt i dag. Arkiverte oppgaver er ikke inkludert. - Beregnet tid: Anslått tid for oppgaver som jobbes med i dag minus tiden som allerede er brukt sammen med dem andre dager.", + "TODAY": "I dag", + "WEEK": "Uke" + }, + "PM": { + "TITLE": "Prosjektstatistikk" + }, + "PP": { + "ARCHIVED_PROJECTS": "Arkiverte prosjekter", + "ARCHIVE_PROJECT": "Arkivprosjekt", + "CREATE_NEW": "Lag ny", + "DELETE_PROJECT": "Slett prosjekt", + "D_CONFIRM_ARCHIVE": { + "MSG": "Er du sikker på at du vil arkivere dette prosjektet? Arkiverte prosjekter vises ikke lenger i menyen, og du kan ikke få tilgang til dataene deres uten å gjenopprette dem. Det anbefales at du sikkerhetskopierer dataene dine før du gjør dette.", + "OK": "Arkiv" + }, + "D_CONFIRM_DELETE": { + "MSG": "Er du sikker på at du vil slette dette prosjektet? Det anbefales å sikkerhetskopiere dataene dine før du gjør dette.", + "OK": "Slett" + }, + "D_CONFIRM_UNARCHIVE": { + "MSG": "Er du sikker på at du vil fjerne arkivet for dette prosjektet?", + "OK": "Unarkiv" + }, + "EDIT_PROJECT": "Rediger prosjekt", + "EXPORT_PROJECT": "Eksporter prosjekt", + "GITHUB_CONFIGURED": "Github-integrasjon konfigurert", + "GITLAB_CONFIGURED": "Gitlab-integrasjon konfigurert", + "IMPORT_FROM_FILE": "Importer fra fil", + "JIRA_CONFIGURED": "Jira Integration konfigurert", + "S_INVALID_JSON": "Ugyldig json for prosjektfilen", + "TITLE": "Prosjektoversikt", + "UN_ARCHIVE_PROJECT": "Unarchive Project" + }, + "PS": { + "GLOBAL_SETTINGS": "Globale innstillinger", + "ISSUE_INTEGRATION": "Problem integrering", + "PRIVATE_POLICY": "Privat policy", + "PRODUCTIVITY_HELPER": "Produktivitetshjelper", + "PROJECT_SETTINGS": "Prosjektspesifikke innstillinger", + "SYNC_EXPORT": "Synkroniser og eksporter", + "TAG_SETTINGS": "Merk spesifikke innstillinger", + "TOGGLE_DARK_MODE": "Bytt mørk modus" + }, + "S": { + "SYNC": { + "ERROR_FALLBACK_TO_BACKUP": "Noe gikk galt under dataimporten. Faller tilbake til lokal sikkerhetskopi.", + "ERROR_INVALID_DATA": "Feil under synkronisering. Ugyldig data", + "IMPORTING": "Importerer data", + "SUCCESS": "Data importert" + } + }, + "SCHEDULE": { + "NO_SCHEDULED": "Det er for øyeblikket ingen planlagte oppgaver. Du kan planlegge en oppgave ved å velge \"Planlegg oppgave\" i oppgavens kontekstmeny. For å åpne den, klikk på de tre små prikkene til høyre for en oppgave.", + "START_TASK": "Start oppgaven og fjern påminnelsen" + }, + "THEMES": { + "SELECT_THEME": "Velg Tema", + "amber": "rav", + "blue": "blå", + "blue-grey": "blågrå", + "cyan": "turkis", + "deep-orange": "dyp oransje", + "deep-purple": "mørk lilla", + "green": "grønn", + "indigo": "indigo", + "light-blue": "lyseblå", + "light-green": "lysegrønn", + "lime": "kalk", + "pink": "rosa", + "purple": "lilla", + "teal": "blågrønn", + "yellow": "gul" + }, + "V": { + "E_1TO10": "Angi en verdi mellom 1 og 10", + "E_DATETIME": "Den angitte verdien er ikke en datotid!", + "E_MAX": "Bør ikke være større enn {{val}}", + "E_MAX_LENGTH": "Bør være maks {{val}} tegn lang", + "E_MIN": "Bør være mindre enn {{val}}", + "E_MIN_LENGTH": "Bør ha minst {{val}} tegn", + "E_PATTERN": "Ugyldig inndata", + "E_REQUIRED": "Dette feltet er obligatorisk" + }, + "WW": { + "ADD_MORE": "Legg til mer", + "ADD_SOME_TASKS": "Legg til noen oppgaver for å planlegge dagen din!", + "COMPLETED_TASKS": "Fullførte oppgaver", + "ESTIMATE_REMAINING": "Anslått gjenværende:", + "FINISH_DAY": "Avslutt dagen", + "HELP_PROCRASTINATION": "Hjelp jeg utsetter!", + "NO_COMPLETED_TASKS": "Det er for tiden ingen fullførte oppgaver", + "NO_PLANNED_TASKS": "Ingen planlagte oppgaver", + "READY_TO_WORK": "Klar til å arbeide!", + "RESET_BREAK_TIMER": "Tilbakestill uten pausetimer", + "TIME_ESTIMATED": "Anslått tid:", + "WITHOUT_BREAK": "Uten pause:", + "WORKING_TODAY": "Jobber i dag:" + } +} diff --git a/src/assets/i18n/nl.json b/src/assets/i18n/nl.json index 93c557b08..6a7639bb0 100644 --- a/src/assets/i18n/nl.json +++ b/src/assets/i18n/nl.json @@ -922,6 +922,7 @@ "JA": "Japans", "KO": "Koreaans", "LABEL": "Selecteer een taal", + "NB": "Noors Bokmål", "NL": "Nederlands", "PT": "Portugees", "RU": "Russisch", diff --git a/src/assets/i18n/pt.json b/src/assets/i18n/pt.json index a0a08cb3d..5a5c2f544 100644 --- a/src/assets/i18n/pt.json +++ b/src/assets/i18n/pt.json @@ -922,6 +922,7 @@ "JA": "Japanese", "KO": "Korean", "LABEL": "Please select a language", + "NB": "Bokmål norueguês", "NL": "Holandês", "PT": "português", "RU": "Russian", diff --git a/src/assets/i18n/ru.json b/src/assets/i18n/ru.json index fc6daa14a..d087a19bd 100644 --- a/src/assets/i18n/ru.json +++ b/src/assets/i18n/ru.json @@ -922,6 +922,7 @@ "JA": "Японский", "KO": "Корейский", "LABEL": "Пожалуйста, выберите язык", + "NB": "Норвежский букмол", "NL": "голландский", "PT": "португальский", "RU": "Русский", diff --git a/src/assets/i18n/tr.json b/src/assets/i18n/tr.json index 23e9f6ef0..54eaef260 100644 --- a/src/assets/i18n/tr.json +++ b/src/assets/i18n/tr.json @@ -922,6 +922,7 @@ "JA": "Japonca", "KO": "Koreli", "LABEL": "Lütfen bir dil seçin", + "NB": "Norveççe Bokmål", "NL": "Flemenkçe", "PT": "Portekizce", "RU": "Rusça", diff --git a/src/assets/i18n/zh.json b/src/assets/i18n/zh.json index 0b83f463a..136af0523 100644 --- a/src/assets/i18n/zh.json +++ b/src/assets/i18n/zh.json @@ -922,6 +922,7 @@ "JA": "日本语", "KO": "朝鲜语", "LABEL": "请选择一种语言", + "NB": "挪威语 Bokmål", "NL": "荷兰语", "PT": "葡萄牙语", "RU": "俄语", From a512c94584ddaa529d0a0a198fc8d9e7a58fc98d Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Wed, 7 Oct 2020 19:58:49 +0200 Subject: [PATCH 107/131] feat(i18n): add norwegian --- src/app/app.constants.ts | 2 ++ .../features/config/form-cfgs/language-selection-form.const.ts | 1 + src/app/t.const.ts | 1 + 3 files changed, 4 insertions(+) diff --git a/src/app/app.constants.ts b/src/app/app.constants.ts index 12236dba1..99208be2c 100644 --- a/src/app/app.constants.ts +++ b/src/app/app.constants.ts @@ -52,6 +52,7 @@ export enum LanguageCode { it = 'it', pt = 'pt', nl = 'nl', + nb = 'nb', } export enum LanguageCodeMomentMap { @@ -68,6 +69,7 @@ export enum LanguageCodeMomentMap { it = 'it', pt = 'pt', nl = 'nl', + nb = 'nb', zh = 'zh-cn', } diff --git a/src/app/features/config/form-cfgs/language-selection-form.const.ts b/src/app/features/config/form-cfgs/language-selection-form.const.ts index 55d0449d3..6f55f6b33 100644 --- a/src/app/features/config/form-cfgs/language-selection-form.const.ts +++ b/src/app/features/config/form-cfgs/language-selection-form.const.ts @@ -27,6 +27,7 @@ export const LANGUAGE_SELECTION_FORM_FORM: ConfigFormSection = { {label: T.GCF.LANG.IT, value: LanguageCode.it}, {label: T.GCF.LANG.PT, value: LanguageCode.pt}, {label: T.GCF.LANG.NL, value: LanguageCode.nl}, + {label: T.GCF.LANG.NB, value: LanguageCode.nb}, ], }, }, diff --git a/src/app/t.const.ts b/src/app/t.const.ts index d1af8525d..d9134154e 100644 --- a/src/app/t.const.ts +++ b/src/app/t.const.ts @@ -939,6 +939,7 @@ export const T = { 'JA': 'GCF.LANG.JA', 'KO': 'GCF.LANG.KO', 'LABEL': 'GCF.LANG.LABEL', + 'NB': 'GCF.LANG.NB', 'NL': 'GCF.LANG.NL', 'PT': 'GCF.LANG.PT', 'RU': 'GCF.LANG.RU', From f1183787e6f8e591265e3c37b666f89e1395c594 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 11:39:33 +0200 Subject: [PATCH 108/131] build: update product name --- build/electron-builder.mas-dev.yaml | 1 + build/electron-builder.mas.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/build/electron-builder.mas-dev.yaml b/build/electron-builder.mas-dev.yaml index 73b919a7e..1f1cd4d14 100644 --- a/build/electron-builder.mas-dev.yaml +++ b/build/electron-builder.mas-dev.yaml @@ -1,4 +1,5 @@ appId: com.super-productivity.app +productName: Super Productivity files: - electron/**/* - "!electron/**/*.ts" diff --git a/build/electron-builder.mas.yaml b/build/electron-builder.mas.yaml index f455142d7..3d4055526 100644 --- a/build/electron-builder.mas.yaml +++ b/build/electron-builder.mas.yaml @@ -1,5 +1,6 @@ appId: com.super-productivity.app afterSign: electron-builder-notarize +productName: Super Productivity files: - electron/**/* - "!electron/**/*.ts" From 251ee8d13a7655b3061d09f7d59cfda064d94d59 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 11:59:53 +0200 Subject: [PATCH 109/131] build: update product name for standard mac too --- electron-builder.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/electron-builder.yaml b/electron-builder.yaml index d6a92692b..c5e43c6c1 100644 --- a/electron-builder.yaml +++ b/electron-builder.yaml @@ -34,6 +34,7 @@ snap: mac: appId: com.super-productivity.app + productName: Super Productivity type: distribution category: public.app-category.productivity entitlements: build/entitlements.mac.plist From 340b996f788c019ee83d92bd66bd4a05ad8da926 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 12:00:09 +0200 Subject: [PATCH 110/131] build: update mac localInstall --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f105b22bf..399c2ed4f 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "localInstall": "sudo echo 'Starting local install' && rm -Rf ./dist/ && rm -Rf ./app-builds/ && yarn buildAllElectron:stage && electron-builder --linux deb && sudo dpkg -i app-builds/superProductivity*.deb", "localInstall:prod": "sudo echo 'Starting local install' && rm -Rf ./dist/ && rm -Rf ./app-builds/ && yarn buildAllElectron:prod && electron-builder --linux deb && sudo dpkg -i app-builds/superProductivity*.deb", "localInstall:quick": "sudo echo 'Starting local install' && rm -Rf ./dist/ && rm -Rf ./app-builds/ && yarn buildFrontend:stage && yarn electron:build && electron-builder --linux deb && sudo dpkg -i app-builds/superProductivity*.deb", - "localInstall:mac": "sudo echo 'Starting local install. Don`t forget APPLEID & APPLEIDPASS !!' && yarn buildAllElectron:prod && sudo echo '' && electron-builder && sudo cp -rf app-builds/mac/superProductivity.app/ /Applications/superProductivity.app", + "localInstall:mac": "sudo echo 'Starting local install. Don`t forget APPLEID & APPLEIDPASS !!' && yarn buildAllElectron:noTests:prod && sudo echo '' && electron-builder && sudo cp -rf app-builds/mac/Super\\ Productivity.app/ /Applications/superProductivity.app", "dist": "yarn buildAllElectron:prod && electron-builder", "dist:only": "electron-builder", "dist:linuxAndWin": "yarn buildAllElectron:prod && electron-builder --linux --win", From 01ef0495bae230f5ccba89526730cdf289e2abe7 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 12:00:23 +0200 Subject: [PATCH 111/131] 5.9.11 --- CHANGELOG.md | 19 +++++++++++++++++++ package.json | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64b863397..a99afd723 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## [5.9.11](https://github.com/johannesjo/super-productivity/compare/v5.9.10...v5.9.11) (2020-10-08) + + +### Bug Fixes + +* not in project context [#545](https://github.com/johannesjo/super-productivity/issues/545) ([a293f2f](https://github.com/johannesjo/super-productivity/commit/a293f2f736d7a61d87cc792b669864b7c2f5c5e8)) + + +### Features + +* **autoBackupRestore:** add translations [#553](https://github.com/johannesjo/super-productivity/issues/553) ([cfeed8d](https://github.com/johannesjo/super-productivity/commit/cfeed8de1048c26e69b65ec1b7689a9f8eebb720)) +* **autoBackupRestore:** implement most basic variant – circular dependency [#553](https://github.com/johannesjo/super-productivity/issues/553) ([bdd3cbc](https://github.com/johannesjo/super-productivity/commit/bdd3cbc49649a6e8d6e7dee613932d9fd4dbe688)) +* **autoBackupRestore:** make it work [#553](https://github.com/johannesjo/super-productivity/issues/553) ([a54711d](https://github.com/johannesjo/super-productivity/commit/a54711d9651d19a0f15b66f0e2f6b4d97f7a3e83)) +* **autoBackupRestore:** outline [#553](https://github.com/johannesjo/super-productivity/issues/553) ([7d00652](https://github.com/johannesjo/super-productivity/commit/7d00652eb9212a80b4a48c487f91623a41fdd11d)) +* **i18n:** add norwegian ([a512c94](https://github.com/johannesjo/super-productivity/commit/a512c94584ddaa529d0a0a198fc8d9e7a58fc98d)) +* **task:** make startable tasks work better ([ada4c97](https://github.com/johannesjo/super-productivity/commit/ada4c97db9fb7075419f43d845b4e33606dbeba2)) + + + ## [5.9.10](https://github.com/johannesjo/super-productivity/compare/v5.9.2...v5.9.10) (2020-10-04) diff --git a/package.json b/package.json index 399c2ed4f..204f4d39b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.10", + "version": "5.9.11", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "johannesjo (http://super-productivity.com)", From 1ab13486193a0c7e8d9e73b3c421550e6da91f9b Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 12:01:50 +0200 Subject: [PATCH 112/131] build: add correct author name --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 204f4d39b..b5ebe02ac 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "5.9.11", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", - "author": "johannesjo (http://super-productivity.com)", + "author": "Johannes Millan (http://super-productivity.com)", "license": "MIT", "homepage": "http://super-productivity.com", "repository": { From d2a5c2027c5e5a6e5d6ebbd56c38562e58c624ac Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 12:02:07 +0200 Subject: [PATCH 113/131] 5.9.12 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a99afd723..a1fed2158 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [5.9.12](https://github.com/johannesjo/super-productivity/compare/v5.9.11...v5.9.12) (2020-10-08) + + + ## [5.9.11](https://github.com/johannesjo/super-productivity/compare/v5.9.10...v5.9.11) (2020-10-08) diff --git a/package.json b/package.json index b5ebe02ac..dc500e477 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.11", + "version": "5.9.12", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "Johannes Millan (http://super-productivity.com)", From 857a7025646559debfd07eb5e5d904eaec5eaa15 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 13:21:58 +0200 Subject: [PATCH 114/131] build: remove productName again for mas --- electron-builder.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/electron-builder.yaml b/electron-builder.yaml index c5e43c6c1..d6a92692b 100644 --- a/electron-builder.yaml +++ b/electron-builder.yaml @@ -34,7 +34,6 @@ snap: mac: appId: com.super-productivity.app - productName: Super Productivity type: distribution category: public.app-category.productivity entitlements: build/entitlements.mac.plist From 4762d9a865f30b3ee1aaa4bfeb5b8b67732799c7 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 13:22:06 +0200 Subject: [PATCH 115/131] 5.9.13 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1fed2158..24cda803c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [5.9.13](https://github.com/johannesjo/super-productivity/compare/v5.9.12...v5.9.13) (2020-10-08) + + + ## [5.9.12](https://github.com/johannesjo/super-productivity/compare/v5.9.11...v5.9.12) (2020-10-08) diff --git a/package.json b/package.json index dc500e477..774991df7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.12", + "version": "5.9.13", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "Johannes Millan (http://super-productivity.com)", From adf6b665862f61059f39d793379f6c78aa943bd0 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 14:51:27 +0200 Subject: [PATCH 116/131] build: fix mac deploy script --- .github/workflows/build-publish-to-mac-store-on-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-publish-to-mac-store-on-release.yml b/.github/workflows/build-publish-to-mac-store-on-release.yml index 2715af230..9b6ed239e 100644 --- a/.github/workflows/build-publish-to-mac-store-on-release.yml +++ b/.github/workflows/build-publish-to-mac-store-on-release.yml @@ -50,13 +50,13 @@ jobs: run: yarn dist:mac:mas:buildOnly - name: Validate App - run: xcrun altool --validate-app -f app-builds/mas/superProductivity-*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} + run: xcrun altool --validate-app -f app-builds/mac/Super*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} env: APPLEID: ${{secrets.APPLEID}} APPLEIDPASS: ${{secrets.APPLEIDPASS}} - name: Push to Store - run: xcrun altool --upload-app -f app-builds/mas/superProductivity-*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} + run: xcrun altool --upload-app -f app-builds/mac/Super*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} env: APPLEID: ${{secrets.APPLEID}} APPLEIDPASS: ${{secrets.APPLEIDPASS}} From d263a46932665c8427c6401917fb366edd7bb391 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 15:06:37 +0200 Subject: [PATCH 117/131] build: fix mac deploy script 2 --- .github/workflows/build-publish-to-mac-store-on-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-publish-to-mac-store-on-release.yml b/.github/workflows/build-publish-to-mac-store-on-release.yml index 9b6ed239e..56118d85b 100644 --- a/.github/workflows/build-publish-to-mac-store-on-release.yml +++ b/.github/workflows/build-publish-to-mac-store-on-release.yml @@ -50,13 +50,13 @@ jobs: run: yarn dist:mac:mas:buildOnly - name: Validate App - run: xcrun altool --validate-app -f app-builds/mac/Super*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} + run: ls app-builds; ls app-build/mas; && xcrun altool --validate-app -f app-builds/mas/Super*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} env: APPLEID: ${{secrets.APPLEID}} APPLEIDPASS: ${{secrets.APPLEIDPASS}} - name: Push to Store - run: xcrun altool --upload-app -f app-builds/mac/Super*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} + run: xcrun altool --upload-app -f app-builds/mas/Super*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} env: APPLEID: ${{secrets.APPLEID}} APPLEIDPASS: ${{secrets.APPLEIDPASS}} From 4f620a2b943020092eb264d1044ebb6012744c6e Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 15:16:21 +0200 Subject: [PATCH 118/131] build: fix syntax error in mac deploy script --- .github/workflows/build-publish-to-mac-store-on-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-publish-to-mac-store-on-release.yml b/.github/workflows/build-publish-to-mac-store-on-release.yml index 56118d85b..7ac56f2eb 100644 --- a/.github/workflows/build-publish-to-mac-store-on-release.yml +++ b/.github/workflows/build-publish-to-mac-store-on-release.yml @@ -50,7 +50,7 @@ jobs: run: yarn dist:mac:mas:buildOnly - name: Validate App - run: ls app-builds; ls app-build/mas; && xcrun altool --validate-app -f app-builds/mas/Super*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} + run: ls app-builds; ls app-build/mas; xcrun altool --validate-app -f app-builds/mas/Super*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} env: APPLEID: ${{secrets.APPLEID}} APPLEIDPASS: ${{secrets.APPLEIDPASS}} From 47c90700d16d7dfbb5b42175d91a05d7dd046ae7 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 15:39:57 +0200 Subject: [PATCH 119/131] build: fix syntax error in mac deploy script --- .github/workflows/build-publish-to-mac-store-on-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-publish-to-mac-store-on-release.yml b/.github/workflows/build-publish-to-mac-store-on-release.yml index 7ac56f2eb..ea7269bce 100644 --- a/.github/workflows/build-publish-to-mac-store-on-release.yml +++ b/.github/workflows/build-publish-to-mac-store-on-release.yml @@ -50,7 +50,7 @@ jobs: run: yarn dist:mac:mas:buildOnly - name: Validate App - run: ls app-builds; ls app-build/mas; xcrun altool --validate-app -f app-builds/mas/Super*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} + run: ls app-builds; ls app-builds/mas; xcrun altool --validate-app -f app-builds/mas/Super*.pkg -u ${{secrets.APPLEID}} -p ${{secrets.APPLEIDPASS}} env: APPLEID: ${{secrets.APPLEID}} APPLEIDPASS: ${{secrets.APPLEIDPASS}} From 1dbb0d264aa8531802d061324e23ff7f011cd8eb Mon Sep 17 00:00:00 2001 From: Bruno Eduardo de Souza Medeiros Date: Thu, 8 Oct 2020 13:49:41 -0300 Subject: [PATCH 120/131] Improve portuguese translation --- src/assets/i18n/pt.json | 82 ++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/src/assets/i18n/pt.json b/src/assets/i18n/pt.json index 5a5c2f544..eff725664 100644 --- a/src/assets/i18n/pt.json +++ b/src/assets/i18n/pt.json @@ -5,12 +5,12 @@ "INSTALL": "Instalar", "MSG": "Deseja instalar Super Productivity como PWA?" }, - "B_OFFLINE": "Você está desconectado da internet. Sincronizar e solicitar dados do provedor de problemas não funcionará.", + "B_OFFLINE": "Você está desconectado da internet. A sincronização e solicitação de dados do provedor de problemas não funcionará.", "D_INITIAL": { "TITLE": "Bem-vindo à v{{nr}}" }, - "UPDATE_MAIN_MODEL": "Super Produtividade recebeu uma grande atualização! Algumas migrações para seus dados são necessárias. Observe que isso torna seus dados incompatíveis com versões mais antigas do aplicativo.", - "UPDATE_MAIN_MODEL_NO_UPDATE": "Nenhuma atualização de modelo escolhida. Observe que você deve fazer o downgrade para a última versão, se não desejar executar a atualização do modelo.", + "UPDATE_MAIN_MODEL": "Super Productivity recebeu uma grande atualização! Algumas migrações para seus dados são necessárias. Observe que isso torna seus dados incompatíveis com versões mais antigas do aplicativo.", + "UPDATE_MAIN_MODEL_NO_UPDATE": "Nenhuma atualização de modelo escolhida. Note que você deve fazer o downgrade para a última versão, se não desejar executar a atualização do modelo.", "UPDATE_WEB_APP": "Nova versão disponível. Carregar nova versão?" }, "BL": { @@ -61,7 +61,7 @@ "IMG": "Imagem", "LINK": "Url" }, - "SELECT_ICON": "Selecione um icone", + "SELECT_ICON": "Selecione um ícone", "SELECT_TYPE": "Selecione um tipo", "TYPES": { "COMMAND": "Comando (Comando shell personalizado)", @@ -86,14 +86,14 @@ }, "D_CONFLICT": { "LAST_CHANGE": "última mudança:", - "LAST_SYNC": "última sincronização:", + "LAST_SYNC": "Última sincronização:", "LOCAL": "Local", "LOCAL_REMOTE": "local -> remoto", - "REMOTE": "Controlo remoto", + "REMOTE": "remoto", "TEXT": "

Atualização do Dropbox. Os dados locais e remotos parecem ter sido modificados.

", "TITLE": "Dropbox: dados conflitantes", - "USE_LOCAL": "Use local", - "USE_REMOTE": "Usar controle remoto" + "USE_LOCAL": "Usar local", + "USE_REMOTE": "Usar remoto" }, "FORM": { "B_GENERATE_TOKEN": "Gerar token", @@ -119,8 +119,8 @@ }, "FORM": { "FILTER_USER": "Nome de usuário (ex.: para filtrar as alterações sozinho)", - "IS_AUTO_ADD_TO_BACKLOG": "Adicionar automáticamente problemas não resolvidos do Github para o backlog", - "IS_AUTO_POLL": "Obter automáticamente issues do Github para alterações", + "IS_AUTO_ADD_TO_BACKLOG": "Adicionar automaticamente problemas não resolvidos do Github para o backlog", + "IS_AUTO_POLL": "Obter automaticamente issues do Github para alterações", "IS_SEARCH_ISSUES_FROM_GITHUB": "Mostrar issues do Github como sugestões qando adicionar novas tarefas", "REPO": "\"username/repositoryName\" para o repositório git que você deseja rastrear", "TOKEN": "Token de acesso" @@ -131,12 +131,12 @@ }, "ISSUE_CONTENT": { "ASSIGNEE": "Responsável", - "AT": "at", + "AT": "em", "DESCRIPTION": "Descrição", "LABELS": "Etiquetas", "MARK_AS_CHECKED": "Marcar atualizações como checadas", "STATUS": "Status", - "SUMMARY": "Indíce", + "SUMMARY": "Índice", "WRITE_A_COMMENT": "Comentar" }, "S": { @@ -161,8 +161,8 @@ }, "FORM": { "FILTER_USER": "Nome de usuário (ex.: para filtrar as alterações sozinho)", - "IS_AUTO_ADD_TO_BACKLOG": "Adicionar automáticamente problemas não resolvidos do Gitlab para o backlog", - "IS_AUTO_POLL": "Obter automáticamente issues do Gitlab para alterações", + "IS_AUTO_ADD_TO_BACKLOG": "Adicionar automaticamente problemas não resolvidos do Gitlab para o backlog", + "IS_AUTO_POLL": "Obter automaticamente issues do Gitlab para alterações", "IS_SEARCH_ISSUES_FROM_GITLAB": "Mostrar issues do Gitlab como sugestões qando adicionar novas tarefas", "PROJECT": "Caminho completo ou nome de usuário / projeto", "TOKEN": "Token de acesso" @@ -173,7 +173,7 @@ }, "ISSUE_CONTENT": { "ASSIGNEE": "Responsável", - "AT": "at", + "AT": "em", "DESCRIPTION": "Descrição", "LABELS": "Etiquetas", "MARK_AS_CHECKED": "Marcar atualizações como checadas", @@ -212,7 +212,7 @@ "LOCAL_REMOTE": "local <=> remoto", "OVERWRITE_LOCAL": "Substituir local", "OVERWRITE_REMOTE": "Substituir remoto", - "REMOTE": "romoto", + "REMOTE": "remoto", "TEXT": "

Atualização do Google Drive Backup. Os dados locais e remotos parecem ter sido modificados. Deseja sobrescrever alterações locais não salvas? Todos os dados serão perdidos para sempre.

", "TITLE": "Sobrescrever dados locais com a Atualização GDrive?" }, @@ -260,7 +260,7 @@ }, "JIRA": { "BANNER": { - "BLOCK_ACCESS_MSG": "Jira: A fim de impedir o desligamento da API, o acesso foi bloqueado pela Super Produtividade. Você provavelmente deve verificar suas configurações do jira!", + "BLOCK_ACCESS_MSG": "Jira: A fim de impedir o desligamento da API, o acesso foi bloqueado pelo Super Productivity. Você provavelmente deve verificar suas configurações do jira!", "BLOCK_ACCESS_UNBLOCK": "Desbloquear" }, "CFG_CMP": { @@ -301,7 +301,7 @@ "TITLE": "Jira: Enviar log de trabalho" }, "FORM": { - "IS_AUTO_ADD_TO_BACKLOG": "Adicionar automáticamente problemas não resolvidos do Github para o backlog", + "IS_AUTO_ADD_TO_BACKLOG": "Adicionar automaticamente problemas não resolvidos do Github para o backlog", "IS_AUTO_POLL": "Pesquisar automaticamente problemas importados do git em busca de alterações", "IS_SEARCH_ISSUES_FROM_GITHUB": "Mostrar issues do Github como sugestões qando adicionar novas tarefas", "REPO": "\"username/repositoryName\" para o repositório git que você deseja rastrear" @@ -341,7 +341,7 @@ }, "ISSUE_CONTENT": { "ASSIGNEE": "Resposável", - "AT": "at", + "AT": "em", "ATTACHMENTS": "Anexos", "CHANGED": "Alterado", "COMMENTS": "Comentarios", @@ -349,7 +349,7 @@ "DESCRIPTION": "Descrição", "LIST_OF_CHANGES": "Lista de mudanças", "MARK_AS_CHECKED": "Marcar atualizações como checadas", - "ON": "on", + "ON": "em", "STATUS": "Status", "STORY_POINTS": "Story Points", "SUMMARY": "Indíce", @@ -463,7 +463,7 @@ "ENJOY_YOURSELF": "Divirta-se, mexa-se, volte em:", "FINISH_SESSION_X": "Você terminou a sessão com sucesso {{nr}}!", "NOTIFICATION": { - "BREAK_X_START": "Pomodoro: Pausa {{nr}} iniciado!", + "BREAK_X_START": "Pomodoro: Pausa {{nr}} iniciada!", "SESSION_X_START": "Pomodoro: Sessão {{nr}} iniciada!" }, "S": { @@ -567,7 +567,7 @@ "L_AUTO_SWITCH_ON": "O gatilho automático é ativado por", "L_ICON": "Ícone", "L_ICON_ON": "Ícone quando alternado", - "L_IS_ENABLED": "ativado", + "L_IS_ENABLED": "Ativado", "L_TITLE": "Título", "L_TYPE": "Tipo", "TITLE": "Contadores simples", @@ -611,7 +611,7 @@ "REPEAT": "Repetir", "SCHEDULE_TASK": "Agendar Tarefa", "SUB_TASKS": "Subtarefas ({{nr}})", - "TIME": "tempo" + "TIME": "Tempo" }, "ADD_TASK_BAR": { "ADD_EXISTING_TASK": "Adicionar tarefa existente \"{{taskTitle}}\"", @@ -912,23 +912,23 @@ "ZOOM_OUT": "Diminuir o zoom (somente para computador)" }, "LANG": { - "AR": "Arabic", - "DE": "German", - "EN": "English", - "ES": "Spanish", + "AR": "Árabe", + "DE": "Alemão", + "EN": "Inglês", + "ES": "Espanhol", "FA": "Persa", - "FR": "French", - "IT": "italiano", - "JA": "Japanese", - "KO": "Korean", - "LABEL": "Please select a language", + "FR": "Francês", + "IT": "Italiano", + "JA": "Japonês", + "KO": "Coreano", + "LABEL": "Por favor escolha um idioma", "NB": "Bokmål norueguês", "NL": "Holandês", - "PT": "português", - "RU": "Russian", - "TITLE": "Language", - "TR": "Turkish", - "ZH": "Chinese" + "PT": "Português", + "RU": "Russo", + "TITLE": "Idioma", + "TR": "Turco", + "ZH": "Chinês" }, "MISC": { "DEFAULT_PROJECT": "Projeto padrão a ser usado para tarefas se nenhum for especificado", @@ -1115,10 +1115,10 @@ "indigo": "índigo", "light-blue": "azul claro", "light-green": "verde claro", - "lime": "Lima", - "pink": "Rosa", + "lime": "lima", + "pink": "rosa", "purple": "roxa", - "teal": "teal", + "teal": "azul petróleo", "yellow": "amarelo" }, "V": { @@ -1141,7 +1141,7 @@ "NO_COMPLETED_TASKS": "No momento, não há tarefas concluídas", "NO_PLANNED_TASKS": "Nenhuma tarefa planejada", "READY_TO_WORK": "Pronto para trabalhar!", - "RESET_BREAK_TIMER": "Reset without break timer", + "RESET_BREAK_TIMER": "Reiniciar sem temporizador de pause", "TIME_ESTIMATED": "Tempo estimado:", "WITHOUT_BREAK": "Sem pausa:", "WORKING_TODAY": "Trabalhando hoje:" From 39508dc2f26f4228b4721d5fcaa255b702585088 Mon Sep 17 00:00:00 2001 From: Ramiellll Date: Thu, 8 Oct 2020 22:17:04 +0200 Subject: [PATCH 121/131] fix: text overlap --- .../config/select-project/select-project.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/features/config/select-project/select-project.component.html b/src/app/features/config/select-project/select-project.component.html index a5a2feb2f..84f514854 100644 --- a/src/app/features/config/select-project/select-project.component.html +++ b/src/app/features/config/select-project/select-project.component.html @@ -4,7 +4,7 @@ [id]="id" [readonly]="to.readonly" matNativeControl> - + From cdc76876bc4508e9f01e20deb63a2719f1374190 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 23:09:07 +0200 Subject: [PATCH 122/131] fix: about for mas... --- electron/main-window.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron/main-window.ts b/electron/main-window.ts index 79e087887..0a2505fdc 100644 --- a/electron/main-window.ts +++ b/electron/main-window.ts @@ -150,7 +150,7 @@ function createMenu(quitApp) { const menuTpl = [{ label: 'Application', submenu: [ - {label: 'About Application', selector: 'orderFrontStandardAboutPanel:'}, + {label: 'About Super Productivity', selector: 'orderFrontStandardAboutPanel:'}, {type: 'separator'}, { label: 'Quit', click: quitApp From 5e65b46020597ccec553859d533446c1fd0e1635 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Thu, 8 Oct 2020 23:10:34 +0200 Subject: [PATCH 123/131] 5.9.14 --- CHANGELOG.md | 9 +++++++++ package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24cda803c..172782c83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [5.9.14](https://github.com/johannesjo/super-productivity/compare/v5.9.13...v5.9.14) (2020-10-08) + + +### Bug Fixes + +* about for mas... ([cdc7687](https://github.com/johannesjo/super-productivity/commit/cdc76876bc4508e9f01e20deb63a2719f1374190)) + + + ## [5.9.13](https://github.com/johannesjo/super-productivity/compare/v5.9.12...v5.9.13) (2020-10-08) diff --git a/package.json b/package.json index 774991df7..cfc841763 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.13", + "version": "5.9.14", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "Johannes Millan (http://super-productivity.com)", From 81f076aefb543b131cfb87e3e8b7696094b14fd2 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 9 Oct 2020 00:20:42 +0200 Subject: [PATCH 124/131] feat: write auto repair for wrongly archived sub tasks --- .../core/data-repair/data-repair.util.spec.ts | 61 +++++++++++++++++++ src/app/core/data-repair/data-repair.util.ts | 39 ++++++++++++ 2 files changed, 100 insertions(+) diff --git a/src/app/core/data-repair/data-repair.util.spec.ts b/src/app/core/data-repair/data-repair.util.spec.ts index 5693d5362..1955477b2 100644 --- a/src/app/core/data-repair/data-repair.util.spec.ts +++ b/src/app/core/data-repair/data-repair.util.spec.ts @@ -404,4 +404,65 @@ describe('dataRepair()', () => { } }); }); + + fit('should move archived sub tasks back to their unarchived parents', () => { + const taskStateBefore = { + ...mock.task, + ...fakeEntityStateFromArray([{ + ...DEFAULT_TASK, + id: 'subTaskUnarchived', + title: 'subTaskUnarchived', + parentId: 'parent', + }, { + ...DEFAULT_TASK, + id: 'parent', + title: 'parent', + parentId: null, + subTaskIds: ['subTaskUnarchived'] + }]) + } as any; + + const taskArchiveStateBefore = { + ...mock.taskArchive, + ...fakeEntityStateFromArray([{ + ...DEFAULT_TASK, + id: 'subTaskArchived', + title: 'subTaskArchived', + parentId: 'parent', + }]) + } as any; + + expect(dataRepair({ + ...mock, + task: taskStateBefore, + taskArchive: taskArchiveStateBefore, + })).toEqual({ + ...mock, + task: { + ...mock.task, + ...fakeEntityStateFromArray([{ + ...DEFAULT_TASK, + id: 'subTaskUnarchived', + title: 'subTaskUnarchived', + parentId: 'parent', + }, { + ...DEFAULT_TASK, + id: 'parent', + title: 'parent', + parentId: null, + subTaskIds: ['subTaskUnarchived', 'subTaskArchived'], + }, { + ...DEFAULT_TASK, + id: 'subTaskArchived', + title: 'subTaskArchived', + parentId: 'parent', + }]) + } as any, + taskArchive: { + ...mock.taskArchive, + ...fakeEntityStateFromArray([]) + } as any, + }); + }); + }); diff --git a/src/app/core/data-repair/data-repair.util.ts b/src/app/core/data-repair/data-repair.util.ts index 2d601f629..a4ad77081 100644 --- a/src/app/core/data-repair/data-repair.util.ts +++ b/src/app/core/data-repair/data-repair.util.ts @@ -2,6 +2,7 @@ import { AppBaseDataEntityLikeStates, AppDataComplete } from '../../imex/sync/sy import { TagCopy } from '../../features/tag/tag.model'; import { ProjectCopy } from '../../features/project/project.model'; import { isDataRepairPossible } from './is-data-repair-possible.util'; +import { Task, TaskArchive, TaskState } from '../../features/tasks/task.model'; const ENTITY_STATE_KEYS: (keyof AppDataComplete)[] = ['task', 'taskArchive', 'taskRepeatCfg', 'tag', 'project', 'simpleCounter']; @@ -17,6 +18,7 @@ export const dataRepair = (data: AppDataComplete): AppDataComplete => { dataOut = _removeMissingTasksFromListsOrRestoreFromArchive(dataOut); dataOut = _removeDuplicatesFromArchive(dataOut); dataOut = _addOrphanedTasksToProjectLists(dataOut); + dataOut = _moveArchivedSubTasksToUnarchivedParents(dataOut); // console.timeEnd('dataRepair'); return dataOut; }; @@ -48,6 +50,43 @@ const _removeDuplicatesFromArchive = (data: AppDataComplete): AppDataComplete => return data; }; +const _moveArchivedSubTasksToUnarchivedParents = (data: AppDataComplete): AppDataComplete => { + // to avoid ambiguity + const taskState: TaskState = data.task; + const taskArchiveState: TaskArchive = data.taskArchive; + const taskArchiveIds = taskArchiveState.ids as string[]; + const orhphanedArchivedSubTasks: Task[] = taskArchiveIds + .map((id: string) => taskArchiveState.entities[id] as Task) + .filter((t: Task) => t.parentId && !taskArchiveIds.includes(t.parentId)); + + orhphanedArchivedSubTasks.forEach((t: Task) => { + // delete archived if duplicate + if (taskState.ids.includes(t.id as string)) { + taskArchiveState.ids = taskArchiveIds.filter(id => t.id !== id); + delete taskArchiveState.entities[t.id]; + } + // copy to today if parent exists + else if (taskState.ids.includes(t.parentId as string)) { + taskState.ids.push((t.id)); + taskState.entities[t.id] = t; + const par: Task = taskState.entities[t.parentId as string] as Task; + par.subTaskIds.push(t.id); + + // and delete from archive + taskArchiveState.ids = taskArchiveIds.filter(id => t.id !== id); + console.log(taskArchiveIds); + delete taskArchiveState.entities[t.id]; + } + // make main if it doesn't + else { + // @ts-ignore + t.parentId = null; + } + }); + + return data; +}; + const _removeMissingTasksFromListsOrRestoreFromArchive = (data: AppDataComplete): AppDataComplete => { const {task, project, tag, taskArchive} = data; const taskIds: string[] = task.ids; From 609941ddebf83ac4a2040159d8087d75316f0716 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 9 Oct 2020 00:52:35 +0200 Subject: [PATCH 125/131] feat: write auto repair for wrongly unarchived archived sub tasks #568 --- .../core/data-repair/data-repair.util.spec.ts | 62 ++++++++++++++++++- src/app/core/data-repair/data-repair.util.ts | 55 +++++++++++++--- 2 files changed, 108 insertions(+), 9 deletions(-) diff --git a/src/app/core/data-repair/data-repair.util.spec.ts b/src/app/core/data-repair/data-repair.util.spec.ts index 1955477b2..16c5458fa 100644 --- a/src/app/core/data-repair/data-repair.util.spec.ts +++ b/src/app/core/data-repair/data-repair.util.spec.ts @@ -405,7 +405,7 @@ describe('dataRepair()', () => { }); }); - fit('should move archived sub tasks back to their unarchived parents', () => { + it('should move archived sub tasks back to their unarchived parents', () => { const taskStateBefore = { ...mock.task, ...fakeEntityStateFromArray([{ @@ -465,4 +465,64 @@ describe('dataRepair()', () => { }); }); + it('should move unarchived sub tasks to their archived parents', () => { + const taskStateBefore = { + ...mock.task, + ...fakeEntityStateFromArray([{ + ...DEFAULT_TASK, + id: 'subTaskUnarchived', + title: 'subTaskUnarchived', + parentId: 'parent', + }]) + } as any; + + const taskArchiveStateBefore = { + ...mock.taskArchive, + ...fakeEntityStateFromArray([{ + ...DEFAULT_TASK, + id: 'subTaskArchived', + title: 'subTaskArchived', + parentId: 'parent', + }, { + ...DEFAULT_TASK, + id: 'parent', + title: 'parent', + parentId: null, + subTaskIds: ['subTaskArchived'] + }]) + } as any; + + expect(dataRepair({ + ...mock, + task: taskStateBefore, + taskArchive: taskArchiveStateBefore, + })).toEqual({ + ...mock, + task: { + ...mock.task, + ...fakeEntityStateFromArray([]) + } as any, + taskArchive: { + ...mock.taskArchive, + ...fakeEntityStateFromArray([{ + ...DEFAULT_TASK, + id: 'subTaskArchived', + title: 'subTaskArchived', + parentId: 'parent', + }, { + ...DEFAULT_TASK, + id: 'parent', + title: 'parent', + parentId: null, + subTaskIds: ['subTaskArchived', 'subTaskUnarchived'] + }, { + ...DEFAULT_TASK, + id: 'subTaskUnarchived', + title: 'subTaskUnarchived', + parentId: 'parent', + }]) + } as any, + }); + }); + }); diff --git a/src/app/core/data-repair/data-repair.util.ts b/src/app/core/data-repair/data-repair.util.ts index a4ad77081..b5102d119 100644 --- a/src/app/core/data-repair/data-repair.util.ts +++ b/src/app/core/data-repair/data-repair.util.ts @@ -2,7 +2,8 @@ import { AppBaseDataEntityLikeStates, AppDataComplete } from '../../imex/sync/sy import { TagCopy } from '../../features/tag/tag.model'; import { ProjectCopy } from '../../features/project/project.model'; import { isDataRepairPossible } from './is-data-repair-possible.util'; -import { Task, TaskArchive, TaskState } from '../../features/tasks/task.model'; +import { TaskArchive, TaskCopy, TaskState } from '../../features/tasks/task.model'; +import { unique } from '../../util/unique'; const ENTITY_STATE_KEYS: (keyof AppDataComplete)[] = ['task', 'taskArchive', 'taskRepeatCfg', 'tag', 'project', 'simpleCounter']; @@ -19,6 +20,7 @@ export const dataRepair = (data: AppDataComplete): AppDataComplete => { dataOut = _removeDuplicatesFromArchive(dataOut); dataOut = _addOrphanedTasksToProjectLists(dataOut); dataOut = _moveArchivedSubTasksToUnarchivedParents(dataOut); + dataOut = _moveUnArchivedSubTasksToArchivedParents(dataOut); // console.timeEnd('dataRepair'); return dataOut; }; @@ -55,11 +57,11 @@ const _moveArchivedSubTasksToUnarchivedParents = (data: AppDataComplete): AppDat const taskState: TaskState = data.task; const taskArchiveState: TaskArchive = data.taskArchive; const taskArchiveIds = taskArchiveState.ids as string[]; - const orhphanedArchivedSubTasks: Task[] = taskArchiveIds - .map((id: string) => taskArchiveState.entities[id] as Task) - .filter((t: Task) => t.parentId && !taskArchiveIds.includes(t.parentId)); + const orhphanedArchivedSubTasks: TaskCopy[] = taskArchiveIds + .map((id: string) => taskArchiveState.entities[id] as TaskCopy) + .filter((t: TaskCopy) => t.parentId && !taskArchiveIds.includes(t.parentId)); - orhphanedArchivedSubTasks.forEach((t: Task) => { + orhphanedArchivedSubTasks.forEach((t: TaskCopy) => { // delete archived if duplicate if (taskState.ids.includes(t.id as string)) { taskArchiveState.ids = taskArchiveIds.filter(id => t.id !== id); @@ -69,12 +71,12 @@ const _moveArchivedSubTasksToUnarchivedParents = (data: AppDataComplete): AppDat else if (taskState.ids.includes(t.parentId as string)) { taskState.ids.push((t.id)); taskState.entities[t.id] = t; - const par: Task = taskState.entities[t.parentId as string] as Task; - par.subTaskIds.push(t.id); + const par: TaskCopy = taskState.entities[t.parentId as string] as TaskCopy; + + par.subTaskIds = unique([...par.subTaskIds, t.id]); // and delete from archive taskArchiveState.ids = taskArchiveIds.filter(id => t.id !== id); - console.log(taskArchiveIds); delete taskArchiveState.entities[t.id]; } // make main if it doesn't @@ -87,6 +89,43 @@ const _moveArchivedSubTasksToUnarchivedParents = (data: AppDataComplete): AppDat return data; }; +const _moveUnArchivedSubTasksToArchivedParents = (data: AppDataComplete): AppDataComplete => { + // to avoid ambiguity + const taskState: TaskState = data.task; + const taskArchiveState: TaskArchive = data.taskArchive; + const taskArchiveIds = taskArchiveState.ids as string[]; + const orhphanedUnArchivedSubTasks: TaskCopy[] = taskState.ids + .map((id: string) => taskState.entities[id] as TaskCopy) + .filter((t: TaskCopy) => t.parentId && !taskState.ids.includes(t.parentId)); + + orhphanedUnArchivedSubTasks.forEach((t: TaskCopy) => { + // delete un-archived if duplicate + if (taskArchiveIds.includes(t.id as string)) { + taskState.ids = taskState.ids.filter(id => t.id !== id); + delete taskState.entities[t.id]; + } + // copy to archive if parent exists + else if (taskArchiveIds.includes(t.parentId as string)) { + taskArchiveIds.push((t.id)); + taskArchiveState.entities[t.id] = t; + + const par: TaskCopy = taskArchiveState.entities[t.parentId as string] as TaskCopy; + par.subTaskIds = unique([...par.subTaskIds, t.id]); + + // and delete from today + taskState.ids = taskState.ids.filter(id => t.id !== id); + delete taskState.entities[t.id]; + } + // make main if it doesn't + else { + // @ts-ignore + t.parentId = null; + } + }); + + return data; +}; + const _removeMissingTasksFromListsOrRestoreFromArchive = (data: AppDataComplete): AppDataComplete => { const {task, project, tag, taskArchive} = data; const taskIds: string[] = task.ids; From 786235b9e5ed936adf43aac7f8d9a995fb3cb558 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 9 Oct 2020 01:11:53 +0200 Subject: [PATCH 126/131] fix: throw error for inconsistent sub task data #568 --- .../core/data-repair/data-repair.util.spec.ts | 2 +- src/app/features/tasks/task.model.ts | 1 + .../imex/sync/is-valid-app-data.util.spec.ts | 70 +++++++++++++++++++ src/app/imex/sync/is-valid-app-data.util.ts | 26 ++++++- 4 files changed, 97 insertions(+), 2 deletions(-) diff --git a/src/app/core/data-repair/data-repair.util.spec.ts b/src/app/core/data-repair/data-repair.util.spec.ts index 16c5458fa..94488bba2 100644 --- a/src/app/core/data-repair/data-repair.util.spec.ts +++ b/src/app/core/data-repair/data-repair.util.spec.ts @@ -31,7 +31,7 @@ describe('dataRepair()', () => { id: 'TEST', title: 'TEST', }]), - })).toEqual({ + } as any)).toEqual({ ...mock, task: taskState, taskArchive: { diff --git a/src/app/features/tasks/task.model.ts b/src/app/features/tasks/task.model.ts index fc53bb9c2..b72518876 100644 --- a/src/app/features/tasks/task.model.ts +++ b/src/app/features/tasks/task.model.ts @@ -22,6 +22,7 @@ export interface TimeSpentOnDayCopy { } export interface TaskArchive extends EntityState { + ids: string[]; // additional entities state properties [MODEL_VERSION_KEY]?: number; } diff --git a/src/app/imex/sync/is-valid-app-data.util.spec.ts b/src/app/imex/sync/is-valid-app-data.util.spec.ts index d8ce0677c..7e08eada5 100644 --- a/src/app/imex/sync/is-valid-app-data.util.spec.ts +++ b/src/app/imex/sync/is-valid-app-data.util.spec.ts @@ -119,6 +119,76 @@ describe('isValidAppData()', () => { })).toThrowError(`Inconsistent Task State: Missing task id goneTag for Project/Tag TEST_TAG`); }); + it('orphaned archived sub tasks', () => { + const taskState = { + ...mock.task, + ...fakeEntityStateFromArray([{ + ...DEFAULT_TASK, + id: 'subTaskUnarchived', + title: 'subTaskUnarchived', + parentId: 'parent', + }, { + ...DEFAULT_TASK, + id: 'parent', + title: 'parent', + parentId: null, + subTaskIds: ['subTaskUnarchived'] + }]) + } as any; + + const taskArchiveState = { + ...mock.taskArchive, + ...fakeEntityStateFromArray([{ + ...DEFAULT_TASK, + id: 'subTaskArchived', + title: 'subTaskArchived', + parentId: 'parent', + }]) + } as any; + + expect(() => isValidAppData({ + ...mock, + // NOTE: it's empty + task: taskState, + taskArchive: taskArchiveState, + })).toThrowError(`Inconsistent Task State: Lonely Sub Task in Archive`); + }); + + it('orphaned today sub tasks', () => { + const taskState = { + ...mock.task, + ...fakeEntityStateFromArray([{ + ...DEFAULT_TASK, + id: 'subTaskUnarchived', + title: 'subTaskUnarchived', + parentId: 'parent', + }]) + } as any; + + const taskArchiveState = { + ...mock.taskArchive, + ...fakeEntityStateFromArray([{ + ...DEFAULT_TASK, + id: 'subTaskArchived', + title: 'subTaskArchived', + parentId: 'parent', + }, { + ...DEFAULT_TASK, + id: 'parent', + title: 'parent', + parentId: null, + subTaskIds: ['subTaskArchived'] + }]) + } as any; + + expect(() => isValidAppData({ + ...mock, + // NOTE: it's empty + task: taskState, + taskArchive: taskArchiveState, + })).toThrowError(`Inconsistent Task State: Lonely Sub Task in Today`); + }); + xit('missing tag for task', () => { expect(() => isValidAppData({ ...mock, diff --git a/src/app/imex/sync/is-valid-app-data.util.ts b/src/app/imex/sync/is-valid-app-data.util.ts index 89e544d33..ec063a3c6 100644 --- a/src/app/imex/sync/is-valid-app-data.util.ts +++ b/src/app/imex/sync/is-valid-app-data.util.ts @@ -4,6 +4,7 @@ import { isEntityStateConsistent } from '../../util/check-fix-entity-state-consi import { devError } from '../../util/dev-error'; import { Tag } from '../../features/tag/tag.model'; import { Project } from '../../features/project/project.model'; +import { Task } from '../../features/tasks/task.model'; export const isValidAppData = (d: AppDataComplete, isSkipInconsistentTaskStateError = false): boolean => { const dAny: any = d; @@ -31,7 +32,10 @@ export const isValidAppData = (d: AppDataComplete, isSkipInconsistentTaskStateEr && typeof dAny.project === 'object' && dAny.project !== null && Array.isArray(d.reminders) && _isEntityStatesConsistent(d) - && (isSkipInconsistentTaskStateError || _isAllTasksAvailable(d)) + && (isSkipInconsistentTaskStateError || + _isAllTasksAvailable(d) + && _isNoLonelySubTasks(d) + ) : typeof dAny === 'object' ; @@ -116,3 +120,23 @@ const _isEntityStatesConsistent = (data: AppDataComplete): boolean => { return !brokenItem; }; + +const _isNoLonelySubTasks = (data: AppDataComplete): boolean => { + data.task.ids.forEach((id: string) => { + const t: Task = data.task.entities[id] as Task; + if (t.parentId && !data.task.ids.includes(t.parentId)) { + console.log(t); + throw new Error(`Inconsistent Task State: Lonely Sub Task in Today`); + } + }); + + data.taskArchive.ids.forEach((id: string) => { + const t: Task = data.taskArchive.entities[id] as Task; + if (t.parentId && !data.taskArchive.ids.includes(t.parentId)) { + console.log(t); + throw new Error(`Inconsistent Task State: Lonely Sub Task in Archive`); + } + }); + + return true; +}; From c26f62b0ae72c80ca4930073094baebd1c3959e3 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 9 Oct 2020 01:46:52 +0200 Subject: [PATCH 127/131] fix: special case #568 --- src/app/core/data-repair/data-repair.util.ts | 30 +++++++++++++------- src/app/imex/sync/is-valid-app-data.util.ts | 9 ++++-- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/app/core/data-repair/data-repair.util.ts b/src/app/core/data-repair/data-repair.util.ts index b5102d119..fda9fa550 100644 --- a/src/app/core/data-repair/data-repair.util.ts +++ b/src/app/core/data-repair/data-repair.util.ts @@ -17,10 +17,11 @@ export const dataRepair = (data: AppDataComplete): AppDataComplete => { // let dataOut: AppDataComplete = dirtyDeepCopy(data); dataOut = _fixEntityStates(dataOut); dataOut = _removeMissingTasksFromListsOrRestoreFromArchive(dataOut); - dataOut = _removeDuplicatesFromArchive(dataOut); dataOut = _addOrphanedTasksToProjectLists(dataOut); dataOut = _moveArchivedSubTasksToUnarchivedParents(dataOut); dataOut = _moveUnArchivedSubTasksToArchivedParents(dataOut); + dataOut = _removeDuplicatesFromArchive(dataOut); + // console.timeEnd('dataRepair'); return dataOut; }; @@ -56,16 +57,20 @@ const _moveArchivedSubTasksToUnarchivedParents = (data: AppDataComplete): AppDat // to avoid ambiguity const taskState: TaskState = data.task; const taskArchiveState: TaskArchive = data.taskArchive; - const taskArchiveIds = taskArchiveState.ids as string[]; - const orhphanedArchivedSubTasks: TaskCopy[] = taskArchiveIds + const orhphanedArchivedSubTasks: TaskCopy[] = taskArchiveState.ids .map((id: string) => taskArchiveState.entities[id] as TaskCopy) - .filter((t: TaskCopy) => t.parentId && !taskArchiveIds.includes(t.parentId)); + .filter((t: TaskCopy) => t.parentId && !taskArchiveState.ids.includes(t.parentId)); + console.log('orhphanedArchivedSubTasks', orhphanedArchivedSubTasks); orhphanedArchivedSubTasks.forEach((t: TaskCopy) => { // delete archived if duplicate if (taskState.ids.includes(t.id as string)) { - taskArchiveState.ids = taskArchiveIds.filter(id => t.id !== id); + taskArchiveState.ids = taskArchiveState.ids.filter(id => t.id !== id); delete taskArchiveState.entities[t.id]; + // if entity is empty for some reason + if (!taskState.entities[t.id]) { + taskState.entities[t.id] = t; + } } // copy to today if parent exists else if (taskState.ids.includes(t.parentId as string)) { @@ -76,7 +81,8 @@ const _moveArchivedSubTasksToUnarchivedParents = (data: AppDataComplete): AppDat par.subTaskIds = unique([...par.subTaskIds, t.id]); // and delete from archive - taskArchiveState.ids = taskArchiveIds.filter(id => t.id !== id); + taskArchiveState.ids = taskArchiveState.ids.filter(id => t.id !== id); + delete taskArchiveState.entities[t.id]; } // make main if it doesn't @@ -93,20 +99,24 @@ const _moveUnArchivedSubTasksToArchivedParents = (data: AppDataComplete): AppDat // to avoid ambiguity const taskState: TaskState = data.task; const taskArchiveState: TaskArchive = data.taskArchive; - const taskArchiveIds = taskArchiveState.ids as string[]; const orhphanedUnArchivedSubTasks: TaskCopy[] = taskState.ids .map((id: string) => taskState.entities[id] as TaskCopy) .filter((t: TaskCopy) => t.parentId && !taskState.ids.includes(t.parentId)); + console.log('orhphanedUnArchivedSubTasks', orhphanedUnArchivedSubTasks); orhphanedUnArchivedSubTasks.forEach((t: TaskCopy) => { // delete un-archived if duplicate - if (taskArchiveIds.includes(t.id as string)) { + if (taskArchiveState.ids.includes(t.id as string)) { taskState.ids = taskState.ids.filter(id => t.id !== id); delete taskState.entities[t.id]; + // if entity is empty for some reason + if (!taskArchiveState.entities[t.id]) { + taskArchiveState.entities[t.id] = t; + } } // copy to archive if parent exists - else if (taskArchiveIds.includes(t.parentId as string)) { - taskArchiveIds.push((t.id)); + else if (taskArchiveState.ids.includes(t.parentId as string)) { + taskArchiveState.ids.push((t.id)); taskArchiveState.entities[t.id] = t; const par: TaskCopy = taskArchiveState.entities[t.parentId as string] as TaskCopy; diff --git a/src/app/imex/sync/is-valid-app-data.util.ts b/src/app/imex/sync/is-valid-app-data.util.ts index ec063a3c6..e3b3e1d55 100644 --- a/src/app/imex/sync/is-valid-app-data.util.ts +++ b/src/app/imex/sync/is-valid-app-data.util.ts @@ -122,11 +122,13 @@ const _isEntityStatesConsistent = (data: AppDataComplete): boolean => { }; const _isNoLonelySubTasks = (data: AppDataComplete): boolean => { + let isValid: boolean = true; data.task.ids.forEach((id: string) => { const t: Task = data.task.entities[id] as Task; if (t.parentId && !data.task.ids.includes(t.parentId)) { console.log(t); - throw new Error(`Inconsistent Task State: Lonely Sub Task in Today`); + // devError(`Inconsistent Task State: Lonely Sub Task in Today`); + isValid = false; } }); @@ -134,9 +136,10 @@ const _isNoLonelySubTasks = (data: AppDataComplete): boolean => { const t: Task = data.taskArchive.entities[id] as Task; if (t.parentId && !data.taskArchive.ids.includes(t.parentId)) { console.log(t); - throw new Error(`Inconsistent Task State: Lonely Sub Task in Archive`); + // devError(`Inconsistent Task State: Lonely Sub Task in Archive`); + isValid = false; } }); - return true; + return isValid; }; From bc227bcae42cd12d2fb250182a88d8df98028b02 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 9 Oct 2020 19:02:58 +0200 Subject: [PATCH 128/131] fix: make tests work again --- src/app/imex/sync/is-valid-app-data.util.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/imex/sync/is-valid-app-data.util.ts b/src/app/imex/sync/is-valid-app-data.util.ts index e3b3e1d55..afaccacd1 100644 --- a/src/app/imex/sync/is-valid-app-data.util.ts +++ b/src/app/imex/sync/is-valid-app-data.util.ts @@ -127,7 +127,7 @@ const _isNoLonelySubTasks = (data: AppDataComplete): boolean => { const t: Task = data.task.entities[id] as Task; if (t.parentId && !data.task.ids.includes(t.parentId)) { console.log(t); - // devError(`Inconsistent Task State: Lonely Sub Task in Today`); + devError(`Inconsistent Task State: Lonely Sub Task in Today`); isValid = false; } }); @@ -136,7 +136,7 @@ const _isNoLonelySubTasks = (data: AppDataComplete): boolean => { const t: Task = data.taskArchive.entities[id] as Task; if (t.parentId && !data.taskArchive.ids.includes(t.parentId)) { console.log(t); - // devError(`Inconsistent Task State: Lonely Sub Task in Archive`); + devError(`Inconsistent Task State: Lonely Sub Task in Archive`); isValid = false; } }); From 5e340aded20258533767bc87b54b4405c46ad5d1 Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 9 Oct 2020 19:35:19 +0200 Subject: [PATCH 129/131] fix: app not closing on windows for some people #567 --- electron/main-window.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron/main-window.ts b/electron/main-window.ts index 0a2505fdc..976da1c3d 100644 --- a/electron/main-window.ts +++ b/electron/main-window.ts @@ -207,7 +207,7 @@ const appCloseHandler = ( } }); - mainWin.on('close', (event) => { + app.on('window-all-closed', (event) => { // NOTE: this might not work if we run a second instance of the app console.log('close, isQuiting:', (app as any).isQuiting); if (!(app as any).isQuiting) { From 94f814716174e97c2b28e481a8e90f778c3eb72b Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 9 Oct 2020 19:45:54 +0200 Subject: [PATCH 130/131] fix: prevent adding tags via short syntax for child tasks #568 --- src/app/features/tasks/short-syntax.spec.ts | 12 ++++++++++++ src/app/features/tasks/short-syntax.util.ts | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/src/app/features/tasks/short-syntax.spec.ts b/src/app/features/tasks/short-syntax.spec.ts index f48b7f58f..8229ce5fa 100644 --- a/src/app/features/tasks/short-syntax.spec.ts +++ b/src/app/features/tasks/short-syntax.spec.ts @@ -184,6 +184,18 @@ describe('shortSyntax', () => { } }); }); + + it('should not add tags for sub tasks', () => { + const t = { + ...TASK, + parentId: 'SOMEPARENT', + title: 'Fun title #blu #idontexist', + tagIds: [] + }; + const r = shortSyntax(t, ALL_TAGS); + + expect(r).toEqual(undefined); + }); }); describe('should work with all combined', () => { diff --git a/src/app/features/tasks/short-syntax.util.ts b/src/app/features/tasks/short-syntax.util.ts index 2eaeee0ee..6943aa8be 100644 --- a/src/app/features/tasks/short-syntax.util.ts +++ b/src/app/features/tasks/short-syntax.util.ts @@ -112,6 +112,10 @@ const parseProjectChanges = (task: Partial, allProjects?: Project[]): const parseTagChanges = (task: Partial, allTags?: Tag[]): { taskChanges: Partial, newTagTitlesToCreate: string[] } => { const taskChanges: Partial = {}; + if (task.parentId) { + return {taskChanges, newTagTitlesToCreate: []}; + } + const newTagTitlesToCreate: string[] = []; // only exec if previous ones are also passed if (Array.isArray(task.tagIds) && Array.isArray(allTags)) { From bec70f990629853ac6ff4d259b01663d11d24a0e Mon Sep 17 00:00:00 2001 From: Johannes Millan Date: Fri, 9 Oct 2020 19:49:00 +0200 Subject: [PATCH 131/131] 5.9.15 --- CHANGELOG.md | 20 ++++++++++++++++++++ package.json | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 172782c83..edbdfad39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +## [5.9.15](https://github.com/johannesjo/super-productivity/compare/v5.9.14...v5.9.15) (2020-10-09) + + +### Bug Fixes + +* app not closing on windows for some people [#567](https://github.com/johannesjo/super-productivity/issues/567) ([5e340ad](https://github.com/johannesjo/super-productivity/commit/5e340aded20258533767bc87b54b4405c46ad5d1)) +* make tests work again ([bc227bc](https://github.com/johannesjo/super-productivity/commit/bc227bcae42cd12d2fb250182a88d8df98028b02)) +* prevent adding tags via short syntax for child tasks [#568](https://github.com/johannesjo/super-productivity/issues/568) ([94f8147](https://github.com/johannesjo/super-productivity/commit/94f814716174e97c2b28e481a8e90f778c3eb72b)) +* special case [#568](https://github.com/johannesjo/super-productivity/issues/568) ([c26f62b](https://github.com/johannesjo/super-productivity/commit/c26f62b0ae72c80ca4930073094baebd1c3959e3)) +* text overlap ([39508dc](https://github.com/johannesjo/super-productivity/commit/39508dc2f26f4228b4721d5fcaa255b702585088)) +* throw error for inconsistent sub task data [#568](https://github.com/johannesjo/super-productivity/issues/568) ([786235b](https://github.com/johannesjo/super-productivity/commit/786235b9e5ed936adf43aac7f8d9a995fb3cb558)) + + +### Features + +* write auto repair for wrongly archived sub tasks ([81f076a](https://github.com/johannesjo/super-productivity/commit/81f076aefb543b131cfb87e3e8b7696094b14fd2)) +* write auto repair for wrongly unarchived archived sub tasks [#568](https://github.com/johannesjo/super-productivity/issues/568) ([609941d](https://github.com/johannesjo/super-productivity/commit/609941ddebf83ac4a2040159d8087d75316f0716)) + + + ## [5.9.14](https://github.com/johannesjo/super-productivity/compare/v5.9.13...v5.9.14) (2020-10-08) diff --git a/package.json b/package.json index cfc841763..24292e2f8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superProductivity", - "version": "5.9.14", + "version": "5.9.15", "description": "Personal Task Management App to help you with your daily struggle with JIRA etc.", "main": "./electron/main.js", "author": "Johannes Millan (http://super-productivity.com)",