Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[refactor] staticify Organization Statistic data #379

Merged
merged 2 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ NEXT_PUBLIC_AUTHING_APP_ID = 60178760106d5f26cb267ac1

NEXT_PUBLIC_COMMUNITY_BASE_ID = BVzab5wF5aWD0OsKGqacwA20n8f
NEXT_PUBLIC_ACTIVITY_TABLE_ID = tbl9kxJAKOwwDewd
NEXT_PUBLIC_OSC_YEAR_STATISTIC_TABLE_ID = tbl1BSojT0UPWwx3
NEXT_PUBLIC_OSC_CITY_STATISTIC_TABLE_ID = tblGFOxKoGQ0CjAe
NEXT_PUBLIC_OSC_TYPE_STATISTIC_TABLE_ID = tblXz03jtvdO25n8
NEXT_PUBLIC_OSC_TAG_STATISTIC_TABLE_ID = tblZGDpom4W7PiHz
NEXT_PUBLIC_ORGANIZATION_TABLE_ID = tbl4vLvOFWWKj5Co
NEXT_PUBLIC_COOPERATION_TABLE_ID = tbltoGsHaDmEaHYr

Expand All @@ -36,4 +40,8 @@ NEXT_PUBLIC_COMMUNITY_TABLE_ID = tblOUWrv9BFn7eZR
NEXT_PUBLIC_COMMUNITY_PERSON_TABLE_ID = tblJMtfXLvZA3Wdj

NEXT_PUBLIC_NGO_BASE_ID = KtNrbiQNYaYNprsQgToc3AqPnle
NEXT_PUBLIC_NGO_TABLE_ID = tbliMpQoBw2DUsLO
NEXT_PUBLIC_NGO_TABLE_ID = tbliMpQoBw2DUsLO
NEXT_PUBLIC_NGO_YEAR_STATISTIC_TABLE_ID = tblY4FT9OuiNhBxs
NEXT_PUBLIC_NGO_CITY_STATISTIC_TABLE_ID = tblO7H3pRSLt2Cnd
NEXT_PUBLIC_NGO_TYPE_STATISTIC_TABLE_ID = tbl69mz6wQTP3YWp
NEXT_PUBLIC_NGO_TAG_STATISTIC_TABLE_ID = tbl3KZefiyEqghcm
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: CI & CD
on:
push:
branches:
- '*'

jobs:
Build-and-Deploy:
Expand Down
20 changes: 7 additions & 13 deletions components/Activity/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { text2color, TimeDistance } from 'idea-react';
import { TimeDistance } from 'idea-react';
import { TableCellLocation } from 'mobx-lark';
import type { FC } from 'react';
import { Badge, Card, Col, Row } from 'react-bootstrap';
import { Card, Col, Row } from 'react-bootstrap';

import { type Activity, ActivityModel } from '../../models/Activity';
import { LarkImage } from '../Base/LarkImage';
import { TagNav } from '../Base/TagNav';
import { TimeOption } from '../data';

