forked from RocketChat/Rocket.Chat
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/protocols' into RocketChat#755
# Conflicts: # packages/rocketchat-i18n/i18n/ru.i18n.json
- Loading branch information
Showing
31 changed files
with
1,920 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { Protocols } from '../../../models/server/raw'; | ||
|
||
export async function findProtocols({ query = {}, pagination: { offset, count, sort } }) { | ||
const cursor = await Protocols.find(query, { | ||
sort: sort || { time: 1 }, | ||
skip: offset, | ||
limit: count, | ||
}); | ||
|
||
const total = await cursor.count(); | ||
|
||
const protocols = await cursor.toArray(); | ||
|
||
return { | ||
protocols, | ||
count: protocols.length, | ||
offset, | ||
total, | ||
}; | ||
} | ||
|
||
export async function findProtocol(_id) { | ||
const cursor = await Protocols.findOne({ _id }); | ||
return cursor; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { API } from '../api'; | ||
import { findProtocols, findProtocol } from '../lib/protocols'; | ||
import { hasPermission } from '../../../authorization'; | ||
|
||
API.v1.addRoute('protocols.list', { authRequired: true }, { | ||
get() { | ||
if (!hasPermission(this.userId, 'manage-protocols')) { | ||
return API.v1.unauthorized(); | ||
} | ||
|
||
const { offset, count } = this.getPaginationItems(); | ||
const { sort, query } = this.parseJsonQuery(); | ||
|
||
return API.v1.success(Promise.await(findProtocols({ | ||
query, | ||
pagination: { | ||
offset, | ||
count, | ||
sort, | ||
}, | ||
}))); | ||
}, | ||
}); | ||
|
||
API.v1.addRoute('protocols.findOne', { authRequired: true }, { | ||
get() { | ||
const { query } = this.parseJsonQuery(); | ||
return API.v1.success(Promise.await(findProtocol(query._id))); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import { Base } from './_Base'; | ||
import { ObjectID } from 'bson'; | ||
|
||
class Protocols extends Base { | ||
constructor() { | ||
super('protocols'); | ||
} | ||
|
||
// INSERT | ||
create(data) { | ||
return this.insert(data); | ||
} | ||
|
||
// REMOVE | ||
removeById(_id) { | ||
return this.remove({ _id }); | ||
} | ||
|
||
// UPDATE | ||
updateProtocol(_id, data) { | ||
data._updatedAt = new Date(); | ||
return this.update({ _id }, { $set: { ...data } }); | ||
} | ||
|
||
createSection(protocolId, sectionData) { | ||
const _id = new ObjectID().toHexString(); | ||
sectionData._id = _id; | ||
|
||
const data = this.findOne({ _id: protocolId }); | ||
data.sections = data.sections ? [...data.sections, sectionData] : [sectionData]; | ||
data._updatedAt = new Date(); | ||
this.update({ _id: protocolId }, { $set: { ...data } }); | ||
|
||
return _id; | ||
} | ||
|
||
removeSectionById(protocolId, _id) { | ||
const data = this.findOne({ _id: protocolId }); | ||
|
||
if (data.sections) { | ||
data.sections = data.sections.filter(section => section._id !== _id); | ||
data._updatedAt = new Date(); | ||
this.update({ _id: protocolId }, { $set: { ...data }}); | ||
} | ||
} | ||
|
||
updateSection(protocolId, sectionData) { | ||
const data = this.findOne({ _id: protocolId }); | ||
|
||
if (data.sections) { | ||
data.sections = data.sections.map((section) => { | ||
if (section._id === sectionData._id) { | ||
return { ...sectionData, items: section.items }; | ||
} | ||
return section; | ||
}); | ||
|
||
data._updatedAt = new Date(); | ||
this.update({ _id: protocolId }, { $set: { ...data }}); | ||
} | ||
|
||
return sectionData._id; | ||
} | ||
|
||
createItem(protocolId, sectionId, item) { | ||
const _id = new ObjectID().toHexString(); | ||
item._id = _id; | ||
|
||
const data = this.findOne({ _id: protocolId }); | ||
|
||
if (data.sections) { | ||
data._updatedAt = new Date(); | ||
|
||
data.sections.forEach((section) => { | ||
if (section._id === sectionId) { | ||
section.items = section.items ? [...section.items, item] : [item]; | ||
} | ||
}); | ||
|
||
this.update({ _id: protocolId }, { $set: { ...data } }) | ||
} | ||
|
||
return _id; | ||
} | ||
|
||
removeItemById(protocolId, sectionId, _id) { | ||
const data = this.findOne({ _id: protocolId }); | ||
|
||
if (data.sections) { | ||
data.sections = data.sections.map((section) => { | ||
if (section._id === sectionId) { | ||
section.items = section.items.filter(item => item._id !== _id); | ||
} | ||
return section; | ||
}); | ||
|
||
data._updatedAt = new Date(); | ||
this.update({ _id: protocolId }, { $set: { ...data }}); | ||
} | ||
} | ||
|
||
updateItem(protocolId, sectionId, itemData) { | ||
const data = this.findOne({ _id: protocolId }); | ||
|
||
if (data.sections) { | ||
data.sections = data.sections.map((section) => { | ||
if (section._id === sectionId) { | ||
section.items = section.items.map((item) => { | ||
if (item._id === itemData._id) { | ||
return { ...itemData }; | ||
} | ||
return item; | ||
}) | ||
} | ||
return section; | ||
}); | ||
|
||
data._updatedAt = new Date(); | ||
this.update({ _id: protocolId }, { $set: { ...data }}); | ||
} | ||
|
||
return itemData._id; | ||
} | ||
|
||
} | ||
|
||
export default new Protocols(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { BaseRaw } from './BaseRaw'; | ||
|
||
export class ProtocolsRaw extends BaseRaw { | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import React, { useState, useCallback } from 'react'; | ||
import { Field, TextAreaInput, Button, InputBox, ButtonGroup, TextInput } from '@rocket.chat/fuselage'; | ||
import DatePicker, { registerLocale } from 'react-datepicker'; | ||
import ru from 'date-fns/locale/ru'; | ||
registerLocale('ru', ru); | ||
|
||
import { useToastMessageDispatch } from '../../../../client/contexts/ToastMessagesContext'; | ||
import { useTranslation } from '../../../../client/contexts/TranslationContext'; | ||
import { useRouteParameter } from '../../../../client/contexts/RouterContext'; | ||
import { useMethod } from '../../../../client/contexts/ServerContext'; | ||
import { validateItemData, createItemData } from './lib'; | ||
import VerticalBar from '../../../../client/components/basic/VerticalBar'; | ||
|
||
export function AddItem({ goToNew, close, onChange, ...props }) { | ||
const t = useTranslation(); | ||
const dispatchToastMessage = useToastMessageDispatch(); | ||
|
||
const [number, setNumber] = useState(''); | ||
const [name, setName] = useState(''); | ||
const [responsible, setResponsible] = useState(''); | ||
const [expireAt, setExpireAt] = useState(''); | ||
|
||
const protocolId = useRouteParameter('id'); | ||
const sectionId = useRouteParameter('sectionId'); | ||
|
||
const insertOrUpdateItem = useMethod('insertOrUpdateItem'); | ||
|
||
const saveAction = useCallback(async (number, name, responsible, expireAt) => { | ||
const itemData = createItemData(number, name, responsible, expireAt); | ||
const validation = validateItemData(itemData); | ||
if (validation.length === 0) { | ||
const _id = await insertOrUpdateItem(protocolId, sectionId, itemData); | ||
return _id; | ||
} | ||
validation.forEach((error) => { throw new Error({ type: 'error', message: t('error-the-field-is-required', { field: t(error) }) }); }); | ||
}, [dispatchToastMessage, insertOrUpdateItem, t]); | ||
|
||
const handleSave = useCallback(async () => { | ||
try { | ||
const result = await saveAction( | ||
number, | ||
name, | ||
responsible, | ||
expireAt | ||
); | ||
dispatchToastMessage({ type: 'success', message: t('Item_Added_Successfully') }); | ||
goToNew(sectionId, result)(); | ||
onChange(); | ||
} catch (error) { | ||
dispatchToastMessage({ type: 'error', message: error }); | ||
} | ||
}, [dispatchToastMessage, goToNew, number, name, responsible, expireAt, onChange, saveAction, t]); | ||
|
||
return <VerticalBar.ScrollableContent {...props}> | ||
<Field> | ||
<Field.Label>{t('Item_Number')}</Field.Label> | ||
<Field.Row> | ||
<InputBox value={number} onChange={(e) => setNumber(e.currentTarget.value)} placeholder={t('Item_Number')} /> | ||
</Field.Row> | ||
</Field> | ||
<Field> | ||
<Field.Label>{t('Item_Name')}</Field.Label> | ||
<Field.Row> | ||
<TextAreaInput rows='10' multiple value={name} onChange={(e) => setName(e.currentTarget.value)} placeholder={t('Item_Name')} /> | ||
</Field.Row> | ||
</Field> | ||
<Field> | ||
<Field.Label>{t('Item_Responsible')}</Field.Label> | ||
<Field.Row> | ||
<TextInput value={responsible} onChange={(e) => setResponsible(e.currentTarget.value)} placeholder={t('Item_Responsible')} /> | ||
</Field.Row> | ||
</Field> | ||
<Field> | ||
<Field.Label>{t('Item_ExpireAt')}</Field.Label> | ||
<Field.Row> | ||
<DatePicker | ||
dateFormat='dd.MM.yyyy' | ||
selected={expireAt} | ||
onChange={(newDate) => setExpireAt(newDate)} | ||
customInput={<TextInput />} | ||
locale='ru' | ||
/> | ||
</Field.Row> | ||
</Field> | ||
<Field> | ||
<Field.Row> | ||
<ButtonGroup stretch w='full'> | ||
<Button mie='x4' onClick={close}>{t('Cancel')}</Button> | ||
<Button primary onClick={handleSave} disabled={number === '' || name === ''}>{t('Save')}</Button> | ||
</ButtonGroup> | ||
</Field.Row> | ||
</Field> | ||
</VerticalBar.ScrollableContent>; | ||
} |
Oops, something went wrong.