antd#Skeleton TypeScript Examples
The following examples show how to use
antd#Skeleton.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: UserListItem.tsx From tailchat with GNU General Public License v3.0 | 6 votes |
UserListItem: React.FC<UserListItemProps> = React.memo((props) => {
const { actions = [] } = props;
const userInfo = useCachedUserInfo(props.userId);
const [isOnline] = useCachedOnlineStatus([props.userId]);
const userName = userInfo.nickname;
const handleClick = useCallback(() => {
// TODO 点击展开用户信息卡片
console.log('clicked avatar');
}, []);
return (
<div className="flex items-center h-14 px-2.5 rounded group bg-black bg-opacity-0 hover:bg-opacity-20 dark:bg-white dark:bg-opacity-0 dark:hover:bg-opacity-20">
<Skeleton
loading={_isEmpty(userInfo)}
avatar={true}
title={false}
active={true}
>
<div className="mr-2" onClick={handleClick}>
<Avatar src={userInfo.avatar} name={userName} isOnline={isOnline} />
</div>
<div className="flex-1 text-gray-900 dark:text-white">
<span>{userName}</span>
<span className="text-gray-500 dark:text-gray-300 opacity-0 group-hover:opacity-100">
#{userInfo.discriminator}
</span>
</div>
<Space>{...actions}</Space>
</Skeleton>
</div>
);
})
Example #2
Source File: index.tsx From electron with MIT License | 6 votes |
Wrap: React.FC = () => {
return (
<section className="flex-col ui-pt-40">
<section className="ui-mb-40">
<SystemController />
<Skeleton active></Skeleton>
</section>
<section>
<SystemController os="win32" />
<Skeleton active></Skeleton>
</section>
</section>
);
}
Example #3
Source File: index.tsx From react-enterprise-starter-pack with MIT License | 6 votes |
Home: React.FC = () => {
const { tasksStore } = useContext(RootStore)
if (!tasksStore.tasks) {
tasksStore.fetchTasks()
return (
<div className="text-center max-w-md m-auto pt-12">
<Spin tip="Loading..."></Spin>
<div className="max-w-sm m-auto mt-2">
<Skeleton active paragraph={{ rows: 2 }} title={false} />
</div>
</div>
)
}
return (
<div className="px-8 pt-12 max-w-md m-auto text-center text-blue-300 border-b border-blue-300">
<Trans>Hello world</Trans>
<br />
<Plural
value={tasksStore.total}
_0="You don't have any task to do"
one="You successfully fetched # task"
other="You successfully fetched # tasks"
/>
<div className="mt-2 mb-5">
<StyledButton type="primary" size="small">
<Trans>I'm a Button</Trans>
</StyledButton>
</div>
</div>
)
}
Example #4
Source File: QueueCard.tsx From office-hours with GNU General Public License v3.0 | 6 votes |
export function QueueCardSkeleton(): ReactElement {
return (
<PaddedCard
headStyle={{
background: "#25426C",
color: "#FFFFFF",
borderRadius: "6px 6px 0 0",
}}
className={"open-queue-card"}
title={<Skeleton title={false} paragraph={{ rows: 1 }} />}
>
<QueueInfoRow>
<Skeleton title paragraph={{ rows: 0 }} />
<Skeleton.Button size="large" />
</QueueInfoRow>
<Skeleton.Avatar size={96} />
<QueueCardDivider />
<Row justify="space-between" align="bottom">
<NotesSkeleton title={false} paragraph={{ rows: 1 }} />
<Skeleton.Button size="large" style={{ marginTop: "12px" }} />
</Row>
</PaddedCard>
);
}
Example #5
Source File: Container.tsx From datart with Apache License 2.0 | 6 votes |
Container: FC<ContainerProps> = memo(props => {
const t = useI18NPrefix('view.properties');
const { title, children, loading, ...rest } = props;
return (
<StyledContainer>
<ListTitle title={t(title)} {...rest} />
<Skeleton active loading={loading}>
{children}
</Skeleton>
</StyledContainer>
);
})
Example #6
Source File: index.tsx From nanolooker with MIT License | 6 votes |
Price = () => {
const { cryptocurrency } = React.useContext(PreferencesContext);
const { isInitialLoading } = React.useContext(MarketStatisticsContext);
const skeletonProps = {
active: true,
paragraph: false,
loading: isInitialLoading,
};
const defaultCryptocurrency = SupportedCryptocurrency.find(
({ symbol }) => symbol === "nano",
) as CryptocurrencyPriceProps;
return (
<>
<Skeleton {...skeletonProps}>
<CryptocurrencyPrice {...defaultCryptocurrency} />
{cryptocurrency.map(symbol => {
const crypto = SupportedCryptocurrency.find(
({ symbol: supportedSymbol }) => supportedSymbol === symbol,
);
return crypto ? (
<CryptocurrencyPrice {...crypto} key={symbol} />
) : null;
})}
</Skeleton>
</>
);
}
Example #7
Source File: home.tsx From config-generator with MIT License | 6 votes |
public renderLayout() {
if (this.isReadyToRender()) {
return <RenderLayout></RenderLayout>;
} else {
return (
<Layout>
<Skeleton active />
</Layout>
);
}
}
Example #8
Source File: UserOrganizationsList.tsx From condo with MIT License | 6 votes |
UserOrganizationsList = ({ userOrganization }) => {
const { user } = useAuth()
const { objs: userOrganizations, loading } = OrganizationEmployee.useObjects(
{ where: user ? { user: { id: user.id }, isAccepted: true } : {} },
{ fetchPolicy: 'network-only' }
)
const list = userOrganizations.map((employee, index) => (
<OrganizationEmployeeItem
employee={employee}
key={index}
userOrganization={userOrganization}
/>
))
return (
<Row gutter={[0, 60]}>
{
loading
? <Skeleton active/>
: list
}
</Row>
)
}
Example #9
Source File: MembersPanel.tsx From tailchat with GNU General Public License v3.0 | 6 votes |
MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
const groupInfo = useGroupInfo(props.groupId);
const members = groupInfo?.members ?? [];
const userInfoList = useUserInfoList(members.map((m) => m.userId));
const [searchStr, setSearchStr] = useState('');
const filteredGroupMembers = useMemo(() => {
return userInfoList.filter((u) => u.nickname.includes(searchStr));
}, [userInfoList, searchStr]);
if (userInfoList.length === 0) {
return <Skeleton />;
}
return (
<div>
<div className="p-2">
<Input
placeholder={t('搜索成员')}
size="large"
suffix={<Icon fontSize={20} color="grey" icon="mdi:magnify" />}
onChange={(e) => setSearchStr(e.target.value)}
/>
</div>
{filteredGroupMembers.map((member) => (
<UserListItem key={member._id} userId={member._id} />
))}
</div>
);
})
Example #10
Source File: listings-skeleton.tsx From tinyhouse with MIT License | 6 votes |
export function ListingsSkeleton({
title,
error = false,
}: ListingsSkeletonProp) {
const errorAlert = error ? (
<Alert
type="error"
message={
<>
Oh no! Something went wrong - please try again later
<span role="img" aria-label="Sad face emoji">
?
</span>
</>
}
className="listing-skeleton__alert"
/>
) : null;
return (
<div className="listings-skeleton">
{errorAlert}
<h2>
{title}
{[...Array(3)].map((_, index) => (
<div key={index}>
<Skeleton active paragraph={{ rows: 1 }} />
<Divider />
</div>
))}
</h2>
</div>
);
}
Example #11
Source File: FormSkeleton.tsx From jitsu with MIT License | 6 votes |
FormSkeleton: React.FC<Props> = () => {
return (
<Row className="w-full h-full">
<Col span={4} />
<Col span={20}>
<Skeleton active paragraph={{ rows: 2 }} />
<Skeleton active title={false} paragraph={{ rows: 3 }} className={`mt-5`} />
</Col>
</Row>
)
}
Example #12
Source File: index.tsx From ant-design-pro-V4 with MIT License | 6 votes |
PageHeaderContent: FC<{ currentUser: Partial<CurrentUser> }> = ({ currentUser }) => {
const loading = currentUser && Object.keys(currentUser).length;
if (!loading) {
return <Skeleton avatar paragraph={{ rows: 1 }} active />;
}
return (
<div className={styles.pageHeaderContent}>
<div className={styles.avatar}>
<Avatar size="large" src={currentUser.avatar} />
</div>
<div className={styles.content}>
<div className={styles.contentTitle}>
早安,
{currentUser.name}
,祝你开心每一天!
</div>
<div>
{currentUser.title} |{currentUser.group}
</div>
</div>
</div>
);
}
Example #13
Source File: TimezoneConfig.tsx From posthog-foss with MIT License | 6 votes |
export function TimezoneConfig(): JSX.Element {
const { preflight } = useValues(preflightLogic)
const { currentTeam, currentTeamLoading } = useValues(teamLogic)
const { updateCurrentTeam } = useActions(teamLogic)
if (!preflight?.available_timezones || !currentTeam) {
return <Skeleton paragraph={{ rows: 0 }} active />
}
return (
<div>
<Select
showSearch
placeholder="Select a timezone"
style={{ width: '20rem', maxWidth: '100%' }}
loading={currentTeamLoading}
disabled={currentTeamLoading}
value={currentTeam.timezone}
onChange={(val) => updateCurrentTeam({ timezone: val })}
data-attr="timezone-select"
>
{Object.entries(preflight.available_timezones).map(([tz, offset]) => {
const display = `${tz.replace(/\//g, ' / ').replace(/_/g, ' ')} (UTC${
offset > 0 ? '+' : '-'
}${Math.abs(offset)})`
return (
<Select.Option value={tz} key={tz}>
{display}
</Select.Option>
)
})}
</Select>
</div>
)
}
Example #14
Source File: index.tsx From metaplex with Apache License 2.0 | 5 votes |
PackSidebar = ({ onOpenPack }: IPropsPackSidebar) => {
const { pack, voucherMetadataKey, provingProcess } = usePack();
const metadataPubkey = voucherMetadataKey || '';
const art = useArt(metadataPubkey);
const uri = pack?.info.uri;
const { publicKey } = useWallet();
const userWallet = pubkeyToString(publicKey);
const isExhausted = provingProcess?.info.isExhausted;
const shouldEnableRedeem =
process.env.NEXT_ENABLE_NFT_PACKS_REDEEM === 'true';
return (
<div className="pack-view__sidebar">
<div className="pack-view__owner">
<div className="item-title">Owner</div>
{(art.creators || []).map(creator => (
<div key={creator.address}>
<MetaAvatar creators={[creator]} size={32} />
<span className="item-name">
{creator.name || shortenAddress(creator?.address || '')}
</span>
{userWallet === creator.address && (
<div className="you-label">You</div>
)}
</div>
))}
</div>
<Divider className="divider" />
<div className="pack-view__art-preview">
{uri && <ArtContent uri={uri} active allowMeshRender artView />}
{!uri && <Skeleton.Image />}
</div>
<h4 className="pack-view__name">
{pack?.info?.name || <Skeleton paragraph={{ rows: 1 }} />}
</h4>
<div className="pack-view__info">
<div className="info-item">
<div className="info-item__title">PACK OF</div>
<div className="info-item__value">
{pack?.info?.packCards || 0} NFTs
</div>
</div>
<div className="info-item">
<div className="info-item__title">Royalties</div>
<div className="info-item__value">
{royalty(art.seller_fee_basis_points)}
</div>
</div>
<div className="info-item">
<ViewOn id={metadataPubkey} />
</div>
</div>
<Divider className="divider" />
{shouldEnableRedeem && !isExhausted && (
<OpenPackButton onClick={onOpenPack} />
)}
<Divider className="divider" />
<div className="pack-view__description-block">
<p className="pack-view__title">DETAILS</p>
<p className="pack-view__text">
{pack?.info?.description || <Skeleton paragraph={{ rows: 3 }} />}
</p>
</div>
<div className="pack-view__info-mobile">
<div className="info-item">
<ViewOn id={metadataPubkey} />
</div>
<Divider className="divider" />
</div>
</div>
);
}
Example #15
Source File: DataAttributes.tsx From posthog-foss with MIT License | 5 votes |
export function DataAttributes(): JSX.Element {
const { currentTeam, currentTeamLoading } = useValues(teamLogic)
const { updateCurrentTeam } = useActions(teamLogic)
const [value, setValue] = useState([] as string[])
useEffect(() => setValue(currentTeam?.data_attributes || []), [currentTeam])
if (!currentTeam) {
return <Skeleton paragraph={{ rows: 0 }} active />
}
return (
<>
<p>
Specify a comma-separated list of{' '}
<a
href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes"
rel="noreferrer noopener"
>
data attributes
</a>{' '}
used in your app. For example: <code>data-attr, data-custom-id, data-myref-*</code>. These attributes
will be used when using the toolbar and defining actions to match unique elements on your pages. You can
use <code>*</code> as a wildcard.
</p>
<p>
For example, when creating an action on your CTA button, the best selector could be something like:{' '}
<code>div > form > button:nth-child(2)</code>. However all buttons in your app have a{' '}
<code>data-custom-id</code> attribute. If you whitelist it here, the selector for your button will
instead be <code>button[data-custom-id='cta-button']</code>.
</p>
<div>
<Select
mode="tags"
style={{ maxWidth: '40rem', marginBottom: '1rem', display: 'block' }}
onChange={(values) => setValue(values || [])}
value={value}
data-attr="data-attribute-select"
placeholder={'data-attr, ...'}
loading={currentTeamLoading}
disabled={currentTeamLoading}
/>
<Button
type="primary"
onClick={() =>
updateCurrentTeam({ data_attributes: value.map((s) => s.trim()).filter((a) => a) || [] })
}
>
Save
</Button>
</div>
</>
)
}
Example #16
Source File: ChatBoxPlaceholder.tsx From tailchat with GNU General Public License v3.0 | 5 votes |
ChatBoxPlaceholder: React.FC = React.memo(() => {
const paragraph = { rows: 1 };
return (
<div className="px-2 w-2/3">
<Skeleton
className="mb-2"
active={true}
avatar={true}
paragraph={paragraph}
/>
<Skeleton
className="mb-2"
active={true}
avatar={true}
paragraph={paragraph}
/>
<Skeleton
className="mb-2"
active={true}
avatar={true}
paragraph={paragraph}
/>
<Skeleton
className="mb-2"
active={true}
avatar={true}
paragraph={paragraph}
/>
<Skeleton
className="mb-2"
active={true}
avatar={true}
paragraph={paragraph}
/>
<Skeleton
className="mb-2"
active={true}
avatar={true}
paragraph={paragraph}
/>
<Skeleton
className="mb-2"
active={true}
avatar={true}
paragraph={paragraph}
/>
<Skeleton
className="mb-2"
active={true}
avatar={true}
paragraph={paragraph}
/>
<Skeleton
className="mb-2"
active={true}
avatar={true}
paragraph={paragraph}
/>
<Skeleton
className="mb-2"
active={true}
avatar={true}
paragraph={paragraph}
/>
</div>
);
})
Example #17
Source File: StatsCard.tsx From condo with MIT License | 5 votes |
StatsCard: React.FC<IStatsCardProps> = (props) => {
const intl = useIntl()
const extraTitle = intl.formatMessage({ id: 'component.statscard.ExtraTitle' })
const SELECTED_PERIOD: SelectedPeriod = {
calendarWeek: intl.formatMessage({ id: 'component.statscard.periodtypes.Week' }),
month: intl.formatMessage({ id: 'component.statscard.periodtypes.Month' }),
quarter: intl.formatMessage({ id: 'component.statscard.periodtypes.Quarter' }),
year: intl.formatMessage({ id: 'component.statscard.periodtypes.Year' }),
}
const { title, children, link, loading = false, onFilterChange, dependencyArray } = props
const [selectedPeriod, setSelectedPeriod] = useState<string>(Object.keys(SELECTED_PERIOD)[0])
const updateDependencies = [selectedPeriod, ...dependencyArray]
useEffect(() => {
onFilterChange(selectedPeriod)
}, updateDependencies)
const menuClick = useCallback(({ key }) => { setSelectedPeriod(key)}, [])
const linkClick = useCallback(() => { Router.push(link) }, [link])
const menuOverlay = (
<Menu onClick={menuClick} disabled={loading}>
{
Object.keys(SELECTED_PERIOD).map((period) => (
<Menu.Item key={period}>{SELECTED_PERIOD[period]}</Menu.Item>
))
}
</Menu>
)
const cardTitle = (
<Space css={cardTitleCss}>
{title}
<Dropdown overlay={menuOverlay} >
<span style={DROPDOWN_TEXT_STYLE}>{SELECTED_PERIOD[selectedPeriod]} <DownOutlined /></span>
</Dropdown>
</Space>
)
const cardExtra = (
<Button style={CARD_EXTRA_STYLE} type={'inlineLink'} onClick={linkClick}>
{extraTitle}{<RightOutlined />}
</Button>
)
return (
<Row gutter={STATS_CARD_ROW_GUTTER} align={'middle'}>
<Col span={24}>
<Card
title={cardTitle}
bordered={false}
headStyle={CARD_HEAD_STYLE}
extra={cardExtra}
>
{loading ? <Skeleton active round paragraph={{ rows: 1 }} /> : children}
</Card>
</Col>
</Row>
)
}
Example #18
Source File: index.tsx From nanolooker with MIT License | 5 votes |
ActiveDifficulty: React.FC = () => {
const { t } = useTranslation();
const [isLoading, setIsLoading] = React.useState(false);
const {
activeDifficulty: { network_minimum, network_current, multiplier },
getActiveDifficulty,
}: UseActiveDifficultyReturn = useActiveDifficulty();
const refreshActiveDifficulty = async () => {
setIsLoading(true);
await refreshActionDelay(getActiveDifficulty);
setIsLoading(false);
};
const opacity = isLoading ? 0.5 : 1;
return (
<Card
size="small"
title={t("pages.status.activeDifficulty")}
extra={
<Tooltip title={t("pages.status.reload")}>
<Button
type="primary"
icon={<ReloadOutlined />}
size="small"
onClick={refreshActiveDifficulty}
loading={isLoading}
/>
</Tooltip>
}
>
<Skeleton active loading={!network_current}>
<Statistic
title={t("pages.status.networkMinimum")}
value={network_minimum}
style={{ opacity }}
/>
<Statistic
title={t("pages.status.networkCurrent")}
value={network_current}
style={{ opacity }}
/>
<Statistic
title={t("pages.status.multiplier")}
value={multiplier}
style={{ opacity }}
/>
</Skeleton>
</Card>
);
}
Example #19
Source File: BillingEnrollment.tsx From posthog-foss with MIT License | 5 votes |
function Plan({ plan, onSubscribe }: { plan: PlanInterface; onSubscribe: (plan: PlanInterface) => void }): JSX.Element {
const [detail, setDetail] = useState('')
const [isDetailLoading, setIsDetailLoading] = useState(true)
const loadPlanDetail = async (key: string): Promise<void> => {
const response = await fetch(`/api/plans/${key}/template/`)
if (response.ok) {
setDetail(await response.text())
}
setIsDetailLoading(false)
}
useEffect(() => {
loadPlanDetail(plan.key)
}, [plan.key])
return (
<Card>
<div className="cursor-pointer" onClick={() => onSubscribe(plan)}>
<img src={plan.image_url || defaultImg} alt="" height={100} width={100} />
<h3 style={{ fontSize: 22 }}>{plan.name}</h3>
<div style={{ fontWeight: 'bold', marginBottom: 16, fontSize: 16 }}>{plan.price_string}</div>
</div>
<div>
<Button
data-attr="btn-subscribe-now"
data-plan={plan.key}
type="primary"
onClick={() => onSubscribe(plan)}
>
Subscribe now
</Button>
</div>
{isDetailLoading ? (
<Skeleton paragraph={{ rows: 6 }} title={false} className="mt" active />
) : (
<div className="plan-description" dangerouslySetInnerHTML={{ __html: detail }} />
)}
</Card>
)
}
Example #20
Source File: QueueCard.tsx From office-hours with GNU General Public License v3.0 | 5 votes |
NotesSkeleton = styled(Skeleton)`
width: 60%;
`
Example #21
Source File: index.tsx From metaplex with Apache License 2.0 | 5 votes |
PreSaleBanner = ({ auction }: IPreSaleBanner) => {
const { isLoading } = useMeta();
const id = auction?.thumbnail.metadata.pubkey;
const art = useArt();
if (isLoading) {
return <Skeleton />;
}
return (
<Row className="presale">
<Col md={12} className="explore">
<ArtContent
pubkey={id}
className="artwork-image"
allowMeshRender={true}
/>
</Col>
<Col md={12} className="presale-info">
<h2 className="art-title">{art.title}</h2>
{auction && (
<AuctionCard
auctionView={auction}
style={{
background: 'transparent',
width: '100%',
padding: 0,
margin: 0,
}}
hideDefaultAction={true}
action={
<>
<Link to={`/auction/${auction.auction.pubkey}`}>
<Button
type="primary"
size="large"
className="action-btn"
style={{ maxWidth: 290 }}
>
Go to auction
</Button>
</Link>
</>
}
/>
)}
</Col>
</Row>
);
}
Example #22
Source File: index.tsx From RareCamp with Apache License 2.0 | 5 votes |
Home = () => {
const router = useRouter()
const { data, isLoading } = useQuery<any>(
'defaultWorkspace',
() => axios.get('/workspaces/default'),
{ retry: false },
)
if (!isLoading && !data?.data?.workspace?.programs?.length)
router.push('/workspace/intro')
useEffect(() => {}, [data])
return (
<AppLayout
title={<PageTitle title="Programs" />}
selectedKey="programs"
>
<UserHeader
getContent={(userInfo) => ({
title: `Hello ${userInfo.name}, welcome back!`,
description: `Here's info about your programs`,
})}
/>
{isLoading || !data?.data?.workspace?.programs?.length ? (
<Skeleton />
) : (
<ProgramCards>
{data?.data?.workspace?.programs.map((program) => (
<Card
key={program.programId}
bordered
style={{ width: 284 }}
>
<Space
style={{
justifyContent: 'space-between',
width: '100%',
}}
>
<Link
href={`/programs/${program.workspaceId}/${program.programId}`}
>
<a>
<Title level={4}>{program.name}</Title>
</a>
</Link>
<EditProgram program={program} />
</Space>
<p>{program.description}</p>
</Card>
))}
<Card bordered style={{ width: 284 }}>
<Link href="/workspace/intro">
<a>
<div className="add-program">
<PlusCircleTwoTone style={{ fontSize: 33 }} />
<div>Add program</div>
</div>
</a>
</Link>
</Card>
</ProgramCards>
)}
</AppLayout>
)
}
Example #23
Source File: PlayerMeta.tsx From posthog-foss with MIT License | 5 votes |
export function PlayerMeta(): JSX.Element {
const { sessionPerson, description, resolution, scale, recordingStartTime, loading } = useValues(metaLogic)
return (
<Col className="player-meta-container">
<Row className="player-meta-person" align="middle" justify="space-between" wrap={false}>
<Row className="player-meta-person-title" align="middle" wrap={false}>
{loading ? (
<Space>
<Skeleton.Avatar active size="small" shape="circle" />
<Skeleton title={false} active paragraph={{ rows: 1, width: 160 }} />
</Space>
) : (
<>
<ProfilePicture
name={sessionPerson?.name}
email={sessionPerson?.properties?.$email}
size="md"
style={{ marginRight: '0.5rem' }}
/>
<span className="email">
<PersonHeader person={sessionPerson} withIcon={false} />
</span>
</>
)}
</Row>
<Col>
{loading ? (
<Skeleton title={false} active paragraph={{ rows: 1, width: 80 }} />
) : (
<span className="time text-muted">
{recordingStartTime && <TZLabel time={dayjs(recordingStartTime)} />}
</span>
)}
</Col>
</Row>
<Row className="player-meta-other" align="middle" justify="start">
<Row className="player-meta-other-description">
{loading ? <Skeleton title={false} active paragraph={{ rows: 1 }} /> : <span>{description}</span>}
</Row>
<Row className="player-meta-other-resolution mt-05">
{loading ? (
<Skeleton title={false} active paragraph={{ rows: 1, width: '100%' }} />
) : (
<span>
{resolution ? (
<>
Resolution: {resolution.width} x {resolution.height} (
{formatDisplayPercentage(scale)}%)
</>
) : (
<>Resolution: ...</>
)}
</span>
)}
</Row>
</Row>
</Col>
)
}
Example #24
Source File: index.tsx From scorpio-h5-design with MIT License | 5 votes |
export default function() {
return (
<Skeleton active />
);
}
Example #25
Source File: SourceCard.tsx From jitsu with MIT License | 5 votes |
function LastTaskStatus({ sourceId }) {
const services = useServices()
const {
error,
data: task,
isLoading,
} = useLoaderAsObject(async () => {
let tasks = await services.backendApiClient.get("/tasks", {
proxy: true,
urlParams: {
project_id: services.activeProject.id,
source: `${services.activeProject.id}.${sourceId}`,
end: new Date().toISOString(),
start: moment().subtract(90, "days").toISOString(),
limit: 100,
},
})
const tasksSorted = tasks.tasks.sort(comparator<Task>(t => new Date(t.finished_at)))
return tasksSorted?.[0]
})
if (isLoading) {
return <Skeleton active title={false} paragraph={{ rows: 1, width: ["100%"] }} className="w-full" />
}
//workaround: "doesn't exist" really means no tasks
if (!task?.status && (error?.message || "").indexOf("doesn't exist")) {
return (
<Tooltip overlay={<>This connector hasn't been started yet</>}>
<Tag color="default">NO RUNS</Tag>
</Tooltip>
)
}
if (error) {
return <Tag color="error">ERROR !</Tag>
}
const date = task.finished_at ? moment.utc(task.finished_at) : null
const now = moment.utc(new Date().toISOString())
return (
<span>
<NavLink
to={projectRoute(sourcesPageRoutes.task, {
sourceId: sourceId,
taskId: TaskId.encode(task.id),
})}
>
<Tag color={task.status === "SUCCESS" ? "success" : "error"}>{task.status.toUpperCase()}</Tag>
<a className="text-xs text-secondaryText underline">{date?.from(now)}</a>
</NavLink>
</span>
)
}
Example #26
Source File: [[...id]].tsx From RareCamp with Apache License 2.0 | 5 votes |
export default function ProgramDetails() {
const router = useRouter()
const { id } = router.query
let workspaceId
let programId
if (id) [workspaceId, programId] = id as string[]
const programQuery = useQuery(
['program', programId],
() =>
axios.get(`/workspaces/${workspaceId}/programs/${programId}`),
{ retry: 0, enabled: Boolean(workspaceId && programId) },
)
const [isAddProjectVisible, setIsAddProjectVisible] =
useState(false)
const hideAddProjectBtn = () => setIsAddProjectVisible(false)
const program = programQuery?.data?.data?.program
const ProgramTitle = (
<PageHeading
title={program?.name}
description={program?.description}
renderEdit={() => program && <EditProgram program={program} />}
/>
)
return (
<AppLayout
title={ProgramTitle}
selectedKey={`program_${program?.programId}`}
>
{programQuery.isLoading ? (
<Skeleton />
) : (
<ProgramDetailsLayout>
{programQuery.isError ? (
<Result
status="500"
title="Program can not be found"
subTitle="Sorry, something went wrong."
extra={<BackToHome />}
/>
) : (
<MainContent direction="vertical" size={16}>
<Button
onClick={() => setIsAddProjectVisible(true)}
icon={<PlusOutlined />}
>
Add Project
</Button>
<OTTable
program={program}
isAddProjectVisible={isAddProjectVisible}
hideAddProjectBtn={hideAddProjectBtn}
/>
</MainContent>
)}
</ProgramDetailsLayout>
)}
</AppLayout>
)
}
Example #27
Source File: index.tsx From posthog-foss with MIT License | 5 votes |
function DomainWhitelist({ isRestricted }: RestrictedComponentProps): JSX.Element {
const { socialAuthAvailable } = useValues(preflightLogic)
const { currentOrganization, currentOrganizationLoading } = useValues(organizationLogic)
const { updateOrganization } = useActions(organizationLogic)
const [localList, setLocalList] = useState([] as string[])
useEffect(() => setLocalList(currentOrganization?.domain_whitelist || []), [currentOrganization?.domain_whitelist])
return (
<div>
<h2 id="domain-whitelist" className="subtitle">
Domain Whitelist
</h2>
{socialAuthAvailable ? (
<div>
Trusted domains for authentication. When <b>new users</b> log in through a social provider (e.g.
Google) using an email address on any of your whitelisted domains, they'll be{' '}
<b>automatically added to this organization.</b>
<div className="mt-05">
{currentOrganization ? (
<Select
mode="tags"
placeholder="Add whitelisted domains (e.g. hogflix.com or movies.hogflix.com)"
onChange={(val) => setLocalList(val as string[])}
loading={currentOrganizationLoading}
style={{ width: '40rem', maxWidth: '100%' }}
onBlur={() => updateOrganization({ domain_whitelist: localList })}
value={localList}
disabled={isRestricted}
>
{currentOrganization.domain_whitelist.map((domain) => (
<Select.Option key={domain} value={domain}>
{domain}
</Select.Option>
))}
</Select>
) : (
<Skeleton active />
)}
</div>
</div>
) : (
<div className="text-muted">
This feature is only available when social authentication is enabled.{' '}
<a
href="https://posthog.com/docs/features/sso?utm_campaign=domain-whitelist&utm_medium=in-product"
target="_blank"
rel="noopener"
>
Learn more <IconOpenInNew />
</a>
</div>
)}
</div>
)
}
Example #28
Source File: DebugEvents.tsx From jitsu with MIT License | 5 votes |
DebugEvents = ({ handleClick }: Props) => {
const services = ApplicationServices.get()
const { data: eventsData, isLoading } = useLoaderAsObject(
async () =>
await services.backendApiClient.get(`/events/cache?project_id=${services.activeProject.id}&limit=10`, {
proxy: true,
})
)
const allEvents = useMemo(() => {
const events = eventsData?.events ?? []
if (events.length > 100) events.length = 100
return events
.map(event => ({
data: event,
time: moment(event.original._timestamp),
}))
.sort((e1: Event, e2: Event) => {
if (e1.time.isAfter(e2.time)) {
return -1
} else if (e2.time.isAfter(e1.time)) {
return 1
}
return 0
})
}, [eventsData?.events])
return (
<Card bordered={false} className={`${styles.events}`}>
{isLoading ? (
<List
dataSource={range(0, 25)}
renderItem={() => (
<Skeleton active title={false} paragraph={{ rows: 2, width: ["100%", "70%"] }} className="mb-2" />
)}
/>
) : (
<List
className={`h-full w-full overflow-y-auto overflow-x-hidden ${styles.withSmallScrollbar}`}
dataSource={allEvents}
renderItem={(item: any) => {
return (
<div
className={`flex flex-col items-stretch ${styles.eventItem}`}
onClick={handleClick(item?.data.original)}
>
<p className="truncate mb-0">{item?.time?.utc?.()?.format?.()}</p>
{item?.data?.original?.event_type ? (
<p className="truncate mb-0">{item?.data?.original?.event_type}</p>
) : (
""
)}
</div>
)
}}
/>
)}
</Card>
)
}
Example #29
Source File: Leaderboard.tsx From nanolooker with MIT License | 4 votes |
Leaderboard: React.FC<Props> = ({ topScores }) => {
const { t } = useTranslation();
const pageSize = 15;
const [currentPage, setCurrentPage] = React.useState(1);
const [paginatedTopScores, setPaginatedTopScores] = React.useState(
[] as PlayerScore[][],
);
React.useEffect(() => {
setPaginatedTopScores(chunk(topScores, pageSize));
}, [topScores]);
return (
<>
<Title level={3}>{t("pages.nanoquakejs.leaderboard")}</Title>
<Card size="small" bordered={false} className="detail-layout">
<Row gutter={12}>
<Col xs={4}>{t("pages.nanoquakejs.rank")}</Col>
<Col xs={14}>{t("pages.nanoquakejs.player")}</Col>
<Col xs={6}>{t("pages.nanoquakejs.frags")}</Col>
</Row>
{!topScores?.length ? (
Array.from(Array(5).keys()).map(index => (
<Row gutter={12} key={index}>
<Col xs={4}>
<Skeleton loading={true} paragraph={false} active />
</Col>
<Col xs={14}>
<Skeleton loading={true} paragraph={false} active />
</Col>
<Col xs={6}>
<Skeleton loading={true} paragraph={false} active />
</Col>
</Row>
))
) : (
<>
{paginatedTopScores[currentPage - 1]?.map(
({ rank, player, frags }) => (
<Row gutter={12} key={rank}>
<Col xs={4}>
<Text
style={{ fontSize: fontSizeToRankMap[rank] ?? "auto" }}
>
#{rank} <Trophy rank={rank} />
</Text>
</Col>
<Col xs={14}>
<Text
style={{ fontSize: fontSizeToRankMap[rank] ?? "auto" }}
>
{player}
</Text>
</Col>
<Col xs={6}>
<Text
style={{ fontSize: fontSizeToRankMap[rank] ?? "auto" }}
>
{frags}
</Text>
</Col>
</Row>
),
)}
<Row className="row-pagination">
<Col xs={24} style={{ textAlign: "right" }}>
<Pagination
size="small"
{...{
total: topScores.length,
pageSize,
current: currentPage,
disabled: false,
onChange: (page: number) => {
setCurrentPage?.(page);
},
showSizeChanger: false,
}}
/>
</Col>
</Row>
</>
)}
</Card>
</>
);
}