Skip to content

Commit

Permalink
RocketChat#821 -> RocketChat#953 [EDIT] Изменена запись протокола в б…
Browse files Browse the repository at this point in the history
…д в форме отправки документов
  • Loading branch information
Scarvis committed Feb 18, 2021
1 parent 16a054b commit f9a6672
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 55 deletions.
3 changes: 2 additions & 1 deletion app/api/server/lib/working-groups-requests.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { WorkingGroupsRequests } from '../../../models/server/raw';

export async function findWorkingGroupsRequests({ query = {}, pagination: { offset, count, sort } }) {
export async function findWorkingGroupsRequests({ query = {}, fields = {}, pagination: { offset, count, sort } }) {
const cursor = await WorkingGroupsRequests.find(query, {
sort: sort || { time: 1 },
skip: offset,
limit: count,
fields,
});

const total = await cursor.count();
Expand Down
3 changes: 2 additions & 1 deletion app/api/server/v1/protocols.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ API.v1.addRoute('protocols.list', { authRequired: true }, {
// }

const { offset, count } = this.getPaginationItems();
const { sort, query } = this.parseJsonQuery();
const { sort, query, stockFields } = this.parseJsonQuery();

return API.v1.success(Promise.await(findProtocols({
query,
fields: stockFields,
pagination: {
offset,
count,
Expand Down
3 changes: 2 additions & 1 deletion app/api/server/v1/working-groups-requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import { findWorkingGroupRequestAnswerByAnswerId, findWorkingGroupsRequests, fin
API.v1.addRoute('working-groups-requests.list', { authRequired: true }, {
get() {
const { offset, count } = this.getPaginationItems();
const { sort, query } = this.parseJsonQuery();
const { sort, query, stockFields } = this.parseJsonQuery();

return API.v1.success(Promise.await(findWorkingGroupsRequests({
query,
fields: stockFields,
pagination: {
offset,
count,
Expand Down
143 changes: 111 additions & 32 deletions app/errand/client/views/errandsPage/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Box, Icon, Table, TextInput, Modal, Button, Label, Field } from '@rocket.chat/fuselage';
import {
Box,
Icon,
Table,
TextInput,
Modal,
Button,
Label,
Field,
Tabs,
TextAreaInput,
ButtonGroup,
} from '@rocket.chat/fuselage';
import { useMediaQuery, useSafely } from '@rocket.chat/fuselage-hooks';

import Page from '../../../../../client/components/basic/Page';
Expand All @@ -8,10 +20,15 @@ import { useRouteParameter } from '../../../../../client/contexts/RouterContext'
import { GenericTable, Th } from '../../../../../client/components/GenericTable';
import { useEndpointData } from '../../../../../client/hooks/useEndpointData';
import { useFormatDate } from '../../../../../client/hooks/useFormatDate';
import { useFormatDateAndTime } from '../../../../../client/hooks/useFormatDateAndTime';
import { useSetModal } from '../../../../../client/contexts/ModalContext';
import { EditErrandContextBar } from './EditErrand';
import { modal } from '../../../../ui-utils/client';
import { GoBackButton } from '../../../../utils/client/views/GoBackButton';
import { useUserId } from '../../../../../client/contexts/UserContext';
import { useEndpointDataExperimental, ENDPOINT_STATES } from '../../../../../client/hooks/useEndpointDataExperimental';
import { settings } from '../../../../settings';
import VerticalBar from '../../../../../client/components/basic/VerticalBar';


const style = { whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' };
Expand All @@ -34,6 +51,51 @@ const FilterByText = ({ setFilter, ...props }) => {
</Box>;
};

function renderRequestModal({ onCancel, request, formatDateAndTime, ...props }) {
const t = useTranslation();
// const formatDate = useFormatDate();

const goToSendAnswer = () => {
window.open([settings.get('Site_Url'), 'd/', request.inviteLink].join(''), '_blank');
};

return <Modal {...props}>
<Modal.Header>
<Modal.Title>{t('Working_group_request')}</Modal.Title>
<Modal.Close onClick={onCancel}/>
</Modal.Header>
<Modal.Content fontScale='p1'>
<VerticalBar.ScrollableContent is='form'>
<Field>
<Field.Label>{t('Number')}</Field.Label>
<Field.Row>
<TextInput disabled value={request.number} key='number' placeholder={t('Number')} />
</Field.Row>
</Field>
<Field>
<Field.Label>{t('Description')}</Field.Label>
<Field.Row>
<TextAreaInput rows='3' disabled value={request.desc} key='desc' placeholder={t('Description')} />
</Field.Row>
</Field>
<Field>
<Field.Label>{t('Date')}</Field.Label>
<Field.Row>
{/*<TextInput disabled value={formatDate(request.date)} key='date' placeholder={t('Date')} />*/}
<TextInput disabled value={formatDateAndTime(request.date)} key='date' placeholder={t('Date')} />
</Field.Row>
</Field>
<Field>
<ButtonGroup>
<Button flexGrow={1} onClick={onCancel}>{t('Cancel')}</Button>
<Button primary mie='none' flexGrow={1} onClick={goToSendAnswer}>{t('Send_request_answer')}</Button>
</ButtonGroup>
</Field>
</VerticalBar.ScrollableContent>
</Modal.Content>
</Modal>;
}

function renderEditModal({ onCancel, erid, onChange, ...props }) {
const t = useTranslation();
return <Modal {...props}>
Expand Down Expand Up @@ -114,7 +176,6 @@ function Errands({
}

function Requests({
type,
data,
sort,
onClick,
Expand All @@ -126,61 +187,55 @@ function Requests({

const mediaQuery = useMediaQuery('(min-width: 768px)');

const formatDate = useFormatDate();

const header = useMemo(() => [
type === 'initiated_by_me' || <Th key={'initiatedBy.username'} direction={sort[1]} active={sort[0] === 'initiatedBy.username'} onClick={onHeaderClick} sort='initiatedBy.username' color='default'>{_t('Errand_Initiated_by')}</Th>,
type === 'charged_to_me' || <Th key={'chargedToUser.username'} direction={sort[1]} active={sort[0] === 'chargedToUser.username'} onClick={onHeaderClick} sort='chargedToUser.username' color='default'>{_t('Errand_Charged_to')}</Th>,
mediaQuery && <Th key={'desc'} direction={sort[1]} active={sort[0] === 'desc'} onClick={onHeaderClick} sort='desc' color='default'>{_t('Description')}</Th>,
mediaQuery && <Th key={'ts'} direction={sort[1]} active={sort[0] === 'ts'} onClick={onHeaderClick} sort='ts' style={{ width: '150px' }} color='default'>{_t('Started_At')}</Th>,
<Th key={'expireAt'} direction={sort[1]} active={sort[0] === 'expireAt'} onClick={onHeaderClick} sort='expireAt' style={{ width: '150px' }} color='default'>{_t('Errand_Expired_date')}</Th>,
<Th key={'t'} direction={sort[1]} active={sort[0] === 't'} onClick={onHeaderClick} sort='t' color='default'>{_t('Status')}</Th>,
].filter(Boolean), [type, sort, mediaQuery]);
mediaQuery && <Th key={'number'} onClick={onHeaderClick} color='default'>{_t('Number')}</Th>,
mediaQuery && <Th key={'desc'} onClick={onHeaderClick} color='default'>{_t('Description')}</Th>,
mediaQuery && <Th key={'date'} onClick={onHeaderClick} style={{ width: '150px' }} color='default'>{_t('Date')}</Th>,
].filter(Boolean), [sort, mediaQuery]);

const formatDate = useFormatDate();
const renderRow = useCallback((item) =>
<Table.Row key={item._id} onKeyDown={onClick(item.initiatedBy.username)} onClick={onClick(item)} role='link' action>
{ type === 'initiated_by_me' || <Table.Cell fontScale='p1' style={style} color='default'>
{item.initiatedBy.username}
</Table.Cell> }
{type === 'charged_to_me' || <Table.Cell fontScale='p1' style={style} color='default'>
{item.chargedToUser.username}
<Table.Row key={item._id} onClick={onClick(item)} role='link' action>
{ mediaQuery && <Table.Cell fontScale='p1' style={style} color='default'>
{item.number}
</Table.Cell> }
{ mediaQuery && <Table.Cell fontScale='p1' style={style} color='default'>
{item.desc}
</Table.Cell> }
{ mediaQuery && <Table.Cell fontScale='p1' style={style} color='default'>
{formatDate(item.ts)}
{formatDate(item.date)}
</Table.Cell>}
<Table.Cell fontScale='p1' style={style} color='default'>
{formatDate(item.expireAt)}
</Table.Cell>
<Table.Cell fontScale='p1' style={style} color='default'>
{_t(item.t)}
</Table.Cell>
</Table.Row>
, [mediaQuery]);

return <GenericTable key='RequestsTable' header={header} renderRow={renderRow} results={data.result} total={data.total} setParams={setParams} params={params} />;
return <GenericTable key='RequestsTable' header={header} renderRow={renderRow} results={data.requests} total={data.total} setParams={setParams} params={params} />;
}

export function ErrandPage() {
const t = useTranslation();
const formatDateAndTime = useFormatDateAndTime();
const userId = useUserId();
const setModal = useSetModal();

const type = useRouteParameter('type');

const [sort, setSort] = useState(['ts', 'asc']);
const [params, setParams] = useState({ type, current: 0, itemsPerPage: 100 });
const [cache, setCache] = useState();
const [tab, setTab] = useState('errands');

let title = 'Errands';
switch (type) {
case 'initiated_by_me':
title = 'Errands_from_me';
tab !== 'errands' && setTab('errands');
break;
case 'charged_to_me':
title = 'Errands_for_me';
title = 'Tasks_for_me';
break;
}

const [sort, setSort] = useState(['ts', 'asc']);
const [params, setParams] = useState({ type, current: 0, itemsPerPage: 100 });
const [cache, setCache] = useState();
const setModal = useSetModal();

const query = useMemo(() => ({
query: JSON.stringify({
type,
Expand All @@ -190,8 +245,21 @@ export function ErrandPage() {
...params.current && { offset: params.current },
}), [params.itemsPerPage, params.current, sort, type, params.text, cache]);

const currentUserPersonData = useEndpointData('users.getPerson', useMemo(() => ({ query: JSON.stringify({ userId }) }), [userId]));
const data = useEndpointData('errands', query) || { result: [], total: 0 };

const currentUserPersonQuery = useMemo(() => currentUserPersonData || { _id: '' }, [currentUserPersonData]);
const { data: resData, state: resState } = useEndpointDataExperimental('protocolItemsPersonsResponsible.list', useMemo(() => ({
query: JSON.stringify({ persons: { $elemMatch: { _id: currentUserPersonQuery._id } } }),
fields: JSON.stringify({ persons: 0 }),
}), [currentUserPersonQuery]));

const requestsQuery = useMemo(() => resData?.protocolItemsPersonsResponsible?.map((protocol) => protocol.itemId) || [], [resData]);
const { data: requests, state } = useEndpointDataExperimental('working-groups-requests.list', useMemo(() => ({
query: JSON.stringify({ answers: { $elemMatch: { sectionItemId: { $in: requestsQuery } } } }),
fields: JSON.stringify({ answers: 0 }),
}), [requestsQuery]));

const onHeaderClick = useCallback((id) => {
const [sortBy, sortDirection] = sort;

Expand All @@ -211,8 +279,15 @@ export function ErrandPage() {

const onClick = useCallback((errand) => () => setModal(() => renderEditModal({ onCancel: cancelModal, erid: errand._id, onChange, key: 'modal-errand' })), []);

const onRequestClick = useCallback((request) => () => setModal(() => renderRequestModal({ onCancel: cancelModal, request, formatDateAndTime, key: 'modal-request' })), []);

const addErrand = useCallback(() => () => setModal(() => renderAddErrandModal({ onChange })), []);

if ([state, resState].includes(ENDPOINT_STATES.LOADING)) {
console.log('loading');
return <Field>{t('Loading')}</Field>;
}

return <Page flexDirection='row'>
<Page>
<Page.Header>
Expand All @@ -225,8 +300,12 @@ export function ErrandPage() {
</Button> }
</Page.Header>
<Page.Content>
<Errands type={type} setParam={setParams} params={params} onHeaderClick={onHeaderClick} data={data} onClick={onClick} sort={sort}/>
{/*<Requests type={type} setParam={setParams} params={params} onHeaderClick={onHeaderClick} data={data} onClick={onClick} sort={sort}/>*/}
{type === 'charged_to_me' && <Tabs flexShrink={0} mbe='x8'>
<Tabs.Item selected={tab === 'errands'} onClick={() => setTab('errands')}>{t('Errands_for_me')}</Tabs.Item>
<Tabs.Item selected={tab === 'requests'} onClick={() => setTab('requests')}>{t('Working_group_requests')}</Tabs.Item>
</Tabs>}
{tab === 'errands' && <Errands type={type} setParam={setParams} params={params} onHeaderClick={onHeaderClick} data={data} onClick={onClick} sort={sort}/>}
{tab === 'requests' && <Requests setParam={setParams} params={params} onHeaderClick={onHeaderClick} data={requests} onClick={onRequestClick} sort={sort}/>}
</Page.Content>
</Page>
</Page>;
Expand Down
13 changes: 6 additions & 7 deletions app/models/server/models/Protocols.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Base } from './_Base';
import { ObjectID } from 'bson';

import { Base } from './_Base';

class Protocols extends Base {
constructor() {
super('protocols');
Expand Down Expand Up @@ -88,29 +89,27 @@ class Protocols extends Base {

data.sections.forEach((section) => {
if (section._id === sectionId) {

if (section.items) {
let internalNum = 0;
section.items.forEach((item) => {
if (item.inum > internalNum) {
internalNum = item.inum;
}
})
});
internalNum++;
item.inum = internalNum;
section.items = [...section.items, item];
} else {
item.inum = 1;
section.items = [item];
}

}
});

this.update({ _id: protocolId }, { $set: { ...data } })
this.update({ _id: protocolId }, { $set: { ...data } });
return _id;
}

return _id;
return null;
}

removeItemById(protocolId, sectionId, _id) {
Expand Down
3 changes: 2 additions & 1 deletion app/protocols/server/methods/deleteItem.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Meteor } from 'meteor/meteor';

import { hasPermission } from '../../../authorization';
import { Protocols } from '../../../models';
import { Protocols, ProtocolItemsPersonsResponsible } from '../../../models';

Meteor.methods({
deleteItem(protocolId, sectionId, _id) {
Expand All @@ -18,6 +18,7 @@ Meteor.methods({
}

Protocols.removeItemById(protocolId, sectionId, _id);
ProtocolItemsPersonsResponsible.removeByItemId(_id);

return true;
},
Expand Down
16 changes: 12 additions & 4 deletions app/protocols/server/methods/insertOrUpdateItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { Meteor } from 'meteor/meteor';
import s from 'underscore.string';

import { hasPermission } from '../../../authorization';
import { Protocols } from '../../../models';
import { Protocols, ProtocolItemsPersonsResponsible } from '../../../models';

Meteor.methods({
insertOrUpdateItem(protocolId, sectionId, item) {
// if (!hasPermission(this.userId, 'manage-protocols')) {
// if (!hasPermission('manage-protocols', Meteor.userId)) {
// throw new Meteor.Error('not_authorized');
// }

Expand All @@ -26,10 +26,18 @@ Meteor.methods({
throw new Meteor.Error('error-the-field-is-required', 'The field Name is required', { method: 'insertOrUpdateItem', field: 'Name' });
}

let _id = null;
const protocolItemsPersonsResponsible = { protocolId, sectionId, itemId: item._id, persons: item.responsible.filter((person) => person.userId).map((person) => ({ _id: person._id })) };

if (!item._id) {
return Protocols.createItem(protocolId, sectionId, item);
_id = Protocols.createItem(protocolId, sectionId, item);
protocolItemsPersonsResponsible.itemId = _id;
!!_id && ProtocolItemsPersonsResponsible.create(protocolItemsPersonsResponsible);
} else {
_id = Protocols.updateItem(protocolId, sectionId, item);
!!_id && ProtocolItemsPersonsResponsible.updateProtocolItemsPersonsResponsible(protocolItemsPersonsResponsible);
}

return Protocols.updateItem(protocolId, sectionId, item);
return _id;
},
});
Loading

0 comments on commit f9a6672

Please sign in to comment.