Add member status and expiry date to Storage

master
Tanner Collin 11 months ago
parent c0c41f5c1c
commit 25f7588064
  1. 10
      apiserver/apiserver/api/serializers.py
  2. 38
      webclient/src/Storage.js

@ -523,6 +523,8 @@ class SimpleStorageSpaceSerializer(serializers.ModelSerializer):
class StorageSpaceSerializer(serializers.ModelSerializer): class StorageSpaceSerializer(serializers.ModelSerializer):
member_id = serializers.SerializerMethodField() member_id = serializers.SerializerMethodField()
member_name = serializers.SerializerMethodField() member_name = serializers.SerializerMethodField()
member_status = serializers.SerializerMethodField()
member_paused = serializers.SerializerMethodField()
class Meta: class Meta:
model = models.StorageSpace model = models.StorageSpace
@ -553,6 +555,14 @@ class StorageSpaceSerializer(serializers.ModelSerializer):
member = obj.user.member member = obj.user.member
return member.preferred_name + ' ' + member.last_name return member.preferred_name + ' ' + member.last_name
def get_member_status(self, obj):
if not obj.user: return None
return obj.user.member.status
def get_member_paused(self, obj):
if not obj.user: return None
return obj.user.member.paused_date
class TrainingSerializer(serializers.ModelSerializer): class TrainingSerializer(serializers.ModelSerializer):
attendance_status = serializers.ChoiceField([ attendance_status = serializers.ChoiceField([

@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import { Link, useParams, useHistory } from 'react-router-dom'; import { Link, useParams, useHistory } from 'react-router-dom';
import './light.css'; import './light.css';
import { MembersDropdown } from './Members.js'; import { MembersDropdown } from './Members.js';
import { isAdmin, BasicTable, requester, useIsMobile } from './utils.js'; import { statusColor, isAdmin, BasicTable, requester, useIsMobile } from './utils.js';
import { Button, Checkbox, Container, Form, Grid, Header, Icon, Input, Message, Segment, Table } from 'semantic-ui-react'; import { Button, Checkbox, Container, Form, Grid, Header, Icon, Input, Message, Segment, Table } from 'semantic-ui-react';
export function StorageEditor(props) { export function StorageEditor(props) {
@ -277,6 +277,7 @@ let storageListCache = false;
let showEmptyCache = false; let showEmptyCache = false;
let showMemodCache = false; let showMemodCache = false;
let showServedCache = false; let showServedCache = false;
let showExpiredCache = false;
export function StorageList(props) { export function StorageList(props) {
const { token } = props; const { token } = props;
@ -285,6 +286,7 @@ export function StorageList(props) {
const [showEmpty, setShowEmpty] = useState(showEmptyCache); const [showEmpty, setShowEmpty] = useState(showEmptyCache);
const [showMemod, setShowMemod] = useState(showMemodCache); const [showMemod, setShowMemod] = useState(showMemodCache);
const [showServed, setShowServed] = useState(showServedCache); const [showServed, setShowServed] = useState(showServedCache);
const [showExpired, setShowExpired] = useState(showExpiredCache);
const [error, setError] = useState(false); const [error, setError] = useState(false);
const isMobile = useIsMobile(); const isMobile = useIsMobile();
@ -310,11 +312,21 @@ export function StorageList(props) {
return false; return false;
} else if (showServed && !x.memo.toLowerCase().includes('served')) { } else if (showServed && !x.memo.toLowerCase().includes('served')) {
return false; return false;
} else if (showExpired && !x.member_paused) {
return false;
} else { } else {
return true; return true;
} }
}; };
const sortStorage = (a, b) => {
if (showExpired) {
return a.member_paused !== b.member_paused ? a.member_paused < b.member_paused ? -1 : 1 : 0;
} else {
return a.shelf_id !== b.shelf_id ? a.shelf_id < b.shelf_id ? -1 : 1 : 0;
}
};
const handleShowEmpty = (e, v) => { const handleShowEmpty = (e, v) => {
setShowEmpty(v.checked); setShowEmpty(v.checked);
showEmptyCache = v.checked; showEmptyCache = v.checked;
@ -330,6 +342,13 @@ export function StorageList(props) {
showServedCache = v.checked; showServedCache = v.checked;
}; };
const handleShowExpired = (e, v) => {
setShowExpired(v.checked);
showExpiredCache = v.checked;
};
const numResults = storageList ? storageList.filter(filterStorage).length : 0;
return ( return (
<div> <div>
<p> <p>
@ -363,29 +382,40 @@ export function StorageList(props) {
onChange={handleShowServed} onChange={handleShowServed}
checked={showServed} checked={showServed}
/> />
<Checkbox
className='filter-option'
label='Show Expired'
onChange={handleShowExpired}
checked={showExpired}
/>
</p> </p>
{!error ? {!error ?
storageList ? storageList ?
<> <>
<p>{storageList.filter(filterStorage).length} results:</p> <p>{numResults} result{numResults === 1 ? '' : 's'}{showExpired && ', ordered by expiry'}:</p>
<Table basic='very'> <Table basic='very'>
{!isMobile && <Table.Header> {!isMobile && <Table.Header>
<Table.Row> <Table.Row>
<Table.HeaderCell>Shelf ID</Table.HeaderCell> <Table.HeaderCell>Shelf ID</Table.HeaderCell>
<Table.HeaderCell>Owner</Table.HeaderCell> <Table.HeaderCell>Owner</Table.HeaderCell>
<Table.HeaderCell>Expired</Table.HeaderCell>
<Table.HeaderCell>Memo</Table.HeaderCell> <Table.HeaderCell>Memo</Table.HeaderCell>
</Table.Row> </Table.Row>
</Table.Header>} </Table.Header>}
<Table.Body> <Table.Body>
{storageList.filter(filterStorage).map(x => {storageList.filter(filterStorage).sort(sortStorage).map(x =>
<Table.Row key={x.id}> <Table.Row key={x.id}>
<Table.Cell><StorageButton storage={x} /></Table.Cell> <Table.Cell><StorageButton storage={x} /></Table.Cell>
<Table.Cell> <Table.Cell>
{isMobile && 'Owner: '}<Link to={'/members/'+x.member_id}>{x.member_name}</Link> {isMobile && 'Owner: '}
{x.member_name && <Icon name='circle' color={statusColor[x.member_status]} />}
<Link to={'/members/'+x.member_id}>{x.member_name}</Link>
</Table.Cell> </Table.Cell>
<Table.Cell>{isMobile && 'Expired: '}{x.member_paused}</Table.Cell>
<Table.Cell>{isMobile && 'Memo: '}{x.memo}</Table.Cell> <Table.Cell>{isMobile && 'Memo: '}{x.memo}</Table.Cell>
</Table.Row> </Table.Row>
)} )}

Loading…
Cancel
Save