export interface ActivityCardProps extends Activity {
Expand Down Expand Up @@ -59,17 +60,10 @@ export const ActivityCard: FC<ActivityCardProps> = ({
</Row>
<Row as="footer" className="flex-fill small mt-1">
<Col xs={8}>
{(host as string[])?.map(organizer => (
<Badge
key={organizer}
className="me-2 text-decoration-none"
bg={text2color(organizer, ['light'])}
as="a"
href={`/search/activity?keywords=${organizer}`}
>
{organizer}
</Badge>
))}
<TagNav
list={host as string[]}
linkOf={organizer => `/search/activity?keywords=${organizer}`}
/>
</Col>
<Col className="text-end" xs={4}>
<TimeDistance {...TimeOption} date={startTime as number} />
Expand Down
7 changes: 5 additions & 2 deletions components/Article/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@ export const ArticleCard: FC<ArticleCardProps> = ({
</Col>
</Row>
<Row as="footer" className="flex-fill small mt-1">
<TagNav className="col-8" model="article" list={tags as string[]} />

<TagNav
className="col-8"
linkOf={value => `/search/article?keywords=${value}`}
list={tags as string[]}
/>
<Col className="text-end" xs={4}>
<TimeDistance {...TimeOption} date={publishedAt as number} />
</Col>
Expand Down
24 changes: 16 additions & 8 deletions components/Base/TagNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,29 @@ import { FC, HTMLAttributes } from 'react';
import { Badge } from 'react-bootstrap';

export interface TagNavProps extends HTMLAttributes<HTMLElement> {
model: string;
linkOf?: (value: string) => string;
list: string[];
onCheck?: (value: string) => any;
}

export const TagNav: FC<TagNavProps> = ({ model, list, ...props }) => (
<nav {...props}>
export const TagNav: FC<TagNavProps> = ({
className = '',
list,
linkOf,
onCheck,
...props
}) => (
<nav className={`d-flex flex-wrap gap-2 ${className}`} {...props}>
{list.map(tag => (
<Badge
key={tag}
key={tag + ''}
as="a"
className="text-decoration-none mx-1"
bg={text2color(tag, ['light'])}
href={`/search/${model}?keywords=${tag}`}
className={`text-decoration-none ${onCheck ? 'cursor-pointer' : ''}`}
bg={text2color(tag + '', ['light'])}
href={linkOf?.(tag)}
onClick={onCheck && (() => onCheck(tag))}
>
{tag}
{tag + ''}
</Badge>
))}
</nav>
Expand Down
8 changes: 6 additions & 2 deletions components/Department/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@ export const GroupCard: FC<GroupCardProps> = ({
alt={name as string}
/>
)}
{tags && <TagNav model="department" list={tags as string[]} />}

{tags && (
<TagNav
linkOf={value => `/search/department?keywords=${value}`}
list={tags as string[]}
/>
)}
{email && (
<dl className="mt-1 d-flex align-items-start">
<dt className="me-1">E-mail:</dt>
Expand Down
7 changes: 5 additions & 2 deletions components/Issue/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ export const IssueCard: FC<IssueCardProps> = ({
</a>
</Card.Title>
<Row className="flex-fill small mt-1">
<TagNav className="col-8" model="issue" list={type as string[]} />

<TagNav
className="col-8"
linkOf={value => `/search/issue?keywords=${value}`}
list={type as string[]}
/>
<Col className="text-end" xs={4}>
{typeof deadline === 'number' && deadline > 0 ? (
<TimeDistance {...TimeOption} date={deadline} />
Expand Down
10 changes: 4 additions & 6 deletions components/Map/CityStatisticMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import dynamic from 'next/dynamic';
import { MarkerMeta, OpenReactMapProps } from 'open-react-map';
import { Component } from 'react';

import { StatisticTrait } from '../../models/Activity';
import metaStore from '../../models/Base/System';
import { OrganizationStatistic } from '../../models/Community/Organization';

const ChinaMap = dynamic(() => import('./ChinaMap'), { ssr: false });

export interface CityStatisticMapProps {
store: StatisticTrait;
data: OrganizationStatistic['city'];
onChange?: (city: string) => any;
}

Expand All @@ -22,16 +22,14 @@ export class CityStatisticMap extends Component<CityStatisticMapProps> {

componentDidMount() {
metaStore.getCityCoordinate();

this.props.store.getStatistic();
}

@computed
get markers() {
const { cityCoordinate } = metaStore,
{ city = {} } = this.observedProps.store.statistic;
{ data } = this.observedProps;

return Object.entries(city)
return Object.entries(data)
.map(([city, count]) => {
const point = cityCoordinate[city];

Expand Down
47 changes: 20 additions & 27 deletions components/Organization/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Icon, text2color } from 'idea-react';
import { Icon } from 'idea-react';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import { Component, HTMLAttributes } from 'react';
import { Badge, Button, Card, CardProps, Image } from 'react-bootstrap';
import { Button, Card, CardProps, Image } from 'react-bootstrap';

import { t } from '../../models/Base/Translation';
import { Organization } from '../../models/Community/Organization';
import { LarkImage } from '../Base/LarkImage';
import { TagNav } from '../Base/TagNav';

export interface OrganizationCardProps
extends Pick<HTMLAttributes<HTMLDivElement>, 'className' | 'style'>,
Expand Down Expand Up @@ -88,38 +89,30 @@ export class OrganizationCard extends Component<OrganizationCardProps> {
<Card.Body>
<Card.Title>
{name as string}
<Badge
className="ms-2 cursor-pointer"
bg={text2color(type + '', ['light'])}
onClick={
<TagNav
className="ms-2"
list={[type as string]}
onCheck={
onSwitch &&
(() =>
confirm(t('confirm_community_type_filter', { type })) &&
onSwitch({ type: type as string }))
}
>
{type + ''}
</Badge>
/>
</Card.Title>

<Card.Text className="d-flex flex-wrap justify-content-end gap-2">
{(tags as string[])?.map(tag => (
<Badge
key={tag}
bg={text2color(tag, ['light'])}
className="cursor-pointer"
onClick={
onSwitch &&
(() =>
confirm(t('confirm_community_tag_filter', { tag })) &&
onSwitch({ tags: [tag] }))
}
>
{tag}
</Badge>
))}
</Card.Text>

{tags && (
<TagNav
className="justify-content-end"
list={tags as string[]}
onCheck={
onSwitch &&
(tag =>
confirm(t('confirm_community_tag_filter', { tag })) &&
onSwitch({ tags: [tag] }))
}
/>
)}
<Card.Text
className="d-none d-sm-block text-wrap overflow-auto"
style={{ minHeight: '5rem', maxHeight: '10rem' }}
Expand Down
94 changes: 57 additions & 37 deletions components/Organization/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { text2color } from 'idea-react';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import { ScrollList } from 'mobx-restful-table';
import dynamic from 'next/dynamic';
import { Component } from 'react';
import { Badge, Button, Nav } from 'react-bootstrap';
import { isEmpty } from 'web-utility';
import { Accordion, Button, Nav } from 'react-bootstrap';
import { sum } from 'web-utility';

import { i18n, t } from '../../models/Base/Translation';
import { OrganizationModel } from '../../models/Community/Organization';
import {
OrganizationModel,
OrganizationStatistic,
} from '../../models/Community/Organization';
import { TagNav } from '../Base/TagNav';
import { CityStatisticMap } from '../Map/CityStatisticMap';
import { OrganizationCardProps } from './Card';
import { OrganizationListLayout } from './List';

const OrganizationCharts = dynamic(() => import('./Charts'), { ssr: false });

export interface OpenCollaborationMapProps {
export interface OpenCollaborationMapProps extends OrganizationStatistic {
store: OrganizationModel;
}

Expand Down Expand Up @@ -45,42 +48,59 @@ export class OpenCollaborationMap extends Component<OpenCollaborationMapProps> {
};

renderFilter() {
const { filter, totalCount } = this.props.store;
const { type, tag } = this.props,
{ filter, totalCount } = this.props.store;
const count =
totalCount != null && totalCount !== Infinity
? totalCount
: (type[filter.type + ''] ??
tag[filter.tags + ''] ??
sum(...Object.values(type)));

return (
!isEmpty(filter) && (
<header
className="d-flex justify-content-between align-items-center sticky-top bg-white py-3"
style={{ top: '5rem' }}
>
<div>
{t('filter')}
{Object.entries(filter).map(([key, value]) => (
<Badge
key={key}
className="mx-2"
bg={text2color(value + '', ['light'])}
>
{value + ''}
</Badge>
))}
</div>
{t('total_x_organizations', { totalCount })}
<Button
variant="warning"
size="sm"
onClick={() => this.switchFilter({})}
>
{t('reset')}
</Button>
</header>
)
<Accordion
as="header"
className="sticky-top bg-white"
style={{ top: '5rem' }}
>
<Accordion.Item eventKey="0">
<Accordion.Header>
<div className="w-100 d-flex justify-content-between align-items-center">
{t('filter')}

<TagNav list={Object.values(filter) as string[]} />

{t('total_x_organizations', { totalCount: count })}
</div>
</Accordion.Header>
<Accordion.Body as="form" onReset={() => this.switchFilter({})}>
<fieldset className="mb-3">
<legend>{t('type')}</legend>

<TagNav
list={Object.keys(type)}
onCheck={type => this.switchFilter({ type })}
/>
</fieldset>
<fieldset className="mb-3">
<legend>{t('tag')}</legend>

<TagNav
list={Object.keys(tag)}
onCheck={tags => this.switchFilter({ tags })}
/>
</fieldset>
<Button type="reset" variant="warning" size="sm">
{t('reset')}
</Button>
</Accordion.Body>
</Accordion.Item>
</Accordion>
);
}

renderTab() {
const { props, tabKey } = this,
{ statistic } = props.store;
const { props, tabKey } = this;

return (
<div>
Expand All @@ -101,10 +121,10 @@ export class OpenCollaborationMap extends Component<OpenCollaborationMapProps> {
</Nav>

{tabKey !== 'map' ? (
<OrganizationCharts {...statistic} />
<OrganizationCharts {...props} />
) : (
<CityStatisticMap
store={props.store}
data={props.city}
onChange={city => this.switchFilter({ city })}
/>
)}
Expand Down
Loading
Loading