diff --git a/client/src/app-components/department-dropdown.js b/client/src/app-components/department-dropdown.js index abc916b9..83d92110 100644 --- a/client/src/app-components/department-dropdown.js +++ b/client/src/app-components/department-dropdown.js @@ -11,21 +11,33 @@ class DepartmentDropdown extends React.Component { onChange: React.PropTypes.func, departments: React.PropTypes.array } - render(){ - return + + render() { + return } - getDepartments(){ + getDepartments() { let departments = this.props.departments.map((department) => { if(department.private*1) { return {content: {department.name} }; - }else{ + } else { return {content: department.name}; } }); return departments; } + + onChange(event) { + if(this.props.onChange) { + this.props.onChange({ + index: event.index, + target: { + value: event.index + } + }); + } + } } export default DepartmentDropdown; diff --git a/client/src/app-components/ticket-viewer.js b/client/src/app-components/ticket-viewer.js index 1f8245a6..90933a12 100644 --- a/client/src/app-components/ticket-viewer.js +++ b/client/src/app-components/ticket-viewer.js @@ -87,7 +87,7 @@ class TicketViewer extends React.Component { renderEditableHeaders() { const ticket = this.props.ticket; - const departments = (this.props.ticket.author.staff ? SessionStore.getDepartments() : this.getPublicDepartments() ); + const departments = this.getDepartmentsForTransfer(); const priorities = { 'low': 0, @@ -209,9 +209,10 @@ class TicketViewer extends React.Component { } renderTicketEvent(options, index) { - if (this.props.userStaff) { + if (this.props.userStaff && typeof options.content === 'string') { options.content = MentionsParser.parse(options.content); } + return ( ); @@ -305,6 +306,7 @@ class TicketViewer extends React.Component { } }; } + getPublicDepartments() { return _.filter(SessionStore.getDepartments(),d => !(d.private*1)); } @@ -352,6 +354,7 @@ class TicketViewer extends React.Component { event.preventDefault(); AreYouSure.openModal(null, this.closeTicket.bind(this)); } + onDeleteTicketClick(event) { event.preventDefault(); AreYouSure.openModal(null, this.deleteTicket.bind(this)); @@ -374,6 +377,7 @@ class TicketViewer extends React.Component { } }).then(this.onTicketModification.bind(this)); } + deleteTicket() { API.call({ path: '/ticket/delete', @@ -388,7 +392,7 @@ class TicketViewer extends React.Component { path: '/ticket/change-department', data: { ticketNumber: this.props.ticket.ticketNumber, - departmentId: SessionStore.getDepartments()[index].id + departmentId: this.getDepartmentsForTransfer()[index].id } }).then(this.onTicketModification.bind(this)); } @@ -485,6 +489,10 @@ class TicketViewer extends React.Component { return staffAssignmentItems; } + getDepartmentsForTransfer() { + return this.props.ticket.author.staff ? SessionStore.getDepartments() : this.getPublicDepartments(); + } + showDeleteButton() { if(!this.props.ticket.owner) { if(this.props.userLevel == 3) return true; diff --git a/client/src/app-components/topic-viewer.js b/client/src/app-components/topic-viewer.js index c1dd01fd..c6395491 100644 --- a/client/src/app-components/topic-viewer.js +++ b/client/src/app-components/topic-viewer.js @@ -131,7 +131,7 @@ class TopicViewer extends React.Component { title: this.props.name, icon: this.props.icon, iconColor: this.props.iconColor, - private: false + private: this.props.private * 1 } }; diff --git a/client/src/app/admin/panel/staff/admin-panel-departments.js b/client/src/app/admin/panel/staff/admin-panel-departments.js index 4c4664a8..0e093702 100644 --- a/client/src/app/admin/panel/staff/admin-panel-departments.js +++ b/client/src/app/admin/panel/staff/admin-panel-departments.js @@ -7,6 +7,7 @@ import API from 'lib-app/api-call'; import ConfigActions from 'actions/config-actions'; import AreYouSure from 'app-components/are-you-sure'; +import DepartmentDropDown from 'app-components/department-dropdown'; import InfoTooltip from 'core-components/info-tooltip'; import Button from 'core-components/button'; @@ -17,6 +18,7 @@ import FormField from 'core-components/form-field'; import SubmitButton from 'core-components/submit-button'; import DropDown from 'core-components/drop-down'; import Icon from 'core-components/icon'; +import Message from 'core-components/message'; class AdminPanelDepartments extends React.Component { static defaultProps = { @@ -28,10 +30,12 @@ class AdminPanelDepartments extends React.Component { selectedIndex: -1, selectedDropDownIndex: 0, edited: false, + errorMessage: null, errors: {}, form: { title: '', - language: 'en' + language: 'en', + private: 0, } }; @@ -44,11 +48,12 @@ class AdminPanelDepartments extends React.Component {
+ {(this.state.errorMessage) ? {i18n(this.state.errorMessage)} : null}
- +
@@ -88,11 +93,7 @@ class AdminPanelDepartments extends React.Component { {i18n('WILL_DELETE_DEPARTMENT')}
{i18n('TRANSFER_TICKETS_TO')} - index !== this.state.selectedIndex).map(department => { - return { - content: department.name - }; - })} onChange={(department, index) => this.setState({selectedDropDownIndex: index})} size="medium"/> + this.setState({selectedDropDownIndex: event.index})} size="medium"/>
); @@ -157,7 +158,7 @@ class AdminPanelDepartments extends React.Component { }).then(() => { this.setState({formLoading: false}); this.retrieveDepartments(); - }).catch(this.onItemChange.bind(this, -1)); + }).catch(result => this.setState({formLoading: false, errorMessage: result.message})); } else { API.call({ path: '/system/add-department', @@ -194,7 +195,8 @@ class AdminPanelDepartments extends React.Component { }).then(() => { this.retrieveDepartments(); this.onItemChange(-1); - }); + }) + .catch(result => this.setState({errorMessage: result.message})); } updateForm(index) { @@ -202,12 +204,14 @@ class AdminPanelDepartments extends React.Component { let department = this.getCurrentDepartment(index); form.name = (department && department.name) || ''; + form.private = (department && department.private) || 0; this.setState({ selectedIndex: index, edited: false, formLoading: false, - form: form, + form, + errorMessage: null, errors: {} }); } @@ -226,6 +230,10 @@ class AdminPanelDepartments extends React.Component { getDropDownItemId() { return this.props.departments.filter((department, index) => index !== this.state.selectedIndex)[this.state.selectedDropDownIndex].id; } + + getDropDownDepartments() { + return this.props.departments.filter((department, index) => index !== this.state.selectedIndex); + } } export default connect((store) => { diff --git a/client/src/app/admin/panel/staff/staff-editor.js b/client/src/app/admin/panel/staff/staff-editor.js index 51d4e54b..0a586eef 100644 --- a/client/src/app/admin/panel/staff/staff-editor.js +++ b/client/src/app/admin/panel/staff/staff-editor.js @@ -168,9 +168,9 @@ class StaffEditor extends React.Component { this.setState({level: form.level})} onSubmit={this.onSubmit.bind(this, 'LEVEL')}> + items: [{content: i18n('LEVEL_1')}, {content: i18n('LEVEL_2')}, {content: i18n('LEVEL_3')}], + size: 'large' + }} /> {i18n('UPDATE_LEVEL')} @@ -243,11 +243,11 @@ class StaffEditor extends React.Component { } getUserDepartments() { - let userDepartments = this.props.departments.map(department => department.name); + let userDepartments = this.props.departments.map(department => department.id); let departmentIndexes = []; - _.forEach(this.getDepartments(), (department, index) => { - if(_.includes(userDepartments, department)) { + _.forEach(SessionStore.getDepartments(), (department, index) => { + if(_.includes(userDepartments, department.id)) { departmentIndexes.push(index); } }); @@ -257,11 +257,11 @@ class StaffEditor extends React.Component { getDepartments() { return SessionStore.getDepartments().map(department => { - if(department.private*1){ - return {department.name} - }else { - return department.name; - } + if(department.private * 1){ + return {department.name} + } else { + return department.name; + } }); } diff --git a/client/src/data/languages/br.js b/client/src/data/languages/br.js index 59399e2b..7f52c4b1 100644 --- a/client/src/data/languages/br.js +++ b/client/src/data/languages/br.js @@ -307,6 +307,7 @@ export default { 'DISABLE_USER_DESCRIPTION': 'O usuário será desativado e não poderá fazer login e criar tickets.', 'PRIVATE_RESPONSE_DESCRIPTION': 'Esta resposta só será vista pelos funcionários', 'PRIVATE_TOPIC_DESCRIPTION': 'Este tópico será visto apenas por membros da equipe', + 'PRIVATE_DEPARTMENT_DESCRIPTION': 'Este departamento só será visto pelos funcionários', //ERRORS 'EMAIL_OR_PASSWORD': 'E-mail ou senha inválidos', @@ -338,6 +339,7 @@ export default { 'ERROR_IMAGE_SIZE': 'Nenhuma imagem pode ter um tamanho maior que {size} MB', 'USER_DISABLED': 'Esta conta está desativada.', 'INVALID_SYNTAX': 'Sintaxe inválida.', + 'DEPARTMENT_PRIVATE_TICKETS': 'Este departamento tem ingressos criados por não funcionários e não pode ser privado', //MESSAGES 'SIGNUP_SUCCESS': 'Você se registrou com sucesso em nosso sistema de suporte.', diff --git a/client/src/data/languages/cn.js b/client/src/data/languages/cn.js index a528b4a4..bc999163 100644 --- a/client/src/data/languages/cn.js +++ b/client/src/data/languages/cn.js @@ -307,6 +307,7 @@ export default { 'DISABLE_USER_DESCRIPTION': '用户将被禁用,无法登录并创建票证。', 'PRIVATE_RESPONSE_DESCRIPTION': '只有工作人员才能看到这种回应', 'PRIVATE_TOPIC_DESCRIPTION': '只有工作人员才能看到此主题', + 'PRIVATE_DEPARTMENT_DESCRIPTION': '只有工作人员才能看到这个部门', //ERRORS 'EMAIL_OR_PASSWORD': '電子郵件或密碼無效', @@ -338,6 +339,7 @@ export default { 'ERROR_IMAGE_SIZE': '没有图像的大小可以超过{size}MB', 'USER_DISABLED': '此帐户已被停用。', 'INVALID_SYNTAX': '无效的语法。', + 'DEPARTMENT_PRIVATE_TICKETS': '这个部门有非工作人员创建的门票,不能是私人的', //MESSAGES 'SIGNUP_SUCCESS': '您已在我們的支持系統中成功註冊', diff --git a/client/src/data/languages/de.js b/client/src/data/languages/de.js index 8a32229d..5e1cc8dc 100644 --- a/client/src/data/languages/de.js +++ b/client/src/data/languages/de.js @@ -307,6 +307,7 @@ export default { 'DISABLE_USER_DESCRIPTION': 'Der Benutzer wird deaktiviert und kann keine Tickets anmelden und erstellen.', 'PRIVATE_RESPONSE_DESCRIPTION': 'Diese Antwort wird nur von den Mitarbeitern gesehen werden', 'PRIVATE_TOPIC_DESCRIPTION': 'Dieses Thema wird nur von Mitarbeitern gesehen', + 'PRIVATE_DEPARTMENT_DESCRIPTION': 'Diese Abteilung wird nur von Mitarbeitern gesehen', //ERRORS 'EMAIL_OR_PASSWORD': 'E-Mail-Adresse oder Passwort ungültig!', @@ -338,6 +339,7 @@ export default { 'ERROR_IMAGE_SIZE': 'Kein Bild darf größer als {size} MB sein', 'USER_DISABLED': 'Dieser Account ist deaktiviert.', 'INVALID_SYNTAX': 'Ungültiger Satzbau.', + 'DEPARTMENT_PRIVATE_TICKETS': 'Diese Abteilung hat Tickets, die von Nicht-Mitarbeitern erstellt wurden, und kann nicht privat sein', //MESSAGES 'SIGNUP_SUCCESS': 'Sie haben sich erfolgreich in unserem Support-System registriert.', diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index 6e1d2c0b..ae727e3f 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -339,6 +339,7 @@ export default { 'ERROR_IMAGE_SIZE': 'No image can have a size greater than {size} MB', 'USER_DISABLED': 'This account is disabled.', 'INVALID_SYNTAX': 'Invalid syntax.', + 'DEPARTMENT_PRIVATE_TICKETS': 'This department has tickets created by non-staff and it can not be private', //MESSAGES 'SIGNUP_SUCCESS': 'You have registered successfully in our support system.', diff --git a/client/src/data/languages/es.js b/client/src/data/languages/es.js index 544ea62e..f0e205f3 100644 --- a/client/src/data/languages/es.js +++ b/client/src/data/languages/es.js @@ -307,6 +307,7 @@ export default { 'DISABLE_USER_DESCRIPTION': 'El usuario estará deshabilitado y no podrá iniciar sesión y crear tickets.', 'PRIVATE_RESPONSE_DESCRIPTION': 'Esta respuesta solo será vista por los miembros del personal.', 'PRIVATE_TOPIC_DESCRIPTION': 'Este tema solo será visto por los miembros del personal.', + 'PRIVATE_DEPARTMENT_DESCRIPTION': 'Este departamento solo será visto por miembros del personal.', //ERRORS 'EMAIL_OR_PASSWORD': 'Email o contraseña inválida', @@ -338,6 +339,7 @@ export default { 'USER_DISABLED': 'Esta cuenta está deshabilitada.', 'INVALID_SYNTAX': 'Sintaxis inválida.', + 'DEPARTMENT_PRIVATE_TICKETS': 'Este departamento tiene entradas creadas por personal no administrativo y no puede ser privado.', //MESSAGES 'SIGNUP_SUCCESS': 'Se ha registrado con éxito en nuestro sistema de soporte.', 'TICKET_SENT': 'El ticket se ha creado correctamente.', diff --git a/client/src/data/languages/fr.js b/client/src/data/languages/fr.js index d3f6a889..97a0587d 100644 --- a/client/src/data/languages/fr.js +++ b/client/src/data/languages/fr.js @@ -307,6 +307,7 @@ export default { 'DISABLE_USER_DESCRIPTION': 'L\'utilisateur sera désactivé et ne pourra pas se connecter et créer des tickets.', 'PRIVATE_RESPONSE_DESCRIPTION': 'Cette réponse ne sera vue que par les membres du personnel', 'PRIVATE_TOPIC_DESCRIPTION': 'Ce sujet ne sera vu que par les membres du personnel', + 'PRIVATE_DEPARTMENT_DESCRIPTION': 'Ce département ne sera vu que par les membres du personnel', //ERRORS 'EMAIL_OR_PASSWORD': 'E-mail ou mot de passe invalide', @@ -338,6 +339,7 @@ export default { 'ERROR_IMAGE_SIZE': 'Aucune image ne peut avoir une taille supérieure à {size} MB', 'USER_DISABLED': 'Ce compte est désactivé.', 'INVALID_SYNTAX': 'Syntaxe invalide.', + 'DEPARTMENT_PRIVATE_TICKETS': 'Ce service a des tickets créés par des non-membres du personnel et il ne peut pas être privé', //MESSAGES 'SIGNUP_SUCCESS': 'Vous êtes inscrit avec succès dans notre système de support.', diff --git a/client/src/data/languages/gr.js b/client/src/data/languages/gr.js index 8a23ae77..ebbc78c0 100644 --- a/client/src/data/languages/gr.js +++ b/client/src/data/languages/gr.js @@ -307,6 +307,7 @@ 'DISABLE_USER_DESCRIPTION': 'Ο χρήστης θα απενεργοποιηθεί και δεν θα μπορέσει να συνδεθεί και να δημιουργήσει εισιτήρια.', 'PRIVATE_RESPONSE_DESCRIPTION': 'Αυτή η απάντηση θα δει μόνο τα μέλη του προσωπικού', 'PRIVATE_TOPIC_DESCRIPTION': 'Αυτό το θέμα θα προβληθεί μόνο από μέλη του προσωπικού', + 'PRIVATE_DEPARTMENT_DESCRIPTION': 'Αυτό το τμήμα θα δει μόνο τα μέλη του προσωπικού', //ERRORS 'EMAIL_OR_PASSWORD': 'Λάθος ηλεκτρονική διεύθυνση ή κωδικός πρόσβασης', @@ -338,6 +339,7 @@ 'ERROR_IMAGE_SIZE': 'Καμία εικόνα δεν μπορεί να έχει μέγεθος μεγαλύτερο από {size} MB', 'USER_DISABLED': 'Αυτός ο λογαριασμός είναι απενεργοποιημένος.', 'INVALID_SYNTAX': 'Μη έγκυρη σύνταξη.', + 'DEPARTMENT_PRIVATE_TICKETS': 'Αυτό το τμήμα έχει εισιτήρια που δημιουργούνται από μη προσωπικό και δεν μπορεί να είναι ιδιωτικό', //MESSAGES 'SIGNUP_SUCCESS': 'Έχετε εγγραφεί με επιτυχία στο σύστημα υποστήριξης μας.', diff --git a/client/src/data/languages/in.js b/client/src/data/languages/in.js index f38476b7..2591fb7f 100644 --- a/client/src/data/languages/in.js +++ b/client/src/data/languages/in.js @@ -307,6 +307,7 @@ export default { 'DISABLE_USER_DESCRIPTION': 'उपयोगकर्ता अक्षम कर दिया जाएगा और साइन इन करने और टिकट बनाने में सक्षम नहीं होगा।', 'PRIVATE_RESPONSE_DESCRIPTION': 'यह प्रतिक्रिया केवल कर्मचारियों के सदस्यों द्वारा देखी जाएगी', 'PRIVATE_TOPIC_DESCRIPTION': 'यह विषय केवल कर्मचारियों के सदस्यों द्वारा देखा जाएगा', + 'PRIVATE_DEPARTMENT_DESCRIPTION': 'यह विभाग केवल कर्मचारियों के सदस्यों द्वारा देखा जाएगा', //ERRORS 'EMAIL_OR_PASSWORD': 'ईमेल या पासवर्ड अमान्य', @@ -338,6 +339,7 @@ export default { 'ERROR_IMAGE_SIZE': 'कोई छवि {size} एमबी से अधिक आकार नहीं हो सकती है', 'USER_DISABLED': 'यह खाता अक्षम है।', 'INVALID_SYNTAX': 'अवैध वाक्य रचना।', + 'DEPARTMENT_PRIVATE_TICKETS': 'इस विभाग में गैर-कर्मचारियों द्वारा बनाए गए टिकट हैं और यह निजी नहीं हो सकता है', //MESSAGES 'SIGNUP_SUCCESS': 'आप हमारे समर्थन प्रणाली में सफलतापूर्वक दर्ज कर लिया है।', diff --git a/client/src/data/languages/it.js b/client/src/data/languages/it.js index e7381d00..25d92867 100644 --- a/client/src/data/languages/it.js +++ b/client/src/data/languages/it.js @@ -307,6 +307,7 @@ export default { 'DISABLE_USER_DESCRIPTION': 'L\'utente sarà disabilitato e non sarà in grado di accedere e creare biglietti.', 'PRIVATE_RESPONSE_DESCRIPTION': 'Questa risposta sarà visibile solo ai membri dello staff', 'PRIVATE_TOPIC_DESCRIPTION': 'Questo argomento sarà visto solo dai membri dello staff', + 'PRIVATE_DEPARTMENT_DESCRIPTION': 'Questo dipartimento sarà visto solo dai membri dello staff', //ERRORS 'EMAIL_OR_PASSWORD': 'Email o password errate', @@ -338,6 +339,7 @@ export default { 'ERROR_IMAGE_SIZE': 'Nessuna immagine può avere una dimensione superiore a {size} MB', 'USER_DISABLED': 'Questo account è disabilitato.', 'INVALID_SYNTAX': 'Sintassi non valida.', + 'DEPARTMENT_PRIVATE_TICKETS': 'Questo dipartimento ha biglietti creati da non dipendenti e non può essere privato', //MESSAGES 'SIGNUP_SUCCESS': 'È stato registrato con successo nel nostro sistema di supporto.', diff --git a/client/src/data/languages/jp.js b/client/src/data/languages/jp.js index 410d5202..750b8ac3 100644 --- a/client/src/data/languages/jp.js +++ b/client/src/data/languages/jp.js @@ -307,6 +307,7 @@ export default { 'DISABLE_USER_DESCRIPTION': 'ユーザーは無効になり、ログインしてチケットを作成することはできません。', 'PRIVATE_RESPONSE_DESCRIPTION': 'スタッフのみがこの回答を見ることができます', 'PRIVATE_TOPIC_DESCRIPTION': 'このトピックは、スタッフによってのみ表示されます', + 'PRIVATE_DEPARTMENT_DESCRIPTION': 'この部署はスタッフだけが見ることができます', //ERRORS 'EMAIL_OR_PASSWORD': '電子メールまたはパスワードが無効です', @@ -338,6 +339,7 @@ export default { 'ERROR_IMAGE_SIZE': 'イメージのサイズが{size} MBを超えることはできません', 'USER_DISABLED': 'このアカウントは無効です。', 'INVALID_SYNTAX': '無効な構文。', + 'DEPARTMENT_PRIVATE_TICKETS': 'この部門には、スタッフ以外が作成したチケットがあり、プライベートにすることはできません', //MESSAGES 'SIGNUP_SUCCESS': 'あなたは私たちのサポートシステムに正常に登録しました。', diff --git a/client/src/data/languages/nl.js b/client/src/data/languages/nl.js index 6b8dcf86..09e3de2e 100644 --- a/client/src/data/languages/nl.js +++ b/client/src/data/languages/nl.js @@ -307,6 +307,7 @@ export default { 'DISABLE_USER_DESCRIPTION': 'De gebruiker wordt uitgeschakeld en kan zich niet aanmelden en geen tickets maken.', 'PRIVATE_RESPONSE_DESCRIPTION': 'Dit antwoord is alleen zichtbaar voor personeelsleden', 'PRIVATE_TOPIC_DESCRIPTION': 'Dit onderwerp is alleen zichtbaar voor personeelsleden', + 'PRIVATE_DEPARTMENT_DESCRIPTION': 'Deze afdeling is alleen zichtbaar voor personeelsleden', //ERRORS 'EMAIL_OR_PASSWORD': 'E-mailadres of wachtwoord ongeldig', @@ -338,6 +339,7 @@ export default { 'ERROR_IMAGE_SIZE': 'Geen enkele afbeelding kan groter zijn dan {size} MB', 'USER_DISABLED': 'Dit account is uitgeschakeld.', 'INVALID_SYNTAX': 'Ongeldige syntaxis.', + 'DEPARTMENT_PRIVATE_TICKETS': 'Deze afdeling heeft tickets gemaakt door niet-personeel en het kan niet privé zijn', //MESSAGES 'SIGNUP_SUCCESS': 'U hebt zich succesvol geregistreerd in ons ondersteuningssysteem.', diff --git a/client/src/data/languages/pt.js b/client/src/data/languages/pt.js index cf3f57fa..053b4cea 100644 --- a/client/src/data/languages/pt.js +++ b/client/src/data/languages/pt.js @@ -307,6 +307,7 @@ export default { 'DISABLE_USER_DESCRIPTION': 'O usuário será desativado e não poderá fazer login e criar tickets.', 'PRIVATE_RESPONSE_DESCRIPTION': 'Esta resposta só será vista pelos funcionários', 'PRIVATE_TOPIC_DESCRIPTION': 'Este tópico será visto apenas por membros da equipe', + 'PRIVATE_DEPARTMENT_DESCRIPTION': 'Este departamento só será visto pelos funcionários', //ERRORS 'EMAIL_OR_PASSWORD': 'E-mail ou senha inválidos', @@ -338,6 +339,7 @@ export default { 'ERROR_IMAGE_SIZE': 'Nenhuma imagem pode ter um tamanho maior que {size} MB', 'USER_DISABLED': 'Esta conta está desativada.', 'INVALID_SYNTAX': 'Sintaxe inválida.', + 'DEPARTMENT_PRIVATE_TICKETS': 'Este departamento tem ingressos criados por não funcionários e não pode ser privado', //MESSAGES 'SIGNUP_SUCCESS': 'Você se registrou com sucesso em nosso sistema de suporte.', diff --git a/client/src/data/languages/ru.js b/client/src/data/languages/ru.js index 9b0e0541..5f713290 100644 --- a/client/src/data/languages/ru.js +++ b/client/src/data/languages/ru.js @@ -307,6 +307,7 @@ export default { 'DISABLE_USER_DESCRIPTION': 'Пользователь будет отключен и не сможет войти и создать билеты', 'PRIVATE_RESPONSE_DESCRIPTION': 'Этот ответ будет рассматриваться только сотрудниками', 'PRIVATE_TOPIC_DESCRIPTION': 'Эта тема будет видна только сотрудникам', + 'PRIVATE_DEPARTMENT_DESCRIPTION': 'Этот отдел будет рассматриваться только сотрудниками', 'PRIVATE_DESCRIPTION': 'Этот ответ будет рассматриваться только сотрудниками', //ERRORS @@ -338,6 +339,7 @@ export default { 'ERRORS_FOUND': 'Ошибки найдены', 'ERROR_IMAGE_SIZE': 'Изображение не может иметь размер больше {size} МБ', 'USER_DISABLED': 'Эта учетная запись отключена.', + 'DEPARTMENT_PRIVATE_TICKETS': 'У этого отдела есть билеты, созданные не сотрудниками, и он не может быть приватным', 'INVALID_SYNTAX': 'Недопустимый синтаксис.', //MESSAGES diff --git a/client/src/data/languages/tr.js b/client/src/data/languages/tr.js index 03e61f05..584a4ffb 100644 --- a/client/src/data/languages/tr.js +++ b/client/src/data/languages/tr.js @@ -307,6 +307,7 @@ export default { 'DISABLE_USER_DESCRIPTION': 'Kullanıcı devre dışı bırakılacak ve oturum açıp bilet oluşturamayacak.', 'PRIVATE_RESPONSE_DESCRIPTION': 'Bu yanıt sadece personel tarafından görülebilir', 'PRIVATE_TOPIC_DESCRIPTION': 'Bu konu sadece çalışanlar tarafından görülebilir', + 'PRIVATE_DEPARTMENT_DESCRIPTION': 'Bu bölüm sadece personel tarafından görülebilir', 'PRIVATE_DESCRIPTION': 'Bu yanıt sadece personel tarafından görülebilir', //ERRORS @@ -338,6 +339,7 @@ export default { 'ERRORS_FOUND': 'Hatalar bulundu', 'ERROR_IMAGE_SIZE': 'Hiçbir resmin boyutu {size} MB\'den büyük olabilir', 'USER_DISABLED': 'Bu hesap devre dışı.', + 'DEPARTMENT_PRIVATE_TICKETS': 'Bu departman, personel olmayanlar tarafından oluşturulan biletlere sahiptir ve özel olamaz', 'INVALID_SYNTAX': 'Geçersiz sözdizimi.', //MESSAGES diff --git a/client/src/reducers/config-reducer.js b/client/src/reducers/config-reducer.js index 51ced243..26da48ea 100644 --- a/client/src/reducers/config-reducer.js +++ b/client/src/reducers/config-reducer.js @@ -49,6 +49,7 @@ class ConfigReducer extends Reducer { 'user-system-enabled': !!(payload.data['user-system-enabled']* 1), 'allow-attachments': !!(payload.data['allow-attachments']* 1), 'maintenance-mode': !!(payload.data['maintenance-mode']* 1), + departments: payload.data.departments.map(department => _.extend({}, department, {private: department.private * 1})), initDone: true }); } diff --git a/server/controllers/system/delete-department.php b/server/controllers/system/delete-department.php index d6750b98..db61ce9f 100755 --- a/server/controllers/system/delete-department.php +++ b/server/controllers/system/delete-department.php @@ -54,18 +54,23 @@ class DeleteDepartmentController extends Controller { if ($this->departmentId === $this->transferDepartmentId) { throw new RequestException(ERRORS::SAME_DEPARTMENT); - return; + } + + $departmentToTransfer = Department::getDataStore($this->transferDepartmentId); + $departmentInstance = Department::getDataStore($this->departmentId); + + if($departmentToTransfer->private && Ticket::count(' author_id IS NOT NULL AND department_id = ? ', [$departmentInstance->id])) { + throw new RequestException(ERRORS::DEPARTMENT_PRIVATE_TICKETS); } $this->transferDepartmentTickets(); - $departmentInstance = Department::getDataStore($this->departmentId); $departmentInstance->delete(); Log::createLog('DELETE_DEPARTMENT', $departmentInstance->name); Response::respondSuccess(); } - + public function transferDepartmentTickets() { $tickets = Ticket::find('department_id = ?', [$this->departmentId]); $newDepartment = Department::getDataStore($this->transferDepartmentId);; @@ -103,4 +108,4 @@ class DeleteDepartmentController extends Controller { $ticket->store(); } } -} \ No newline at end of file +} diff --git a/server/controllers/system/edit-department.php b/server/controllers/system/edit-department.php index 64ab6771..c5a20c21 100755 --- a/server/controllers/system/edit-department.php +++ b/server/controllers/system/edit-department.php @@ -43,14 +43,17 @@ class EditDepartmentController extends Controller { } public function handler() { - - $newname = Controller::request('name'); + $newName = Controller::request('name'); $departmentId = Controller::request('departmentId'); $private = Controller::request('private'); $departmentInstance = Department::getDataStore($departmentId); - $newname ? $departmentInstance->name = $newname : null; + if($private && Ticket::count(' author_id IS NOT NULL AND department_id = ? ', [$departmentId])) { + throw new RequestException(ERRORS::DEPARTMENT_PRIVATE_TICKETS); + } + + if($newName) $departmentInstance->name = $newName; $departmentInstance->private = $private ? 1 : 0; $departmentInstance->store(); diff --git a/server/controllers/user/login.php b/server/controllers/user/login.php index 886446d4..6d31d6d5 100755 --- a/server/controllers/user/login.php +++ b/server/controllers/user/login.php @@ -154,7 +154,7 @@ class LoginController extends Controller { private function createRememberToken() { $remember = Controller::request('remember'); - if ($remember) { + if (!Controller::request('staff') && $remember) { $this->rememberToken = Hashing::generateRandomToken(); $this->rememberExpiration = Date::getNextDate(30); diff --git a/server/data/ERRORS.php b/server/data/ERRORS.php index add61421..6d4343e0 100755 --- a/server/data/ERRORS.php +++ b/server/data/ERRORS.php @@ -199,6 +199,10 @@ * @apiDefine INVALID_TEXT_3 * @apiError {String} INVALID_TEXT_3 text3 of mail template has an invalid syntax or missing variables */ +/** + * @apiDefine DEPARTMENT_PRIVATE_TICKETS + * @apiError {String} DEPARTMENT_PRIVATE_TICKETS There are tickets for in department created by non-staff and it can't be private + */ class ERRORS { const INVALID_CREDENTIALS = 'INVALID_CREDENTIALS'; @@ -252,4 +256,5 @@ class ERRORS { const INVALID_TEXT_1 = 'INVALID_TEXT_1'; const INVALID_TEXT_2 = 'INVALID_TEXT_2'; const INVALID_TEXT_3 = 'INVALID_TEXT_3'; + const DEPARTMENT_PRIVATE_TICKETS = 'DEPARTMENT_PRIVATE_TICKETS'; } diff --git a/tests/system/delete-department.rb b/tests/system/delete-department.rb index 0c841b95..bf9b3ba5 100644 --- a/tests/system/delete-department.rb +++ b/tests/system/delete-department.rb @@ -56,7 +56,7 @@ describe 'system/delete-department' do (result['message']).should.equal('SAME_DEPARTMENT') end - it 'should delete department' do + it 'should fail if department to transfer is private' do result = request('/system/delete-department', { csrf_userid: $csrf_userid, csrf_token: $csrf_token, @@ -64,6 +64,18 @@ describe 'system/delete-department' do transferDepartmentId: 2 }) + (result['status']).should.equal('fail') + (result['message']).should.equal('DEPARTMENT_PRIVATE_TICKETS') + end + + it 'should delete department' do + result = request('/system/delete-department', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + departmentId: 4, + transferDepartmentId: 3 + }) + (result['status']).should.equal('success') row = $database.getRow('department', 4, 'id') @@ -73,13 +85,13 @@ describe 'system/delete-department' do ticket2 = $database.getRow('ticket', ticket2, 'ticket_number') ticket3 = $database.getRow('ticket', ticket3, 'ticket_number') - (ticket1['department_id']).should.equal('2') + (ticket1['department_id']).should.equal('3') (ticket1['owner_id']).should.equal(nil) - (ticket2['department_id']).should.equal('2') + (ticket2['department_id']).should.equal('3') (ticket2['owner_id']).should.equal(nil) - (ticket3['department_id']).should.equal('2') + (ticket3['department_id']).should.equal('3') (ticket3['owner_id']).should.equal($csrf_userid) lastLog = $database.getLastRow('log')