Compare commits

..
Author SHA1 Message Date
Maksim Eltyshev a0f584e814 chore: Update version 2024-09-16 21:21:30 +02:00
Maksim Eltyshev 135f5eccb5 chore: Bump express and related dependencies 2024-09-16 13:26:29 +02:00
Maksim Eltyshev 10001db8cf chore: Update dependencies 2024-09-16 12:04:56 +02:00
Maksim Eltyshev 7ee351fe30 fix: Preserve extension for attachments with long filename
Closes #77
2024-09-16 00:45:53 +02:00
Maksim Eltyshev 73746b83d1 chore: Bump custom-ui css 2024-09-16 00:18:08 +02:00
Aline Fauquette f9a7b38ce9 feat: Change update strategy in case of persistence in Helm (#876) 2024-09-13 22:54:46 +02:00
dependabot[bot] 1f261fe7b6 chore(deps): Bump micromatch from 4.0.7 to 4.0.8 in /client (#879)
Bumps [micromatch](https://github.com/micromatch/micromatch) from 4.0.7 to 4.0.8.
- [Release notes](https://github.com/micromatch/micromatch/releases)
- [Changelog](https://github.com/micromatch/micromatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/micromatch/compare/4.0.7...4.0.8)

---
updated-dependencies:
- dependency-name: micromatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-13 22:43:00 +02:00
dependabot[bot] 80bee30463 chore(deps): Bump serve-static and express in /client (#878)
Bumps [serve-static](https://github.com/expressjs/serve-static) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together.

Updates `serve-static` from 1.15.0 to 1.16.2
- [Release notes](https://github.com/expressjs/serve-static/releases)
- [Changelog](https://github.com/expressjs/serve-static/blob/v1.16.2/HISTORY.md)
- [Commits](https://github.com/expressjs/serve-static/compare/v1.15.0...v1.16.2)

Updates `express` from 4.19.2 to 4.21.0
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/4.21.0/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.19.2...4.21.0)

---
updated-dependencies:
- dependency-name: serve-static
  dependency-type: indirect
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-13 22:42:49 +02:00
dependabot[bot] a9957481b6 chore(deps): Bump send and express in /client (#877)
Bumps [send](https://github.com/pillarjs/send) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together.

Updates `send` from 0.18.0 to 0.19.0
- [Release notes](https://github.com/pillarjs/send/releases)
- [Changelog](https://github.com/pillarjs/send/blob/master/HISTORY.md)
- [Commits](https://github.com/pillarjs/send/compare/0.18.0...0.19.0)

Updates `express` from 4.19.2 to 4.21.0
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/4.21.0/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.19.2...4.21.0)

---
updated-dependencies:
- dependency-name: send
  dependency-type: indirect
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-13 22:42:39 +02:00
dependabot[bot] 36b05a5478 chore(deps): Bump webpack from 5.91.0 to 5.94.0 in /client (#864)
Bumps [webpack](https://github.com/webpack/webpack) from 5.91.0 to 5.94.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.91.0...v5.94.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-13 22:42:08 +02:00
dependabot[bot] af91512abf chore(deps): Bump micromatch from 4.0.7 to 4.0.8 (#874)
Bumps [micromatch](https://github.com/micromatch/micromatch) from 4.0.7 to 4.0.8.
- [Release notes](https://github.com/micromatch/micromatch/releases)
- [Changelog](https://github.com/micromatch/micromatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/micromatch/compare/4.0.7...4.0.8)

---
updated-dependencies:
- dependency-name: micromatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-13 22:39:40 +02:00
Maël Gangloff 8fd0f682d9 feat: Google Chat notifications (#867) 2024-09-04 15:33:43 +02:00
Maksim Eltyshev 9699fbe76a feat: Additional httpOnly token for enhanced security in browsers 2024-09-01 09:31:04 +02:00
Aurélien Troncy 4176a62f1a fix: Update French translation (#862) 2024-08-30 13:27:39 +02:00
Tyler Sweat c12f0844d7 fix: Update Spanish translation (#861) 2024-08-30 11:50:45 +02:00
Aurélien Troncy e6644eb745 feat: Ability to show detailed auth errors, set to false by default (#860) 2024-08-30 11:47:29 +02:00
Blyamur b2e1fba9a0 fix: Update Russian translation (#857) 2024-08-27 16:09:31 +02:00
Maksim Eltyshev 818ae4a6df chore: Update version 2024-08-14 21:39:43 +02:00
Aurélien Troncy 0de0e809ac fix: Update French translation (#849) 2024-08-14 21:37:02 +02:00
Maksim Eltyshev da727c0a0b chore: Generate separate file to store version
Closes #848
2024-08-13 22:26:44 +02:00
Ken 4841a65c77 feat: Add Traditional Chinese translation (#846) 2024-08-13 12:53:42 +02:00
Maksim Eltyshev 0ec4b619d9 chore: Update version 2024-08-12 23:23:50 +02:00
Maksim Eltyshev 12f05adde7 fix: Fix styles, refactoring 2024-08-12 23:17:17 +02:00
Arkadiusz Dzięgiel c594e8bd71 feat: Colorize due date and make it toggleable (#845) 2024-08-12 18:29:50 +02:00
Maksim Eltyshev f84166406f ref: Refactoring 2024-07-26 20:51:59 +02:00
Fayad 82b2ba298d feat: Improvements for mobile version (#776) 2024-07-26 19:02:13 +02:00
jaycoolslm 38b6805ba1 fix: Update healthcheck parameters in docker-compose-dev.yml (#834) 2024-07-24 13:10:56 +02:00
dependabot[bot] 6a7a582045 chore(deps): Bump socket.io-parser from 3.3.3 to 3.3.4 in /client (#833)
Bumps [socket.io-parser](https://github.com/Automattic/socket.io-parser) from 3.3.3 to 3.3.4.
- [Release notes](https://github.com/Automattic/socket.io-parser/releases)
- [Changelog](https://github.com/socketio/socket.io-parser/blob/3.3.4/CHANGELOG.md)
- [Commits](https://github.com/Automattic/socket.io-parser/compare/3.3.3...3.3.4)

---
updated-dependencies:
- dependency-name: socket.io-parser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-23 12:50:41 +02:00
Blyamur c53a00b4ba fix: Update Russian translation (#832) 2024-07-22 16:32:12 +02:00
Blyamur 52103c775b fix: Update Russian translation (#831) 2024-07-22 16:30:44 +02:00
Maksim Eltyshev eeb1bd80cc chore: Update version 2024-07-21 19:44:49 +02:00
dependabot[bot] e6b8538863 chore(deps): Bump ws, engine.io and socket.io-adapter in /server (#830)
Bumps [ws](https://github.com/websockets/ws), [engine.io](https://github.com/socketio/engine.io) and [socket.io-adapter](https://github.com/socketio/socket.io-adapter). These dependencies needed to be updated together.

Updates `ws` from 8.11.0 to 8.17.1
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.11.0...8.17.1)

Updates `engine.io` from 6.5.4 to 6.5.5
- [Release notes](https://github.com/socketio/engine.io/releases)
- [Changelog](https://github.com/socketio/engine.io/blob/6.5.5/CHANGELOG.md)
- [Commits](https://github.com/socketio/engine.io/compare/6.5.4...6.5.5)

Updates `socket.io-adapter` from 2.5.4 to 2.5.5
- [Release notes](https://github.com/socketio/socket.io-adapter/releases)
- [Changelog](https://github.com/socketio/socket.io-adapter/blob/2.5.5/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io-adapter/compare/2.5.4...2.5.5)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
- dependency-name: engine.io
  dependency-type: indirect
- dependency-name: socket.io-adapter
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-21 19:42:36 +02:00
Maksim Eltyshev 9dc38932fb feat: Languages with country codes 2024-07-21 19:33:57 +02:00
Aurélien Troncy e9b4a4adfc fix: Disable x-powered-by header (#829) 2024-07-21 18:27:26 +02:00
Mazyar Yousefiniyae shad 76c78c7252 feat: Add Persian translation (#828) 2024-07-21 18:21:18 +02:00
Maksim Eltyshev 04f52a63f2 chore: Update version 2024-07-17 14:03:00 +02:00
Maksim Eltyshev 6b16a104b1 docs: Update docker pulls counter 2024-07-16 12:39:57 +02:00
Maksim Eltyshev aff853c602 ref: Refactoring, fix linting 2024-07-16 12:33:38 +02:00
aleb_the_flash ad2966c5d6 feat: Improve OIDC support for strict providers (#824) 2024-07-16 12:19:27 +02:00
Maksim Eltyshev 8d74cc1732 chore: Update version 2024-07-15 16:24:31 +02:00
Emmanuel Guyot ea94fe8bf3 fix: Order users by name (#806) 2024-07-15 15:26:26 +02:00
Αλέξανδρος 6052f8999f fix: Fix application crashing when webhook is unavailable (#815) 2024-07-15 14:40:33 +02:00
ItzAndriss 67d1b1c194 fix: Update Hungarian translation (#823) 2024-07-15 14:25:31 +02:00
Stephan Michard b3cb8405f5 fix: Update German translation (#821) 2024-07-15 14:19:06 +02:00
Maksim Eltyshev 7acaec6d04 fix: Fix incorrect related data when transferring card
Closes #431, closes #803
2024-07-15 14:01:06 +02:00
Maksim Eltyshev 72896a66b3 chore: Update version 2024-06-21 12:11:15 +02:00
Maksim Eltyshev 4be4783251 fix: Fix icon spacing for action buttons 2024-06-21 12:01:46 +02:00
HannesOberreiter 5c6c6a0bcf feat: Add copy link action to card modal (#804) 2024-06-21 11:48:36 +02:00
HannesOberreiter ba178d66fa docs: Add types to webhook function (#796) 2024-06-18 15:41:12 +02:00
HannesOberreiter 270ce29f87 feat: Add custom user agent with base url to webhook (#799) 2024-06-18 15:36:51 +02:00
HannesOberreiter de1ed3c784 ref: Define all possible event types in webhook module (#795) 2024-06-18 15:32:39 +02:00
Maksim Eltyshev caf8790f28 chore: Update version 2024-06-14 17:18:42 +02:00
Sarah Soo 81436b373d feat: Ability to specify existing secrets for values in Helm (#791)
Closes #790
2024-06-14 16:41:10 +02:00
NathanVss cc1e886a31 feat: Ability to allow everyone to create projects (#787) 2024-06-14 16:38:06 +02:00
Maksim Eltyshev f0e9fe7904 chore: Update version 2024-06-12 09:06:20 +02:00
Gavin Mogan 5fcea5d651 fix: Handle WEBHOOKS env variable being unset (#785)
Closes #784
2024-06-12 08:59:36 +02:00
Maksim Eltyshev a963d85a66 chore: Update version 2024-06-12 01:02:55 +02:00
Samuel 04b42decef meta: Add issue templates (#782) 2024-06-12 00:59:37 +02:00
Maksim Eltyshev c065566c15 feat: Webhooks configuration, all events support, refactoring 2024-06-12 00:51:36 +02:00
HannesOberreiter 3779bdb053 feat: Events via webhook (#771)
Closes #215, closes #656
2024-06-06 20:22:14 +02:00
HannesOberreiter 4124ab17d2 fix: Focus end of field when editing (#779) 2024-06-06 20:06:16 +02:00
Maksim Eltyshev 0e3bc92a61 chore: Update version 2024-06-02 01:36:29 +02:00
Maksim Eltyshev b8d7e713b9 chore: Update dependencies 2024-06-02 01:34:03 +02:00
Emmanuel Guyot 017eee8302 fix: Use server base path for socket connection (#772)
Closes #768
2024-05-23 23:59:44 +02:00
Mitch Harvey 1b28892cf5 fix: Fix Helm template for dburl secret (#770) 2024-05-21 23:32:07 +02:00
299 changed files with 15554 additions and 18640 deletions
+53
View File
@@ -0,0 +1,53 @@
name: "🐛 Bug Report"
description: Report a bug found while using Planka
title: "[Bug]: "
labels: ["Type: Bug", "Status: Triage"]
body:
- type: dropdown
id: issue-type
attributes:
label: Where is the problem occurring?
description: Select the part of the application where you encountered the issue.
options:
- "I encountered the problem while using the application (Frontend)"
- "I encountered the problem while interacting with the server (Backend)"
- "I'm not sure"
- type: dropdown
id: browsers
attributes:
label: What browsers are you seeing the problem on?
multiple: true
options:
- Brave
- Chrome
- Firefox
- Microsoft Edge
- Safari
- Other
- type: textarea
id: current-behavior
attributes:
label: Current behaviour
description: A description of what is currently happening, including screenshots and other useful information (**DO NOT INCLUDE PRIVATE INFORMATION**).
placeholder: Currently...
validations:
required: true
- type: textarea
id: desired-behavior
attributes:
label: Desired behaviour
description: A clear description of what you think should happen.
placeholder: In this situation, I expected ...
- type: textarea
id: reproduction
attributes:
label: Steps to reproduce
description: Clearly describe which steps or actions you have taken to arrive at the problem. If you have some experience with the code, please link to the specific pieces of code.
placeholder: I did X, then Y, before arriving at Z, when ERROR ...
validations:
required: true
- type: textarea
id: other
attributes:
label: Other information
description: Any other details?
@@ -0,0 +1,33 @@
name: "✨ Feature Request"
description: Suggest a feature or enhancement to improve Planka.
labels: ["Type: Idea"]
body:
- type: dropdown
id: idea-type
attributes:
label: Is this a feature for the backend or frontend?
multiple: true
options:
- Backend
- Frontend
validations:
required: true
- type: textarea
id: feature
attributes:
label: What would you like?
description: A clear description of the feature or enhancement wanted.
placeholder: I'd like to be able to...
validations:
required: true
- type: textarea
id: reason
attributes:
label: Why is this needed?
description: A clear description of why this would be useful to have.
placeholder: I want this because...
- type: textarea
id: other
attributes:
label: Other information
placeholder: Any other details?
Executable → Regular
-2
View File
@@ -1,4 +1,2 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
+1 -1
View File
@@ -1,7 +1,7 @@
# Planka
#### Elegant open source project tracking.
![David (path)](https://img.shields.io/github/package-json/v/plankanban/planka) ![Docker Pulls](https://img.shields.io/docker/pulls/meltyshev/planka) ![GitHub](https://img.shields.io/github/license/plankanban/planka)
![David (path)](https://img.shields.io/github/package-json/v/plankanban/planka) ![Docker Pulls](https://img.shields.io/badge/docker_pulls-4M%2B-%23066da5) ![GitHub](https://img.shields.io/github/license/plankanban/planka)
![](https://raw.githubusercontent.com/plankanban/planka/master/demo.gif)
+2 -2
View File
@@ -15,13 +15,13 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.31
version: 0.2.8
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.17.4"
appVersion: "1.22.0"
dependencies:
- alias: postgresql
+27 -3
View File
@@ -11,6 +11,10 @@ spec:
selector:
matchLabels:
{{- include "planka.selectorLabels" . | nindent 6 }}
{{- if .Values.persistence.enabled }}
strategy:
type: Recreate
{{- end }}
template:
metadata:
{{- with .Values.podAnnotations }}
@@ -68,7 +72,7 @@ spec:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: .Values.existingDburlSecret
name: {{ .Values.existingDburlSecret }}
key: uri
{{- else }}
- name: DATABASE_URL
@@ -90,17 +94,37 @@ spec:
value: http://localhost:3000
{{- end }}
- name: SECRET_KEY
{{- if .Values.existingSecretkeySecret }}
valueFrom:
secretKeyRef:
name: {{ .Values.existingSecretkeySecret }}
key: key
{{- else }}
value: {{ required "A secret key needs to be generated using 'openssl rand -hex 64' and assigned to secretkey." .Values.secretkey }}
{{- end }}
- name: TRUST_PROXY
value: "0"
- name: DEFAULT_ADMIN_EMAIL
value: {{ .Values.admin_email }}
- name: DEFAULT_ADMIN_PASSWORD
value: {{ .Values.admin_password }}
- name: DEFAULT_ADMIN_NAME
value: {{ .Values.admin_name }}
{{- if .Values.existingAdminCredsSecret }}
- name: DEFAULT_ADMIN_USERNAME
valueFrom:
secretKeyRef:
name: {{ .Values.existingAdminCredsSecret }}
key: username
- name: DEFAULT_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.existingAdminCredsSecret }}
key: password
{{- else }}
- name: DEFAULT_ADMIN_USERNAME
value: {{ .Values.admin_username }}
- name: DEFAULT_ADMIN_PASSWORD
value: {{ .Values.admin_password }}
{{- end }}
{{ range $k, $v := .Values.env }}
- name: {{ $k | quote }}
value: {{ $v | quote }}
+10
View File
@@ -17,6 +17,16 @@ fullnameOverride: ""
# Generate a secret using openssl rand -base64 45
secretkey: ""
## @param existingSecretkeySecret Name of an existing secret containing the session key string
## NOTE: Must contain key `key`
## NOTE: When it's set, the secretkey parameter is ignored
existingSecretkeySecret: ""
## @param existingAdminCredsSecret Name of an existing secret containing the admin username and password
## NOTE: Must contain keys `username` and `password`
## NOTE: When it's set, the `admin_username` and `admin_password` parameters are ignored
existingAdminCredsSecret: ""
# Base url for Planka. Will override `ingress.hosts[0].host`
# Defaults to `http://localhost:3000` if ingress is disabled.
baseUrl: ""
-1
View File
@@ -1 +0,0 @@
REACT_APP_VERSION=1.17.4
+2216 -7883
View File
File diff suppressed because it is too large Load Diff
+17 -16
View File
@@ -65,8 +65,8 @@
"dequal": "^2.0.3",
"easymde": "^2.18.0",
"history": "^5.3.0",
"i18next": "^23.11.2",
"i18next-browser-languagedetector": "^7.2.1",
"i18next": "^23.15.1",
"i18next-browser-languagedetector": "^8.0.0",
"initials": "^3.1.2",
"js-cookie": "^3.0.5",
"jwt-decode": "^4.0.0",
@@ -75,20 +75,20 @@
"lodash": "^4.17.21",
"nanoid": "^5.0.7",
"node-sass": "^9.0.0",
"photoswipe": "^5.4.3",
"photoswipe": "^5.4.4",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react": "18.2.0",
"react-app-rewired": "^2.2.1",
"react-beautiful-dnd": "^13.1.1",
"react-datepicker": "^4.25.0",
"react-dom": "^18.2.0",
"react-dom": "18.2.0",
"react-dropzone": "^14.2.3",
"react-i18next": "^13.5.0",
"react-i18next": "^15.0.2",
"react-input-mask": "^2.0.4",
"react-markdown": "^8.0.7",
"react-photoswipe-gallery": "^2.2.7",
"react-redux": "^8.1.3",
"react-router-dom": "^6.22.3",
"react-router-dom": "^6.26.2",
"react-scripts": "5.0.1",
"react-simplemde-editor": "^5.2.0",
"react-textarea-autosize": "^8.5.3",
@@ -102,22 +102,23 @@
"sails.io.js": "^1.2.1",
"semantic-ui-react": "^2.1.5",
"socket.io-client": "^2.5.0",
"validator": "^13.11.0",
"validator": "^13.12.0",
"whatwg-fetch": "^3.6.20",
"zxcvbn": "^4.4.2"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.3.1",
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@testing-library/jest-dom": "^6.5.0",
"@testing-library/react": "^15.0.7",
"@testing-library/user-event": "^14.5.2",
"babel-preset-airbnb": "^5.0.0",
"chai": "^4.4.1",
"chai": "^4.5.0",
"eslint": "^8.57.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
"react-test-renderer": "^18.2.0"
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-jsx-a11y": "^6.10.0",
"eslint-plugin-react": "^7.36.1",
"eslint-plugin-react-hooks": "^4.6.2",
"react-test-renderer": "18.2.0"
}
}
+1 -1
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
+6 -1
View File
@@ -57,10 +57,15 @@ updateCard.failure = (id, error) => ({
},
});
const handleCardUpdate = (card) => ({
const handleCardUpdate = (card, isFetched, cardMemberships, cardLabels, tasks, attachments) => ({
type: ActionTypes.CARD_UPDATE_HANDLE,
payload: {
card,
isFetched,
cardMemberships,
cardLabels,
tasks,
attachments,
},
});
+4 -5
View File
@@ -1,15 +1,14 @@
import http from './http';
import socket from './socket';
/* Actions */
const createAccessToken = (data, headers) => http.post('/access-tokens', data, headers);
const createAccessToken = (data, headers) =>
http.post('/access-tokens?withHttpOnlyToken=true', data, headers);
const exchangeForAccessTokenUsingOidc = (data, headers) =>
http.post('/access-tokens/exchange-using-oidc', data, headers);
http.post('/access-tokens/exchange-using-oidc?withHttpOnlyToken=true', data, headers);
const deleteCurrentAccessToken = (headers) =>
socket.delete('/access-tokens/me', undefined, headers);
const deleteCurrentAccessToken = (headers) => http.delete('/access-tokens/me', undefined, headers);
export default {
createAccessToken,
+2 -1
View File
@@ -5,7 +5,7 @@ import Config from '../constants/Config';
const http = {};
// TODO: add all methods
['GET', 'POST'].forEach((method) => {
['GET', 'POST', 'DELETE'].forEach((method) => {
http[method.toLowerCase()] = (url, data, headers) => {
const formData =
data &&
@@ -19,6 +19,7 @@ const http = {};
method,
headers,
body: formData,
credentials: 'include',
})
.then((response) =>
response.json().then((body) => ({
+1 -1
View File
@@ -13,7 +13,7 @@ io.sails.environment = process.env.NODE_ENV;
const { socket } = io;
socket.path = `${Config.BASE_PATH}/socket.io`;
socket.path = `${Config.SERVER_BASE_PATH}/socket.io`;
socket.connect = socket._connect; // eslint-disable-line no-underscore-dangle
['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].forEach((method) => {
@@ -1,6 +1,8 @@
:global(#app) {
.wrapper {
height: 100%;
max-height: 100vh;
max-width: 100vw;
position: fixed;
width: 100%;
z-index: -1;
@@ -48,16 +48,6 @@
min-width: 100%;
}
.panel {
align-items: center;
display: flex;
margin-bottom: 20px;
}
.panelItem {
margin-right: 20px;
}
.wrapper {
margin: 0 20px;
}
@@ -3,12 +3,13 @@
align-items: center;
display: flex;
flex: 0 0 auto;
margin-right: 20px;
}
.actions {
align-items: center;
display: flex;
gap: 20px;
justify-content: flex-start;
margin: 20px 20px;
}
@@ -50,6 +50,10 @@
transition: width 0.2s ease;
width: 280px;
@media only screen and (max-width: 797px) {
width: 220px;
}
input {
font-size: 13px;
}
+4 -1
View File
@@ -24,6 +24,7 @@ const Card = React.memo(
index,
name,
dueDate,
isDueDateCompleted,
stopwatch,
coverUrl,
boardId,
@@ -120,7 +121,7 @@ const Card = React.memo(
)}
{dueDate && (
<span className={classNames(styles.attachment, styles.attachmentLeft)}>
<DueDate value={dueDate} size="tiny" />
<DueDate value={dueDate} isCompleted={isDueDateCompleted} size="tiny" />
</span>
)}
{stopwatch && (
@@ -221,6 +222,7 @@ Card.propTypes = {
index: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
dueDate: PropTypes.instanceOf(Date),
isDueDateCompleted: PropTypes.bool,
stopwatch: PropTypes.object, // eslint-disable-line react/forbid-prop-types
coverUrl: PropTypes.string,
boardId: PropTypes.string.isRequired,
@@ -255,6 +257,7 @@ Card.propTypes = {
Card.defaultProps = {
dueDate: undefined,
isDueDateCompleted: undefined,
stopwatch: undefined,
coverUrl: undefined,
};
@@ -21,6 +21,14 @@
background: #ebeef0;
color: #516b7a;
}
@media only screen and (max-width: 797px) {
&:focus,
&:active {
background: #ebeef0;
color: #516b7a;
}
}
}
.attachment {
@@ -55,6 +63,12 @@
box-shadow: 0 1px 0 #ccc;
position: relative;
@media only screen and (max-width: 797px) {
.target {
opacity: 1;
}
}
&:hover {
background: #f5f6f7;
border-bottom-color: rgba(9, 30, 66, 0.25);
+2 -1
View File
@@ -5,6 +5,7 @@ import TextareaAutosize from 'react-textarea-autosize';
import { Button, Form, TextArea } from 'semantic-ui-react';
import { useClosableForm, useField } from '../../hooks';
import { focusEnd } from '../../utils/element-helpers';
import styles from './NameEdit.module.scss';
@@ -79,7 +80,7 @@ const NameEdit = React.forwardRef(({ children, defaultValue, onUpdate }, ref) =>
useEffect(() => {
if (isOpened) {
field.current.ref.current.focus();
focusEnd(field.current.ref.current);
}
}, [isOpened]);
@@ -6,6 +6,7 @@ import TextareaAutosize from 'react-textarea-autosize';
import { Button, Form, TextArea } from 'semantic-ui-react';
import { useForm } from '../../../hooks';
import { focusEnd } from '../../../utils/element-helpers';
import styles from './CommentEdit.module.scss';
@@ -70,7 +71,7 @@ const CommentEdit = React.forwardRef(({ children, defaultData, onUpdate }, ref)
useEffect(() => {
if (isOpened) {
textField.current.ref.current.focus();
focusEnd(textField.current.ref.current);
}
}, [isOpened]);
@@ -2,7 +2,7 @@
.dropzone {
background: white;
font-size: 20px;
font-weight: 700;
font-weight: bold;
height: 100%;
line-height: 30px;
opacity: 0.7;
@@ -16,7 +16,7 @@
.contentError {
color: #fff;
font-size: 20px;
font-weight: 700;
font-weight: bold;
height: 20px;
width: 470px;
}
@@ -35,7 +35,7 @@
color: #5e6c84;
display: block;
font-size: 18px;
font-weight: 700;
font-weight: bold;
height: 100%;
line-height: 80px;
overflow: hidden;
@@ -50,7 +50,7 @@
.name {
color: #17394d;
font-size: 14px;
font-weight: 700;
font-weight: bold;
line-height: 20px;
word-wrap: break-word;
}
+49 -7
View File
@@ -1,8 +1,8 @@
import React, { useCallback, useRef } from 'react';
import React, { useCallback, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { useTranslation } from 'react-i18next';
import { Button, Grid, Icon, Modal } from 'semantic-ui-react';
import { Button, Checkbox, Grid, Icon, Modal } from 'semantic-ui-react';
import { usePopup } from '../../lib/popup';
import { Markdown } from '../../lib/custom-ui';
@@ -32,6 +32,7 @@ const CardModal = React.memo(
name,
description,
dueDate,
isDueDateCompleted,
stopwatch,
isSubscribed,
isActivitiesFetching,
@@ -81,6 +82,7 @@ const CardModal = React.memo(
onClose,
}) => {
const [t] = useTranslation();
const [isLinkCopied, setIsLinkCopied] = useState(false);
const isGalleryOpened = useRef(false);
@@ -117,6 +119,12 @@ const CardModal = React.memo(
[onUpdate],
);
const handleDueDateCompletionChange = useCallback(() => {
onUpdate({
isDueDateCompleted: !isDueDateCompleted,
});
}, [isDueDateCompleted, onUpdate]);
const handleStopwatchUpdate = useCallback(
(newStopwatch) => {
onUpdate({
@@ -146,6 +154,14 @@ const CardModal = React.memo(
onClose();
}, [onDuplicate, onClose]);
const handleCopyLinkClick = useCallback(() => {
navigator.clipboard.writeText(window.location.href);
setIsLinkCopied(true);
setTimeout(() => {
setIsLinkCopied(false);
}, 5000);
}, []);
const handleGalleryOpen = useCallback(() => {
isGalleryOpened.current = true;
}, []);
@@ -291,13 +307,24 @@ const CardModal = React.memo(
context: 'title',
})}
</div>
<span className={styles.attachment}>
<span className={classNames(styles.attachment, styles.attachmentDueDate)}>
{canEdit ? (
<DueDateEditPopup defaultValue={dueDate} onUpdate={handleDueDateUpdate}>
<DueDate value={dueDate} />
</DueDateEditPopup>
<>
<Checkbox
checked={isDueDateCompleted}
disabled={!canEdit}
onChange={handleDueDateCompletionChange}
/>
<DueDateEditPopup defaultValue={dueDate} onUpdate={handleDueDateUpdate}>
<DueDate
withStatusIcon
value={dueDate}
isCompleted={isDueDateCompleted}
/>
</DueDateEditPopup>
</>
) : (
<DueDate value={dueDate} />
<DueDate withStatusIcon value={dueDate} isCompleted={isDueDateCompleted} />
)}
</span>
</div>
@@ -506,6 +533,19 @@ const CardModal = React.memo(
<Icon name="copy outline" className={styles.actionIcon} />
{t('action.duplicate')}
</Button>
{window.isSecureContext && (
<Button fluid className={styles.actionButton} onClick={handleCopyLinkClick}>
<Icon
name={isLinkCopied ? 'linkify' : 'unlink'}
className={styles.actionIcon}
/>
{isLinkCopied
? t('common.linkIsCopied')
: t('action.copyLink', {
context: 'title',
})}
</Button>
)}
<DeletePopup
title="common.deleteCard"
content="common.areYouSureYouWantToDeleteThisCard"
@@ -540,6 +580,7 @@ CardModal.propTypes = {
name: PropTypes.string.isRequired,
description: PropTypes.string,
dueDate: PropTypes.instanceOf(Date),
isDueDateCompleted: PropTypes.bool,
stopwatch: PropTypes.object, // eslint-disable-line react/forbid-prop-types
isSubscribed: PropTypes.bool.isRequired,
isActivitiesFetching: PropTypes.bool.isRequired,
@@ -594,6 +635,7 @@ CardModal.propTypes = {
CardModal.defaultProps = {
description: undefined,
dueDate: undefined,
isDueDateCompleted: false,
stopwatch: undefined,
};
@@ -20,18 +20,26 @@
.actionIcon {
color: #17394d;
display: inline;
margin-right: 8px;
}
.actions {
margin-bottom: 24px;
@media only screen and (max-width: 797px) {
flex: 1;
}
@media only screen and (max-width: 425px) {
padding: 0;
width: 100%;
}
}
.actionsTitle {
color: #8c8c8c;
font-size: 12px;
font-weight: 500;
font-weight: normal;
letter-spacing: 0.04em;
margin-top: 16px;
text-transform: uppercase;
@@ -50,6 +58,12 @@
max-width: 100%;
}
.attachmentDueDate {
align-items: center;
display: flex;
gap: 4px;
}
.attachments {
display: inline-block;
margin: 0 8px 8px 0;
@@ -63,6 +77,11 @@
.contentPadding {
padding: 8px 8px 0 16px;
@media only screen and (max-width: 797px) {
padding-right: 16px;
width: 100% !important;
}
}
.cursorPointer {
@@ -139,7 +158,7 @@
.headerTitle {
color: #17394d;
font-size: 20px;
font-weight: 700;
font-weight: bold;
line-height: 24px;
}
@@ -155,6 +174,11 @@
.modalPadding {
padding: 0px;
@media only screen and (max-width: 797px) {
display: flex;
flex-flow: column nowrap;
}
}
.moduleHeader {
@@ -185,6 +209,15 @@
.sidebarPadding {
padding: 8px 16px 0 8px;
@media only screen and (max-width: 797px) {
align-items: flex-start;
display: flex;
flex-flow: row wrap;
gap: 10px;
padding-left: 16px;
width: 100% !important;
}
}
.text {
@@ -6,7 +6,7 @@
box-shadow: none;
color: #17394d;
font-size: 20px;
font-weight: 700;
font-weight: bold;
line-height: 24px;
margin: -5px;
overflow: hidden;
@@ -5,6 +5,7 @@ import TextareaAutosize from 'react-textarea-autosize';
import { Button, Form, TextArea } from 'semantic-ui-react';
import { useField } from '../../../hooks';
import { focusEnd } from '../../../utils/element-helpers';
import styles from './NameEdit.module.scss';
@@ -65,7 +66,7 @@ const NameEdit = React.forwardRef(({ children, defaultValue, onUpdate }, ref) =>
useEffect(() => {
if (isOpened) {
field.current.ref.current.focus();
focusEnd(field.current.ref.current);
}
}, [isOpened]);
@@ -4,6 +4,7 @@
border-radius: 4px;
bottom: 20px;
box-shadow: #b04632 0 1px 0;
max-width: calc(100% - 40px);
padding: 12px 18px;
position: fixed;
right: 20px;
+81 -2
View File
@@ -1,8 +1,10 @@
import upperFirst from 'lodash/upperFirst';
import React from 'react';
import React, { useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { useTranslation } from 'react-i18next';
import { Icon } from 'semantic-ui-react';
import { useForceUpdate } from '../../lib/hooks';
import getDateFormat from '../../utils/get-date-format';
@@ -14,6 +16,12 @@ const SIZES = {
MEDIUM: 'medium',
};
const STATUSES = {
DUE_SOON: 'dueSoon',
OVERDUE: 'overdue',
COMPLETED: 'completed',
};
const LONG_DATE_FORMAT_BY_SIZE = {
tiny: 'longDate',
small: 'longDate',
@@ -26,8 +34,47 @@ const FULL_DATE_FORMAT_BY_SIZE = {
medium: 'fullDateTime',
};
const DueDate = React.memo(({ value, size, isDisabled, onClick }) => {
const STATUS_ICON_PROPS_BY_STATUS = {
[STATUSES.DUE_SOON]: {
name: 'hourglass half',
color: 'orange',
},
[STATUSES.OVERDUE]: {
name: 'hourglass end',
color: 'red',
},
[STATUSES.COMPLETED]: {
name: 'checkmark',
color: 'green',
},
};
const getStatus = (dateTime, isCompleted) => {
if (isCompleted) {
return STATUSES.COMPLETED;
}
const secondsLeft = Math.floor((dateTime.getTime() - new Date().getTime()) / 1000);
if (secondsLeft <= 0) {
return STATUSES.OVERDUE;
}
if (secondsLeft <= 24 * 60 * 60) {
return STATUSES.DUE_SOON;
}
return null;
};
const DueDate = React.memo(({ value, size, isCompleted, isDisabled, withStatusIcon, onClick }) => {
const [t] = useTranslation();
const forceUpdate = useForceUpdate();
const statusRef = useRef(null);
statusRef.current = getStatus(value, isCompleted);
const intervalRef = useRef(null);
const dateFormat = getDateFormat(
value,
@@ -35,11 +82,34 @@ const DueDate = React.memo(({ value, size, isDisabled, onClick }) => {
FULL_DATE_FORMAT_BY_SIZE[size],
);
useEffect(() => {
if ([null, STATUSES.DUE_SOON].includes(statusRef.current)) {
intervalRef.current = setInterval(() => {
const status = getStatus(value, isCompleted);
if (status !== statusRef.current) {
forceUpdate();
}
if (status === STATUSES.OVERDUE) {
clearInterval(intervalRef.current);
}
}, 1000);
}
return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
};
}, [value, isCompleted, forceUpdate]);
const contentNode = (
<span
className={classNames(
styles.wrapper,
styles[`wrapper${upperFirst(size)}`],
!withStatusIcon && statusRef.current && styles[`wrapper${upperFirst(statusRef.current)}`],
onClick && styles.wrapperHoverable,
)}
>
@@ -47,6 +117,10 @@ const DueDate = React.memo(({ value, size, isDisabled, onClick }) => {
value,
postProcess: 'formatDate',
})}
{withStatusIcon && statusRef.current && (
// eslint-disable-next-line react/jsx-props-no-spreading
<Icon {...STATUS_ICON_PROPS_BY_STATUS[statusRef.current]} className={styles.statusIcon} />
)}
</span>
);
@@ -62,14 +136,19 @@ const DueDate = React.memo(({ value, size, isDisabled, onClick }) => {
DueDate.propTypes = {
value: PropTypes.instanceOf(Date).isRequired,
size: PropTypes.oneOf(Object.values(SIZES)),
isCompleted: PropTypes.bool.isRequired,
isDisabled: PropTypes.bool,
withStatusIcon: PropTypes.bool,
onClick: PropTypes.func,
onCompletionToggle: PropTypes.func,
};
DueDate.defaultProps = {
size: SIZES.MEDIUM,
isDisabled: false,
withStatusIcon: false,
onClick: undefined,
onCompletionToggle: undefined,
};
export default DueDate;
@@ -8,16 +8,17 @@
padding: 0;
}
.statusIcon {
line-height: 1;
margin: 0 0 0 8px;
}
.wrapper {
background: #dce0e4;
border: none;
border-radius: 3px;
color: #6a808b;
display: inline-block;
outline: none;
text-align: left;
transition: background 0.3s ease;
vertical-align: top;
}
.wrapperHoverable:hover {
@@ -43,4 +44,21 @@
line-height: 20px;
padding: 6px 12px;
}
/* Statuses */
.wrapperDueSoon {
background: #f2711c;
color: #fff;
}
.wrapperOverdue {
background: #db2828;
color: #fff;
}
.wrapperCompleted {
background: #21ba45;
color: #fff;
}
}
@@ -1,5 +1,6 @@
:global(#app) {
.wrapper {
max-width: 100vw;
position: fixed;
width: 100%;
z-index: 1;
@@ -87,7 +87,12 @@
}
.userName {
display: none;
margin-right: 10px;
@media only screen and (min-width: 797px) {
display: block;
}
}
.wrapper {
+2 -2
View File
@@ -17,7 +17,7 @@ const SIZES = {
const Label = React.memo(({ name, color, size, isDisabled, onClick }) => {
const contentNode = (
<div
<span
title={name}
className={classNames(
styles.wrapper,
@@ -28,7 +28,7 @@ const Label = React.memo(({ name, color, size, isDisabled, onClick }) => {
)}
>
{name || '\u00A0'}
</div>
</span>
);
return onClick ? (
@@ -11,17 +11,17 @@
.wrapper {
border-radius: 3px;
box-sizing: border-box;
color: #fff;
font-weight: 400;
outline: none;
display: inline-block;
font-weight: normal;
overflow: hidden;
text-overflow: ellipsis;
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2);
vertical-align: top;
white-space: nowrap;
}
.wrapperNameless{
.wrapperNameless {
width: 40px;
}
@@ -80,6 +80,12 @@
&:hover .target {
opacity: 1;
}
@media only screen and (max-width: 797px) {
.target {
opacity: 1;
}
}
}
.headerEditable {
@@ -103,6 +109,15 @@
background: rgba(9, 30, 66, 0.13);
color: #516b7a;
}
@media only screen and (max-width: 797px) {
&:focus,
&:active {
background: rgba(9, 30, 66, 0.13);
color: #516b7a;
}
}
}
.headerName {
+2 -1
View File
@@ -4,6 +4,7 @@ import TextareaAutosize from 'react-textarea-autosize';
import { TextArea } from 'semantic-ui-react';
import { useField } from '../../hooks';
import { focusEnd } from '../../utils/element-helpers';
import styles from './NameEdit.module.scss';
@@ -71,7 +72,7 @@ const NameEdit = React.forwardRef(({ children, defaultValue, onUpdate }, ref) =>
useEffect(() => {
if (isOpened) {
field.current.ref.current.select();
focusEnd(field.current.ref.current);
}
}, [isOpened]);
+6
View File
@@ -18,6 +18,11 @@ const createMessage = (error) => {
}
switch (error.message) {
case 'Invalid credentials':
return {
type: 'error',
content: 'common.invalidCredentials',
};
case 'Invalid email or username':
return {
type: 'error',
@@ -116,6 +121,7 @@ const Login = React.memo(
useEffect(() => {
if (wasSubmitting && !isSubmitting && error) {
switch (error.message) {
case 'Invalid credentials':
case 'Invalid email or username':
emailOrUsernameField.current.select();
@@ -11,6 +11,10 @@
vertical-align: top;
width: 36px;
@media only screen and (max-width: 797px) {
margin-left: 10px;
}
&:hover {
background: rgba(0, 0, 0, 0.32);
}
@@ -10,13 +10,10 @@
.wrapper {
background: #dce0e4;
border: none;
border-radius: 3px;
color: #6a808b;
display: inline-block;
font-variant-numeric: tabular-nums;
outline: none;
text-align: left;
transition: background 0.3s ease;
vertical-align: top;
}
@@ -14,12 +14,10 @@
}
.wrapper {
border: none;
border-radius: 50%;
color: #fff;
display: inline-block;
line-height: 1;
outline: none;
text-align: center;
vertical-align: top;
}
@@ -32,7 +30,6 @@
.wrapperTiny {
font-size: 10px;
font-weight: 400;
height: 24px;
line-height: 20px;
padding: 2px 0;
@@ -41,7 +38,6 @@
.wrapperSmall {
font-size: 12px;
font-weight: 400;
height: 28px;
padding: 8px 0;
width: 28px;
@@ -49,7 +45,6 @@
.wrapperMedium {
font-size: 14px;
font-weight: 500;
height: 32px;
padding: 10px 0;
width: 32px;
@@ -57,7 +52,6 @@
.wrapperLarge {
font-size: 14px;
font-weight: 500;
height: 36px;
padding: 12px 0 10px;
width: 36px;
@@ -65,7 +59,6 @@
.wrapperMassive {
font-size: 36px;
font-weight: 500;
height: 100px;
padding: 32px 0 10px;
width: 100px;
@@ -2,7 +2,7 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import { Image, Tab } from 'semantic-ui-react';
import Config from '../../constants/Config';
import version from '../../version';
import logo from '../../assets/images/logo.png';
@@ -15,7 +15,7 @@ const AboutPane = React.memo(() => {
<Tab.Pane attached={false} className={styles.wrapper}>
<Image centered src={logo} size="large" />
<div className={styles.version}>
{t('common.version')} {Config.VERSION}
{t('common.version')} {version}
</div>
</Tab.Pane>
);
-3
View File
@@ -195,9 +195,6 @@ export default {
CARD_UPDATE__SUCCESS: 'CARD_UPDATE__SUCCESS',
CARD_UPDATE__FAILURE: 'CARD_UPDATE__FAILURE',
CARD_UPDATE_HANDLE: 'CARD_UPDATE_HANDLE',
CARD_TRANSFER: 'CARD_TRANSFER',
CARD_TRANSFER__SUCCESS: 'CARD_TRANSFER__SUCCESS',
CARD_TRANSFER__FAILURE: 'CARD_TRANSFER__FAILURE',
CARD_DUPLICATE: 'CARD_DUPLICATE',
CARD_DUPLICATE__SUCCESS: 'CARD_DUPLICATE__SUCCESS',
CARD_DUPLICATE__FAILURE: 'CARD_DUPLICATE__FAILURE',
+3 -3
View File
@@ -1,12 +1,12 @@
const VERSION = process.env.REACT_APP_VERSION;
const { BASE_URL } = window;
const BASE_PATH = BASE_URL.replace(/^.*\/\/[^/]*(.*)[^?#]*.*$/, '$1');
const SERVER_BASE_URL =
process.env.REACT_APP_SERVER_BASE_URL ||
(process.env.NODE_ENV === 'production' ? BASE_URL : 'http://localhost:1337');
const SERVER_BASE_PATH = SERVER_BASE_URL.replace(/^.*\/\/[^/]*(.*)[^?#]*.*$/, '$1');
const SERVER_HOST_NAME = SERVER_BASE_URL.replace(/^(.*\/\/[^/?#]*).*$/, '$1');
const ACCESS_TOKEN_KEY = 'accessToken';
@@ -17,9 +17,9 @@ const POSITION_GAP = 65535;
const ACTIVITIES_LIMIT = 50;
export default {
VERSION,
BASE_PATH,
SERVER_BASE_URL,
SERVER_BASE_PATH,
SERVER_HOST_NAME,
ACCESS_TOKEN_KEY,
ACCESS_TOKEN_VERSION_KEY,
+3 -4
View File
@@ -20,10 +20,8 @@ const makeMapStateToProps = () => {
const allLabels = selectors.selectLabelsForCurrentBoard(state);
const currentUserMembership = selectors.selectCurrentUserMembershipForCurrentBoard(state);
const { name, dueDate, stopwatch, coverUrl, boardId, listId, isPersisted } = selectCardById(
state,
id,
);
const { name, dueDate, isDueDateCompleted, stopwatch, coverUrl, boardId, listId, isPersisted } =
selectCardById(state, id);
const users = selectUsersByCardId(state, id);
const labels = selectLabelsByCardId(state, id);
@@ -38,6 +36,7 @@ const makeMapStateToProps = () => {
index,
name,
dueDate,
isDueDateCompleted,
stopwatch,
coverUrl,
boardId,
@@ -21,6 +21,7 @@ const mapStateToProps = (state) => {
name,
description,
dueDate,
isDueDateCompleted,
stopwatch,
isSubscribed,
isActivitiesFetching,
@@ -49,6 +50,7 @@ const mapStateToProps = (state) => {
name,
description,
dueDate,
isDueDateCompleted,
stopwatch,
isSubscribed,
isActivitiesFetching,
+2 -1
View File
@@ -6,12 +6,13 @@ import entryActions from '../entry-actions';
import Projects from '../components/Projects';
const mapStateToProps = (state) => {
const { allowAllToCreateProjects } = selectors.selectConfig(state);
const { isAdmin } = selectors.selectCurrentUser(state);
const projects = selectors.selectProjectsForCurrentUser(state);
return {
items: projects,
canAdd: isAdmin,
canAdd: allowAllToCreateProjects || isAdmin,
};
};
+3 -3
View File
@@ -58,9 +58,9 @@ i18n
.use(initReactI18next)
.init({
resources: embeddedLocales,
fallbackLng: 'en',
fallbackLng: 'en-US',
supportedLngs: languages,
load: 'languageOnly',
load: 'currentOnly',
interpolation: {
escapeValue: false,
format(value, format, language) {
@@ -80,7 +80,7 @@ i18n
});
i18n.loadCoreLocale = async (language = i18n.resolvedLanguage) => {
if (language === 'en') {
if (language === i18n.options.fallbackLng[0]) {
return;
}
@@ -64,7 +64,7 @@
.markdown-body b,
.markdown-body strong {
font-weight: 600;
font-weight: bold; // 600
}
.markdown-body dfn {
@@ -73,7 +73,7 @@
.markdown-body h1 {
margin: .67em 0;
font-weight: 600;
font-weight: bold; // 600
padding-bottom: .3em;
font-size: 2em;
border-bottom: 1px solid hsla(210, 18%, 87%, 1);
@@ -253,34 +253,34 @@
.markdown-body h6 {
margin-top: 24px;
margin-bottom: 16px;
font-weight: 600;
font-weight: bold; // 600
line-height: 1.25;
}
.markdown-body h2 {
font-weight: 600;
font-weight: bold; // 600
padding-bottom: .3em;
font-size: 1.5em;
border-bottom: 1px solid hsla(210, 18%, 87%, 1);
}
.markdown-body h3 {
font-weight: 600;
font-weight: bold; // 600
font-size: 1.25em;
}
.markdown-body h4 {
font-weight: 600;
font-weight: bold; // 600
font-size: 1em;
}
.markdown-body h5 {
font-weight: 600;
font-weight: bold; // 600
font-size: .875em;
}
.markdown-body h6 {
font-weight: 600;
font-weight: bold; // 600
font-size: .85em;
color: #57606a;
}
@@ -481,7 +481,7 @@
font-family: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 1em;
font-style: normal !important;
font-weight: 400;
font-weight: normal; // 400
line-height: 1;
vertical-align: -0.075em;
}
@@ -650,7 +650,7 @@
margin-top: 16px;
font-size: 1em;
font-style: italic;
font-weight: 600;
font-weight: bold; // 600
}
.markdown-body dl dd {
@@ -659,7 +659,7 @@
}
.markdown-body table th {
font-weight: 600;
font-weight: bold; // 600
}
.markdown-body table th,
@@ -868,7 +868,7 @@
}
.markdown-body .csv-data th {
font-weight: 600;
font-weight: bold; // 600
background: #f6f8fa;
border-top: 0;
}
@@ -912,7 +912,7 @@
}
.markdown-body .task-list-item label {
font-weight: 400;
font-weight: normal;
}
.markdown-body .task-list-item.enabled label {
+2568 -2729
View File
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'bg',
language: 'bg-BG',
country: 'bg',
name: 'Български',
embeddedLocale: login,
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'cs',
language: 'cs-CZ',
country: 'cz',
name: 'Čeština',
embeddedLocale: login,
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'da',
language: 'da-DK',
country: 'dk',
name: 'Dansk',
embeddedLocale: login,
@@ -104,6 +104,7 @@ export default {
language: 'Sprache',
leaveBoard_title: 'Board verlassen',
leaveProject_title: 'Projekt verlassen',
linkIsCopied: 'Link kopiert',
list: 'Listen',
listActions_title: 'Aufgaben auflisten',
managers: 'Manager',
@@ -169,6 +170,7 @@ export default {
addTask: 'Aufgabe hinzufügen',
addToCard: 'Zu Karte hinzufügen',
addUser: 'Benutzer hinzufügen',
copyLink_title: 'Link kopieren',
createBoard: 'Board erstellen',
createFile: 'Datei erstellen',
createLabel: 'Label erstellen',
@@ -190,6 +192,8 @@ export default {
deleteTask: 'Aufgabe löschen',
deleteTask_title: 'Aufgabe löschen',
deleteUser: 'Benutzer löschen',
duplicate: 'Kopieren',
duplicateCard_title: 'Karte kopieren',
edit: 'Bearbeiten',
editDueDate_title: 'Fälligkeitsdatum bearbeiten',
editDescription_title: 'Beschreibung ändern',
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'de',
language: 'de-DE',
country: 'de',
name: 'Deutsch',
embeddedLocale: login,

Some files were not shown because too many files have changed in this diff Show More