Compare commits

..
26 Commits
Author SHA1 Message Date
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
116 changed files with 856 additions and 174 deletions
+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.34
version: 0.2.5
# 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.18.0"
appVersion: "1.20.1"
dependencies:
- alias: postgresql
+22 -2
View File
@@ -90,17 +90,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 -1
View File
@@ -1 +1 @@
REACT_APP_VERSION=1.18.0
REACT_APP_VERSION=1.20.1
+12 -12
View File
@@ -12,7 +12,7 @@
"dequal": "^2.0.3",
"easymde": "^2.18.0",
"history": "^5.3.0",
"i18next": "^23.11.5",
"i18next": "^23.12.2",
"i18next-browser-languagedetector": "^8.0.0",
"initials": "^3.1.2",
"js-cookie": "^3.0.5",
@@ -30,7 +30,7 @@
"react-datepicker": "^4.25.0",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-i18next": "^14.1.2",
"react-i18next": "^15.0.0",
"react-input-mask": "^2.0.4",
"react-markdown": "^8.0.7",
"react-photoswipe-gallery": "^2.2.7",
@@ -2007,9 +2007,9 @@
"integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA=="
},
"node_modules/@babel/runtime": {
"version": "7.24.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.6.tgz",
"integrity": "sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==",
"version": "7.24.8",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz",
"integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -11975,9 +11975,9 @@
}
},
"node_modules/i18next": {
"version": "23.11.5",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.5.tgz",
"integrity": "sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==",
"version": "23.12.2",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-23.12.2.tgz",
"integrity": "sha512-XIeh5V+bi8SJSWGL3jqbTEBW5oD6rbP5L+E7dVQh1MNTxxYef0x15rhJVcRb7oiuq4jLtgy2SD8eFlf6P2cmqg==",
"funding": [
{
"type": "individual",
@@ -22084,11 +22084,11 @@
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
},
"node_modules/react-i18next": {
"version": "14.1.2",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.2.tgz",
"integrity": "sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg==",
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.0.0.tgz",
"integrity": "sha512-2O3IgF4zivg57Q6p6i+ChDgJ371IDcEWbuWC6gvoh5NbkDMs0Q+O7RPr4v61+Se32E0V+LmtwePAeqWZW0bi6g==",
"dependencies": {
"@babel/runtime": "^7.23.9",
"@babel/runtime": "^7.24.8",
"html-parse-stringify": "^3.0.1"
},
"peerDependencies": {
+2 -2
View File
@@ -65,7 +65,7 @@
"dequal": "^2.0.3",
"easymde": "^2.18.0",
"history": "^5.3.0",
"i18next": "^23.11.5",
"i18next": "^23.12.2",
"i18next-browser-languagedetector": "^8.0.0",
"initials": "^3.1.2",
"js-cookie": "^3.0.5",
@@ -83,7 +83,7 @@
"react-datepicker": "^4.25.0",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-i18next": "^14.1.2",
"react-i18next": "^15.0.0",
"react-input-mask": "^2.0.4",
"react-markdown": "^8.0.7",
"react-photoswipe-gallery": "^2.2.7",
+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,
},
});
+18 -1
View File
@@ -1,4 +1,4 @@
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';
@@ -81,6 +81,7 @@ const CardModal = React.memo(
onClose,
}) => {
const [t] = useTranslation();
const [isLinkCopied, setIsLinkCopied] = useState(false);
const isGalleryOpened = useRef(false);
@@ -146,6 +147,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;
}, []);
@@ -506,6 +515,14 @@ const CardModal = React.memo(
<Icon name="copy outline" className={styles.actionIcon} />
{t('action.duplicate')}
</Button>
<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"
@@ -20,7 +20,6 @@
.actionIcon {
color: #17394d;
display: inline;
margin-right: 8px;
}
-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',
+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;
}
@@ -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,
@@ -106,6 +106,7 @@ export default {
language: 'Language',
leaveBoard_title: 'Leave Board',
leaveProject_title: 'Leave Project',
linkIsCopied: 'Link is copied',
list: 'List',
listActions_title: 'List Actions',
managers: 'Managers',
@@ -183,6 +184,7 @@ export default {
addTask: 'Add task',
addToCard: 'Add to card',
addUser: 'Add user',
copyLink_title: 'Copy Link',
createBoard: 'Create board',
createFile: 'Create file',
createLabel: 'Create label',
@@ -4,8 +4,8 @@ import login from './login';
import core from './core';
export default {
language: 'en',
country: 'gb',
language: 'en-US',
country: 'us',
name: 'English',
embeddedLocale: merge(login, core),
};
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'es',
language: 'es-ES',
country: 'es',
name: 'Español',
embeddedLocale: login,
+254
View File
@@ -0,0 +1,254 @@
import dateFns from 'date-fns/locale/fa-IR';
export default {
dateFns,
format: {
date: 'M/d/yyyy',
time: 'p',
dateTime: '$t(format:date) $t(format:time)',
longDate: 'MMM d',
longDateTime: "MMMM d 'at' p",
fullDate: 'MMM d, y',
fullDateTime: "MMMM d, y 'at' p",
},
translation: {
common: {
aboutPlanka: 'درباره Planka',
account: 'حساب کاربری',
actions: 'اقدامات',
addAttachment_title: 'اضافه کردن پیوست',
addComment: 'اضافه کردن نظر',
addManager_title: 'اضافه کردن مدیر',
addMember_title: 'اضافه کردن عضو',
addUser_title: 'اضافه کردن کاربر',
administrator: 'مدیر سیستم',
all: 'همه',
allChangesWillBeAutomaticallySavedAfterConnectionRestored:
'تمام تغییرات به صورت خودکار ذخیره می‌شوند<br />بعد از بازیابی ارتباط.',
areYouSureYouWantToDeleteThisAttachment:
'آیا مطمئن هستید که می‌خواهید این پیوست را حذف کنید؟',
areYouSureYouWantToDeleteThisBoard: 'آیا مطمئن هستید که می‌خواهید این برد را حذف کنید؟',
areYouSureYouWantToDeleteThisCard: 'آیا مطمئن هستید که می‌خواهید این کارت را حذف کنید؟',
areYouSureYouWantToDeleteThisComment: 'آیا مطمئن هستید که می‌خواهید این نظر را حذف کنید؟',
areYouSureYouWantToDeleteThisLabel: 'آیا مطمئن هستید که می‌خواهید این برچسب را حذف کنید؟',
areYouSureYouWantToDeleteThisList: 'آیا مطمئن هستید که می‌خواهید این لیست را حذف کنید؟',
areYouSureYouWantToDeleteThisProject: 'آیا مطمئن هستید که می‌خواهید این پروژه را حذف کنید؟',
areYouSureYouWantToDeleteThisTask: 'آیا مطمئن هستید که می‌خواهید این وظیفه را حذف کنید؟',
areYouSureYouWantToDeleteThisUser: 'آیا مطمئن هستید که می‌خواهید این کاربر را حذف کنید؟',
areYouSureYouWantToLeaveBoard: 'آیا مطمئن هستید که می‌خواهید از برد خارج شوید؟',
areYouSureYouWantToLeaveProject: 'آیا مطمئن هستید که می‌خواهید از پروژه خارج شوید؟',
areYouSureYouWantToRemoveThisManagerFromProject:
'آیا مطمئن هستید که می‌خواهید این مدیر را از پروژه حذف کنید؟',
areYouSureYouWantToRemoveThisMemberFromBoard:
'آیا مطمئن هستید که می‌خواهید این عضو را از برد حذف کنید؟',
attachment: 'پیوست',
attachments: 'پیوست‌ها',
authentication: 'احراز هویت',
background: 'پس‌زمینه',
board: 'برد',
boardNotFound_title: 'برد یافت نشد',
canComment: 'می‌تواند نظر بدهد',
canEditContentOfBoard: 'می‌تواند محتوای برد را ویرایش کند.',
canOnlyViewBoard: 'فقط می‌تواند برد را مشاهده کند.',
cardActions_title: 'اقدامات کارت',
cardNotFound_title: 'کارت یافت نشد',
cardOrActionAreDeleted: 'کارت یا اقدام حذف شده‌اند.',
color: 'رنگ',
copy_inline: 'کپی',
createBoard_title: 'ایجاد برد',
createLabel_title: 'ایجاد برچسب',
createNewOneOrSelectExistingOne: 'یک جدید ایجاد کنید یا<br />یکی موجود را انتخاب کنید.',
createProject_title: 'ایجاد پروژه',
createTextFile_title: 'ایجاد فایل متنی',
currentPassword: 'رمز عبور فعلی',
dangerZone_title: 'منطقه خطر',
date: 'تاریخ',
dueDate: 'تاریخ سررسید',
dueDate_title: 'تاریخ سررسید',
deleteAttachment_title: 'حذف پیوست',
deleteBoard_title: 'حذف برد',
deleteCard_title: 'حذف کارت',
deleteComment_title: 'حذف نظر',
deleteLabel_title: 'حذف برچسب',
deleteList_title: 'حذف لیست',
deleteProject_title: 'حذف پروژه',
deleteTask_title: 'حذف وظیفه',
deleteUser_title: 'حذف کاربر',
description: 'توضیحات',
detectAutomatically: 'تشخیص خودکار',
dropFileToUpload: 'فایل را برای آپلود بکشید',
editor: 'ویرایشگر',
editAttachment_title: 'ویرایش پیوست',
editAvatar_title: 'ویرایش آواتار',
editBoard_title: 'ویرایش برد',
editDueDate_title: 'ویرایش تاریخ سررسید',
editEmail_title: 'ویرایش ایمیل',
editInformation_title: 'ویرایش اطلاعات',
editLabel_title: 'ویرایش برچسب',
editPassword_title: 'ویرایش رمز عبور',
editPermissions_title: 'ویرایش دسترسی‌ها',
editStopwatch_title: 'ویرایش کرنومتر',
editUsername_title: 'ویرایش نام کاربری',
email: 'ایمیل',
emailAlreadyInUse: 'ایمیل قبلا استفاده شده است',
enterCardTitle: 'عنوان کارت را وارد کنید... [Ctrl+Enter] برای باز شدن خودکار.',
enterDescription: 'توضیحات را وارد کنید...',
enterFilename: 'نام فایل را وارد کنید',
enterListTitle: 'عنوان لیست را وارد کنید...',
enterProjectTitle: 'عنوان پروژه را وارد کنید',
enterTaskDescription: 'توضیحات وظیفه را وارد کنید...',
filterByLabels_title: 'فیلتر بر اساس برچسب‌ها',
filterByMembers_title: 'فیلتر بر اساس اعضا',
fromComputer_title: 'از کامپیوتر',
fromTrello: 'از Trello',
general: 'عمومی',
hours: 'ساعت‌ها',
importBoard_title: 'وارد کردن برد',
invalidCurrentPassword: 'رمز عبور فعلی نامعتبر است',
labels: 'برچسب‌ها',
language: 'زبان',
leaveBoard_title: 'ترک برد',
leaveProject_title: 'ترک پروژه',
linkIsCopied: 'لینک کپی شد',
list: 'لیست',
listActions_title: 'اقدامات لیست',
managers: 'مدیران',
managerActions_title: 'اقدامات مدیر',
members: 'اعضا',
memberActions_title: 'اقدامات عضو',
minutes: 'دقیقه‌ها',
moveCard_title: 'انتقال کارت',
name: 'نام',
newestFirst: 'جدیدترین اول',
newEmail: 'ایمیل جدید',
newPassword: 'رمز عبور جدید',
newUsername: 'نام کاربری جدید',
noConnectionToServer: 'ارتباط با سرور قطع است',
noBoards: 'بردی وجود ندارد',
noLists: 'لیستی وجود ندارد',
noProjects: 'پروژه‌ای وجود ندارد',
notifications: 'اعلان‌ها',
noUnreadNotifications: 'اعلان خوانده نشده‌ای وجود ندارد.',
oldestFirst: 'قدیمی‌ترین اول',
openBoard_title: 'باز کردن برد',
optional_inline: 'اختیاری',
organization: 'سازمان',
phone: 'تلفن',
preferences: 'ترجیحات',
pressPasteShortcutToAddAttachmentFromClipboard:
'نکته: با فشردن Ctrl-V (Cmd-V در مک) می‌توانید پیوست را از کلیپ بورد اضافه کنید.',
project: 'پروژه',
projectNotFound_title: 'پروژه یافت نشد',
removeManager_title: 'حذف مدیر',
removeMember_title: 'حذف عضو',
searchLabels: 'جستجوی برچسب‌ها...',
searchMembers: 'جستجوی اعضا...',
searchUsers: 'جستجوی کاربران...',
searchCards: 'جستجوی کارت‌ها...',
seconds: 'ثانیه‌ها',
selectBoard: 'انتخاب برد',
selectList: 'انتخاب لیست',
selectPermissions_title: 'انتخاب دسترسی‌ها',
selectProject: 'انتخاب پروژه',
settings: 'تنظیمات',
sortList_title: 'مرتب‌سازی لیست',
stopwatch: 'کرنومتر',
subscribeToMyOwnCardsByDefault: 'به طور پیش‌فرض به کارت‌های خودم مشترک شوم',
taskActions_title: 'اقدامات وظیفه',
tasks: 'وظایف',
thereIsNoPreviewAvailableForThisAttachment: 'پیش نمایشی برای این پیوست موجود نیست.',
time: 'زمان',
title: 'عنوان',
userActions_title: 'اقدامات کاربر',
userAddedThisCardToList: '<0>{{user}}</0><1> این کارت را به {{list}} اضافه کرد</1>',
userLeftNewCommentToCard: '{{user}} نظر جدید «{{comment}}» را به <2>{{card}}</2> اضافه کرد',
userMovedCardFromListToList:
'{{user}} <2>{{card}}</2> را از {{fromList}} به {{toList}} منتقل کرد',
userMovedThisCardFromListToList:
'<0>{{user}}</0><1> این کارت را از {{fromList}} به {{toList}} منتقل کرد</1>',
username: 'نام کاربری',
usernameAlreadyInUse: 'نام کاربری قبلا استفاده شده است',
users: 'کاربران',
version: 'نسخه',
viewer: 'بیننده',
writeComment: 'نظر بنویسید...',
},
action: {
addAnotherCard: 'اضافه کردن کارت دیگر',
addAnotherList: 'اضافه کردن لیست دیگر',
addAnotherTask: 'اضافه کردن وظیفه دیگر',
addCard: 'اضافه کردن کارت',
addCard_title: 'اضافه کردن کارت',
addComment: 'اضافه کردن نظر',
addList: 'اضافه کردن لیست',
addMember: 'اضافه کردن عضو',
addMoreDetailedDescription: 'اضافه کردن توضیحات بیشتر',
addTask: 'اضافه کردن وظیفه',
addToCard: 'اضافه کردن به کارت',
addUser: 'اضافه کردن کاربر',
copyLink_title: 'کپی لینک',
createBoard: 'ایجاد برد',
createFile: 'ایجاد فایل',
createLabel: 'ایجاد برچسب',
createNewLabel: 'ایجاد برچسب جدید',
createProject: 'ایجاد پروژه',
delete: 'حذف',
deleteAttachment: 'حذف پیوست',
deleteAvatar: 'حذف آواتار',
deleteBoard: 'حذف برد',
deleteCard: 'حذف کارت',
deleteCard_title: 'حذف کارت',
deleteComment: 'حذف نظر',
deleteImage: 'حذف تصویر',
deleteLabel: 'حذف برچسب',
deleteList: 'حذف لیست',
deleteList_title: 'حذف لیست',
deleteProject: 'حذف پروژه',
deleteProject_title: 'حذف پروژه',
deleteTask: 'حذف وظیفه',
deleteTask_title: 'حذف وظیفه',
deleteUser: 'حذف کاربر',
duplicate: 'تکرار',
duplicateCard_title: 'تکرار کارت',
edit: 'ویرایش',
editDueDate_title: 'ویرایش تاریخ سررسید',
editDescription_title: 'ویرایش توضیحات',
editEmail_title: 'ویرایش ایمیل',
editInformation_title: 'ویرایش اطلاعات',
editPassword_title: 'ویرایش رمز عبور',
editPermissions: 'ویرایش دسترسی‌ها',
editStopwatch_title: 'ویرایش کرنومتر',
editTitle_title: 'ویرایش عنوان',
editUsername_title: 'ویرایش نام کاربری',
hideDetails: 'پنهان کردن جزئیات',
import: 'وارد کردن',
leaveBoard: 'ترک برد',
leaveProject: 'ترک پروژه',
logOut_title: 'خروج',
makeCover_title: 'ایجاد کاور',
move: 'انتقال',
moveCard_title: 'انتقال کارت',
remove: 'حذف',
removeBackground: 'حذف پس‌زمینه',
removeCover_title: 'حذف کاور',
removeFromBoard: 'حذف از برد',
removeFromProject: 'حذف از پروژه',
removeManager: 'حذف مدیر',
removeMember: 'حذف عضو',
save: 'ذخیره',
showAllAttachments: 'نمایش همه پیوست‌ها ({{hidden}} مخفی)',
showDetails: 'نمایش جزئیات',
showFewerAttachments: 'نمایش کمتر پیوست‌ها',
sortList_title: 'مرتب‌سازی لیست',
start: 'شروع',
stop: 'توقف',
subscribe: 'مشترک شدن',
unsubscribe: 'لغو اشتراک',
uploadNewAvatar: 'آپلود آواتار جدید',
uploadNewImage: 'آپلود تصویر جدید',
},
},
};
+8
View File
@@ -0,0 +1,8 @@
import login from './login';
export default {
language: 'fa-IR',
country: 'ir',
name: 'فارسی',
embeddedLocale: login,
};
+22
View File
@@ -0,0 +1,22 @@
export default {
translation: {
common: {
emailOrUsername: 'ایمیل یا نام کاربری',
invalidEmailOrUsername: 'ایمیل یا نام کاربری نامعتبر است',
invalidPassword: 'رمز عبور نامعتبر است',
logInToPlanka: 'ورود به Planka',
noInternetConnection: 'بدون اتصال به اینترنت',
pageNotFound_title: 'صفحه یافت نشد',
password: 'رمز عبور',
projectManagement: 'مدیریت پروژه',
serverConnectionFailed: 'اتصال به سرور ناموفق بود',
unknownError: 'خطای ناشناخته، بعداً دوباره تلاش کنید',
useSingleSignOn: 'استفاده از ورود یکپارچه',
},
action: {
logIn: 'ورود',
logInWithSSO: 'ورود با SSO',
},
},
};
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'fr',
language: 'fr-FR',
country: 'fr',
name: 'Français',
embeddedLocale: login,
@@ -15,6 +15,16 @@ export default {
translation: {
common: {
aboutPlanka: 'Plankáról',
account: 'Fiók',
actions: 'Műveletek',
addAttachment_title: 'Melléklet hozzáadása',
addComment: 'Megjegyzés hozzáadása',
addManager_title: 'Menedzser hozzáadása',
addMember_title: 'Tag létrehozása',
addUser_title: 'Felhasználó hozzáadása',
administrator: 'Rendszergazda',
all: 'Összes',
allChangesWillBeAutomaticallySavedAfterConnectionRestored:
'Az összes változás automatikusan mentésre kerül a kapcsolat helyreállása után.',
areYouSureYouWantToDeleteThisAttachment: 'Biztosan törölni szeretné ezt a mellékletet?',
@@ -29,7 +39,7 @@ export default {
areYouSureYouWantToLeaveBoard: 'Biztosan el akarja hagyni a táblát?',
areYouSureYouWantToLeaveProject: 'Biztosan el akarja hagyni a projektet?',
areYouSureYouWantToRemoveThisManagerFromProject:
'Biztosan eltávolítja ezt a vezetőt a projektből?',
'Biztosan eltávolítja ezt a menedzsert a projektből?',
areYouSureYouWantToRemoveThisMemberFromBoard: 'Biztosan eltávolítja ezt a tagot a tábláról?',
attachment: 'Melléklet',
attachments: 'Mellékletek',
@@ -44,6 +54,7 @@ export default {
cardNotFound_title: 'Kártya nem található',
cardOrActionAreDeleted: 'A kártya vagy művelet törölve lett.',
color: 'Szín',
copy_inline: 'másolás',
createBoard_title: 'Tábla létrehozása',
createLabel_title: 'Címke létrehozása',
createNewOneOrSelectExistingOne: 'Hozzon létre egy újat, vagy válasszon ki egy meglévőt.',
@@ -52,6 +63,7 @@ export default {
currentPassword: 'Jelenlegi jelszó',
dangerZone_title: 'Veszélyzóna',
date: 'Dátum',
dueDate: 'Határidő',
dueDate_title: 'Esedékesség dátuma',
deleteAttachment_title: 'Melléklet törlése',
deleteBoard_title: 'Tábla törlése',
@@ -97,13 +109,17 @@ export default {
language: 'Nyelv',
leaveBoard_title: 'Tábla elhagyása',
leaveProject_title: 'Projekt elhagyása',
linkIsCopied: 'Link másolva',
list: 'Lista',
listActions_title: 'Lista műveletek',
managers: 'Vezetők',
managers: 'Menedzserek',
managerActions_title: 'Menedzseri műveletek',
members: 'Tagok',
memberActions_title: 'Tag műveletek',
minutes: 'Percek',
moveCard_title: 'Kártya áthelyezése',
name: 'Név',
newestFirst: 'Újabbak előre',
newEmail: 'Új e-mail',
newPassword: 'Új jelszó',
newUsername: 'Új felhasználónév',
@@ -113,6 +129,7 @@ export default {
noProjects: 'Nincsenek projektek',
notifications: 'Értesítések',
noUnreadNotifications: 'Nincsenek olvasatlan értesítések.',
oldestFirst: 'Régebbi előre',
openBoard_title: 'Tábla megnyitása',
optional_inline: 'opcionális',
organization: 'Szervezet',
@@ -122,17 +139,19 @@ export default {
'Tipp: nyomja meg a Ctrl-V (Cmd-V a Mac-en) billentyűkombinációt a vágólapról történő melléklet hozzáadásához.',
project: 'Projekt',
projectNotFound_title: 'Projekt nem található',
removeManager_title: 'Vezető eltávolítása',
removeManager_title: 'Menedzser eltávolítása',
removeMember_title: 'Tag eltávolítása',
searchLabels: 'Címkék keresése...',
searchMembers: 'Tagok keresése...',
searchUsers: 'Felhasználók keresése...',
searchCards: 'Kártyák keresése..',
seconds: 'Másodpercek',
selectBoard: 'Válassza ki a táblát',
selectList: 'Válassza ki a listát',
selectPermissions_title: 'Jogosultságok kiválasztása',
selectProject: 'Válassza ki a projektet',
settings: 'Beállítások',
sortList_title: 'Rendezés listában',
stopwatch: 'Stopper',
subscribeToMyOwnCardsByDefault: 'Alapértelmezés szerint feliratkozás a saját kártyáimra',
taskActions_title: 'Feladat műveletek',
@@ -170,6 +189,7 @@ export default {
addTask: 'Feladat hozzáadása',
addToCard: 'Kártyához hozzáadása',
addUser: 'Felhasználó hozzáadása',
copyLink_title: 'Link másolása',
createBoard: 'Tábla létrehozása',
createFile: 'Fájl létrehozása',
createLabel: 'Címke létrehozása',
@@ -191,6 +211,8 @@ export default {
deleteTask: 'Feladat törlése',
deleteTask_title: 'Feladat törlése',
deleteUser: 'Felhasználó törlése',
duplicate: 'Másolás',
duplicateCard_title: 'Kártya másolása',
edit: 'Szerkesztés',
editDueDate_title: 'Esedékesség dátumának szerkesztése',
editDescription_title: 'Leírás szerkesztése',
@@ -214,12 +236,13 @@ export default {
removeCover_title: 'Borító eltávolítása',
removeFromBoard: 'Eltávolítás a tábláról',
removeFromProject: 'Eltávolítás a projektről',
removeManager: 'Vezető eltávolítása',
removeManager: 'Menedzser eltávolítása',
removeMember: 'Tag eltávolítása',
save: 'Mentés',
showAllAttachments: 'Összes melléklet megjelenítése ({{hidden}} rejtve)',
showDetails: 'Részletek megjelenítése',
showFewerAttachments: 'Kevesebb melléklet megjelenítése',
sortList_title: 'Rendezés listában',
start: 'Indítás',
stop: 'Megállítás',
subscribe: 'Feliratkozás',
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'hu',
language: 'hu-HU',
country: 'hu',
name: 'Magyar',
embeddedLocale: login,
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'id',
language: 'id-ID',
country: 'id',
name: 'Bahasa Indonesia',
embeddedLocale: login,
+48 -46
View File
@@ -1,51 +1,53 @@
import bg from './bg';
import cs from './cs';
import da from './da';
import de from './de';
import en from './en';
import es from './es';
import fr from './fr';
import hu from './hu';
import id from './id';
import it from './it';
import ja from './ja';
import ko from './ko';
import nl from './nl';
import pl from './pl';
import pt from './pt';
import ro from './ro';
import ru from './ru';
import sk from './sk';
import sv from './sv';
import tr from './tr';
import ua from './ua';
import uz from './uz';
import zh from './zh';
import bgBG from './bg-BG';
import csCZ from './cs-CZ';
import daDK from './da-DK';
import deDE from './de-DE';
import enUS from './en-US';
import esES from './es-ES';
import faIR from './fa-IR';
import frFR from './fr-FR';
import huHU from './hu-HU';
import idID from './id-ID';
import itIT from './it-IT';
import jaJP from './ja-JP';
import koKR from './ko-KR';
import nlNL from './nl-NL';
import plPL from './pl-PL';
import ptBR from './pt-BR';
import roRO from './ro-RO';
import ruRU from './ru-RU';
import skSK from './sk-SK';
import svSE from './sv-SE';
import trTR from './tr-TR';
import ukUA from './uk-UA';
import uzUZ from './uz-UZ';
import zhCN from './zh-CN';
const locales = [
bg,
cs,
da,
de,
en,
es,
fr,
hu,
id,
it,
ja,
ko,
nl,
pl,
pt,
ro,
ru,
sk,
sv,
tr,
ua,
uz,
zh,
bgBG,
csCZ,
daDK,
deDE,
enUS,
esES,
faIR,
frFR,
huHU,
idID,
itIT,
jaJP,
koKR,
nlNL,
plPL,
ptBR,
roRO,
ruRU,
skSK,
svSE,
trTR,
ukUA,
uzUZ,
zhCN,
];
export default locales;
@@ -1,4 +1,8 @@
import dateFns from 'date-fns/locale/it';
export default {
dateFns,
format: {
date: 'd/M/yyyy',
time: 'p',
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'it',
language: 'it-IT',
country: 'it',
name: 'Italiano',
embeddedLocale: login,
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'ja',
language: 'ja-JP',
country: 'jp',
name: '日本語',
embeddedLocale: login,
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'ko',
language: 'ko-KR',
country: 'kr',
name: '한국어',
embeddedLocale: login,
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'nl',
language: 'nl-NL',
country: 'nl',
name: 'Nederlands',
embeddedLocale: login,
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'pl',
language: 'pl-PL',
country: 'pl',
name: 'Polski',
embeddedLocale: login,
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'pt',
language: 'pt-BR',
country: 'br',
name: 'Português',
embeddedLocale: login,
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'ro',
language: 'ro-RO',
country: 'ro',
name: 'Română',
embeddedLocale: login,
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'ru',
language: 'ru-RU',
country: 'ru',
name: 'Русский',
embeddedLocale: login,
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'sk',
language: 'sk-SK',
country: 'sk',
name: 'Slovenčina',
embeddedLocale: login,
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'sv',
language: 'sv-SE',
country: 'se',
name: 'Svenska',
embeddedLocale: login,
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'tr',
language: 'tr-TR',
country: 'tr',
name: 'Türkçe',
embeddedLocale: login,
@@ -1,4 +1,8 @@
import dateFns from 'date-fns/locale/uk';
export default {
dateFns,
format: {
date: 'd/M/yyyy',
time: 'p',
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'ua',
language: 'uk-UA',
country: 'ua',
name: 'Українська',
embeddedLocale: login,
@@ -1,4 +1,8 @@
import dateFns from 'date-fns/locale/uz';
export default {
dateFns,
format: {
date: 'M/d/yyyy',
time: 'p',
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'uz',
language: 'uz-UZ',
country: 'uz',
name: "O'zbek",
embeddedLocale: login,
@@ -1,4 +1,8 @@
import dateFns from 'date-fns/locale/zh-CN';
export default {
dateFns,
format: {
date: 'M/d/yyyy',
time: 'p',
@@ -1,7 +1,7 @@
import login from './login';
export default {
language: 'zh',
language: 'zh-CN',
country: 'cn',
name: '中文',
embeddedLocale: login,
+1
View File
@@ -28,6 +28,7 @@ export default class extends BaseModel {
case ActionTypes.CORE_INITIALIZE:
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE:
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE:
case ActionTypes.CARD_UPDATE_HANDLE:
if (payload.attachments) {
payload.attachments.forEach((attachment) => {
Attachment.upsert(attachment);
+7 -4
View File
@@ -1,3 +1,4 @@
import orderBy from 'lodash/orderBy';
import { attr, fk, many } from 'redux-orm';
import BaseModel from './BaseModel';
@@ -218,10 +219,6 @@ export default class extends BaseModel {
}
}
getOrderedMembershipsQuerySet() {
return this.memberships.orderBy('createdAt');
}
getOrderedLabelsQuerySet() {
return this.labels.orderBy('position');
}
@@ -230,6 +227,12 @@ export default class extends BaseModel {
return this.lists.orderBy('position');
}
getOrderedMembershipsModelArray() {
return orderBy(this.memberships.toModelArray(), (boardMembershipModel) =>
boardMembershipModel.user.name.toLocaleLowerCase(),
);
}
getMembershipModelForUser(userId) {
return this.memberships
.filter({
+34 -3
View File
@@ -180,7 +180,6 @@ export default class extends BaseModel {
break;
case ActionTypes.CARD_CREATE:
case ActionTypes.CARD_UPDATE__SUCCESS:
case ActionTypes.CARD_UPDATE_HANDLE:
Card.upsert(payload.card);
break;
@@ -202,8 +201,40 @@ export default class extends BaseModel {
break;
}
case ActionTypes.CARD_UPDATE:
Card.withId(payload.id).update(payload.data);
case ActionTypes.CARD_UPDATE: {
const cardModel = Card.withId(payload.id);
// TODO: introduce separate action?
if (payload.data.boardId && payload.data.boardId !== cardModel.boardId) {
cardModel.deleteWithRelated();
} else {
cardModel.update(payload.data);
}
break;
}
case ActionTypes.CARD_UPDATE_HANDLE:
if (payload.isFetched) {
const cardModel = Card.withId(payload.card.id);
if (cardModel) {
cardModel.deleteWithRelated();
}
}
Card.upsert(payload.card);
if (payload.cardMemberships) {
payload.cardMemberships.forEach(({ cardId, userId }) => {
Card.withId(cardId).users.add(userId);
});
}
if (payload.cardLabels) {
payload.cardLabels.forEach(({ cardId, labelId }) => {
Card.withId(cardId).labels.add(labelId);
});
}
break;
case ActionTypes.CARD_DUPLICATE: {
+1
View File
@@ -27,6 +27,7 @@ export default class extends BaseModel {
case ActionTypes.CORE_INITIALIZE:
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE:
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE:
case ActionTypes.CARD_UPDATE_HANDLE:
if (payload.tasks) {
payload.tasks.forEach((task) => {
Task.upsert(task);
+1 -1
View File
@@ -298,7 +298,7 @@ export default class extends BaseModel {
static getOrderedUndeletedQuerySet() {
return this.filter({
deletedAt: null,
}).orderBy('createdAt');
}).orderBy((user) => user.name.toLocaleLowerCase());
}
getOrderedProjectManagersQuerySet() {
+23 -2
View File
@@ -81,9 +81,30 @@ export function* updateCurrentCard(data) {
yield call(updateCard, cardId, data);
}
// TODO: handle card transfer
export function* handleCardUpdate(card) {
yield put(actions.handleCardUpdate(card));
let fetch = false;
if (card.boardId) {
const prevCard = yield select(selectors.selectCardById, card.id);
fetch = !prevCard || prevCard.boardId !== card.boardId;
}
let cardMemberships;
let cardLabels;
let tasks;
let attachments;
if (fetch) {
try {
({
item: card, // eslint-disable-line no-param-reassign
included: { cardMemberships, cardLabels, tasks, attachments },
} = yield call(request, api.getCard, card.id));
} catch (error) {
fetch = false;
}
}
yield put(actions.handleCardUpdate(card, fetch, cardMemberships, cardLabels, tasks, attachments));
}
export function* moveCard(id, listId, index = 0) {
+8 -11
View File
@@ -55,17 +55,14 @@ export const selectMembershipsForCurrentBoard = createSelector(
return boardModel;
}
return boardModel
.getOrderedMembershipsQuerySet()
.toModelArray()
.map((boardMembershipModel) => ({
...boardMembershipModel.ref,
isPersisted: !isLocalId(boardMembershipModel.id),
user: {
...boardMembershipModel.user.ref,
isCurrent: boardMembershipModel.user.id === currentUserId,
},
}));
return boardModel.getOrderedMembershipsModelArray().map((boardMembershipModel) => ({
...boardMembershipModel.ref,
isPersisted: !isLocalId(boardMembershipModel.id),
user: {
...boardMembershipModel.user.ref,
isCurrent: boardMembershipModel.user.id === currentUserId,
},
}));
},
);
+9 -4
View File
@@ -1,7 +1,6 @@
version: '3.8'
services:
server:
build:
context: ./server
@@ -13,6 +12,7 @@ services:
- NODE_ENV=development
- DATABASE_URL=postgresql://user:password@postgres:5432/planka_db
- SECRET_KEY=notsecretkey
# - TRUST_PROXY=0
# - TOKEN_EXPIRES_IN=365 # In days
@@ -23,10 +23,17 @@ services:
# Configure knex to accept SSL certificates
# - KNEX_REJECT_UNAUTHORIZED_SSL_CERTIFICATE=false
# - ALLOW_ALL_TO_CREATE_PROJECTS=true
# - OIDC_ISSUER=
# - OIDC_CLIENT_ID=
# - OIDC_CLIENT_SECRET=
# - OIDC_ID_TOKEN_SIGNED_RESPONSE_ALG=
# - OIDC_USERINFO_SIGNED_RESPONSE_ALG=
# - OIDC_SCOPES=openid email profile
# - OIDC_RESPONSE_MODE=fragment
# - OIDC_USE_DEFAULT_RESPONSE_MODE=true
# - OIDC_ADMIN_ROLES=admin
# - OIDC_EMAIL_ATTRIBUTE=email
# - OIDC_NAME_ATTRIBUTE=name
@@ -56,7 +63,6 @@ services:
# - SLACK_BOT_TOKEN=
# - SLACK_CHANNEL_ID=
working_dir: /app
command: ["sh", "-c", "npm run start"]
depends_on:
@@ -85,11 +91,11 @@ services:
dockerfile: ../config/development/Dockerfile.server
environment:
- DATABASE_URL=postgresql://user:password@postgres:5432/planka_db
# - DEFAULT_ADMIN_EMAIL=demo@demo.demo # Do not remove if you want to prevent this user from being edited/deleted
# - DEFAULT_ADMIN_PASSWORD=demo
# - DEFAULT_ADMIN_NAME=Demo Demo
# - DEFAULT_ADMIN_USERNAME=demo
working_dir: /app
command: ["sh", "-c", "npm run db:init"]
volumes:
@@ -126,6 +132,5 @@ services:
- server
- client
volumes:
db-data:
+6
View File
@@ -31,10 +31,16 @@ services:
# - DEFAULT_ADMIN_NAME=Demo Demo
# - DEFAULT_ADMIN_USERNAME=demo
# - ALLOW_ALL_TO_CREATE_PROJECTS=true
# - OIDC_ISSUER=
# - OIDC_CLIENT_ID=
# - OIDC_CLIENT_SECRET=
# - OIDC_ID_TOKEN_SIGNED_RESPONSE_ALG=
# - OIDC_USERINFO_SIGNED_RESPONSE_ALG=
# - OIDC_SCOPES=openid email profile
# - OIDC_RESPONSE_MODE=fragment
# - OIDC_USE_DEFAULT_RESPONSE_MODE=true
# - OIDC_ADMIN_ROLES=admin
# - OIDC_EMAIL_ATTRIBUTE=email
# - OIDC_NAME_ATTRIBUTE=name
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "planka",
"version": "1.18.0",
"version": "1.20.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "planka",
"version": "1.18.0",
"version": "1.20.1",
"hasInstallScript": true,
"license": "AGPL-3.0",
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "planka",
"version": "1.18.0",
"version": "1.20.1",
"private": true,
"homepage": "https://plankanban.github.io/planka",
"repository": {
+6
View File
@@ -22,10 +22,16 @@ SECRET_KEY=notsecretkey
# DEFAULT_ADMIN_NAME=Demo Demo
# DEFAULT_ADMIN_USERNAME=demo
# ALLOW_ALL_TO_CREATE_PROJECTS=true
# OIDC_ISSUER=
# OIDC_CLIENT_ID=
# OIDC_CLIENT_SECRET=
# OIDC_ID_TOKEN_SIGNED_RESPONSE_ALG=
# OIDC_USERINFO_SIGNED_RESPONSE_ALG=
# OIDC_SCOPES=openid email profile
# OIDC_RESPONSE_MODE=fragment
# OIDC_USE_DEFAULT_RESPONSE_MODE=true
# OIDC_ADMIN_ROLES=admin
# OIDC_EMAIL_ATTRIBUTE=email
# OIDC_NAME_ATTRIBUTE=name
@@ -4,6 +4,9 @@ const Errors = {
INVALID_CODE_OR_NONCE: {
invalidCodeOrNonce: 'Invalid code or nonce',
},
INVALID_USERINFO_SIGNATURE: {
invalidUserinfoSignature: 'Invalid signature on userinfo due to client misconfiguration',
},
EMAIL_ALREADY_IN_USE: {
emailAlreadyInUse: 'Email already in use',
},
@@ -31,6 +34,9 @@ module.exports = {
invalidCodeOrNonce: {
responseType: 'unauthorized',
},
invalidUserinfoSignature: {
responseType: 'unauthorized',
},
emailAlreadyInUse: {
responseType: 'conflict',
},
@@ -51,6 +57,7 @@ module.exports = {
sails.log.warn(`Invalid code or nonce! (IP: ${remoteAddress})`);
return Errors.INVALID_CODE_OR_NONCE;
})
.intercept('invalidUserinfoSignature', () => Errors.INVALID_USERINFO_SIGNATURE)
.intercept('emailAlreadyInUse', () => Errors.EMAIL_ALREADY_IN_USE)
.intercept('usernameAlreadyInUse', () => Errors.USERNAME_ALREADY_IN_USE)
.intercept('missingValues', () => Errors.MISSING_VALUES);
+16
View File
@@ -1,3 +1,9 @@
const Errors = {
NOT_ENOUGH_RIGHTS: {
notEnoughRights: 'Not enough rights',
},
};
module.exports = {
inputs: {
name: {
@@ -6,9 +12,19 @@ module.exports = {
},
},
exits: {
notEnoughRights: {
responseType: 'forbidden',
},
},
async fn(inputs) {
const { currentUser } = this.req;
if (!currentUser.isAdmin && !sails.config.custom.allowAllToCreateProjects) {
throw Errors.NOT_ENOUGH_RIGHTS;
}
const values = _.pick(inputs, ['name']);
const { project, projectManager } = await sails.helpers.projects.createOne.with({

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