lodash#capitalize TypeScript Examples
The following examples show how to use
lodash#capitalize.
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: utils.tsx From backstage with Apache License 2.0 | 7 votes |
export function tooltipValueFormatter(durationOrCount: number, name: string) {
return [
<span style={infoText}>
{capitalize(name)}:{' '}
{name.endsWith(' count')
? durationOrCount
: formatDuration(durationOrCount)}
</span>,
null,
];
}
Example #2
Source File: index.ts From json-schema-yup-transform with MIT License | 6 votes |
createNotSchema = (
[key, value]: [string, NotSchema],
jsonSchema: JSONSchema
): Yup.MixedSchema<string> => {
const label = value.title || capitalize(key);
const message = getErrorMessage(value.description, CompositSchemaTypes.NOT, [key, { title: value.title }]) || `${label} matches alternatives`;
const schema = createValidationSchema(
[key, value.not as JSONSchema],
jsonSchema
);
return Yup.mixed().test("not-schema", message, function (current) {
return schema.isValidSync(current, this.options) === false;
});
}
Example #3
Source File: nav-bar.tsx From homebridge-zigbee-nt with Apache License 2.0 | 6 votes |
CONFIGURED_PAGES = [ { label: capitalize(Page.HOME), value: Page.HOME, }, { label: capitalize(Page.DEVICES), value: Page.DEVICES, }, { label: capitalize(Page.COORDINATOR), value: Page.COORDINATOR, }, ]
Example #4
Source File: index.tsx From admin with MIT License | 6 votes |
TableViewHeader: React.FC<TableViewHeaderProps> = ({
views,
activeView = views[0],
setActiveView,
}) => {
return (
<div className="flex inter-large-semibold gap-x-base text-grey-40">
{views.map((k, i) => (
<div
key={i}
className={clsx("cursor-pointer", {
["text-grey-90"]: k === activeView,
})}
onClick={() => {
if (setActiveView) {
setActiveView(k)
}
}}
>
{capitalize(k)}
</div>
))}
</div>
)
}
Example #5
Source File: index.stories.tsx From pancake-toolkit with GNU General Public License v3.0 | 6 votes |
Default: React.FC = () => {
return (
<>
<Box mb="32px">
<button type="button">Unstyled Button</button>
</Box>
<Box mb="32px">
{Object.values(variants).map((variant) => {
return (
<Box key={variant} mb="32px">
{Object.values(scales).map((scale) => {
return (
<Button key={scale} variant={variant} scale={scale} mr="8px">
{`${capitalize(variant)} ${scale.toUpperCase()}`}
</Button>
);
})}
</Box>
);
})}
</Box>
<Box>
<Button mr="8px" disabled>
Disabled
</Button>
<Button variant="secondary" disabled>
Disabled
</Button>
</Box>
</>
);
}
Example #6
Source File: OrderByButton.tsx From querybook with Apache License 2.0 | 6 votes |
OrderByButton: React.FC<ISortButtonProps> = ({
asc,
orderByField,
orderByFieldSymbol,
className,
onOrderByFieldToggle = NOOP,
onAscToggle = NOOP,
}) => {
const buttonSymbol = useMemo(
() => orderByFieldSymbol ?? capitalize(orderByField.slice(0, 2)),
[orderByField, orderByFieldSymbol]
);
return (
<span className={clsx('OrderByButton', className)}>
<TextToggleButton
value={false}
onChange={onAscToggle}
tooltip={asc ? 'Ascending' : 'Descending'}
tooltipPos="left"
text={asc ? 'โ' : 'โ'}
/>
<TextToggleButton
value={false}
onChange={onOrderByFieldToggle}
tooltip={`Order by ${orderByField}`}
tooltipPos="left"
text={buttonSymbol}
/>
</span>
);
}
Example #7
Source File: EntityListDocsTable.tsx From backstage with Apache License 2.0 | 6 votes |
EntityListDocsTable = (props: EntityListDocsTableProps) => {
const { columns, actions } = props;
const { loading, error, entities, filters } = useEntityList();
const { isStarredEntity, toggleStarredEntity } = useStarredEntities();
const [, copyToClipboard] = useCopyToClipboard();
const title = capitalize(filters.user?.value ?? 'all');
const defaultActions = [
actionFactories.createCopyDocsUrlAction(copyToClipboard),
actionFactories.createStarEntityAction(
isStarredEntity,
toggleStarredEntity,
),
];
if (error) {
return (
<WarningPanel
severity="error"
title="Could not load available documentation."
>
<CodeSnippet language="text" text={error.toString()} />
</WarningPanel>
);
}
return (
<DocsTable
title={title}
entities={entities}
loading={loading}
actions={actions || defaultActions}
columns={columns}
/>
);
}
Example #8
Source File: index.ts From json-schema-yup-transform with MIT License | 6 votes |
createAnyOfSchema = (
[key, value]: [string, AnyOfSchema],
jsonSchema: JSONSchema
): Yup.MixedSchema<string> => {
const label = value.title || capitalize(key);
const message = getErrorMessage(value.description, CompositSchemaTypes.ANYOF, [key, { title: value.title }]) || `${label} does not match alternatives`;
const schemas = value.anyOf.map((val) =>
createValidationSchema([key, val as JSONSchema], jsonSchema)
);
return Yup.mixed().test("one-of-schema", message, function (current) {
return schemas.some((s) => s.isValidSync(current, this.options));
});
}
Example #9
Source File: index.stories.tsx From vvs-ui with GNU General Public License v3.0 | 6 votes |
Default: React.FC = () => {
return (
<>
<Box mb="32px">
<button type="button">Unstyled Button</button>
</Box>
<Box mb="32px">
{Object.values(variants).map((variant) => {
return (
<Box key={variant} mb="32px">
{Object.values(scales).map((scale) => {
return (
<Button key={scale} variant={variant} scale={scale} mr="8px">
{`${capitalize(variant)} ${scale.toUpperCase()}`}
</Button>
);
})}
</Box>
);
})}
</Box>
<Box>
<Button mr="8px" disabled>
Disabled
</Button>
<Button variant="secondary" disabled>
Disabled
</Button>
</Box>
</>
);
}
Example #10
Source File: RoundSettings.tsx From fishbowl with MIT License | 6 votes |
function RoundSettings() {
const currentGame = React.useContext(CurrentGameContext)
return (
<RoundSettingsList>
{currentGame.rounds.map((round, index) => {
return (
<ListItem key={round.id}>
<ListItemText>
<Box pl={2}>
{index + 1}. {capitalize(round.value)}
</Box>
</ListItemText>
</ListItem>
)
})}
</RoundSettingsList>
)
}
Example #11
Source File: index.stories.tsx From vvs-ui with GNU General Public License v3.0 | 6 votes |
Default: React.FC = () => {
const [progress, setProgress] = useState(random(1, 100));
const handleClick = () => setProgress(random(1, 100));
return (
<div style={{ padding: "32px", width: "400px" }}>
{Object.values(variants).map((variant) => {
return (
<Box key={variant} mb="16px">
<Heading size="md" mb="8px">
{capitalize(variant)}
</Heading>
<Progress variant={variant} primaryStep={progress} />
</Box>
);
})}
<Heading size="md" mb="8px">
Small
</Heading>
<Progress scale="sm" primaryStep={progress} />
<div style={{ marginTop: "32px" }}>
<Button type="button" scale="sm" onClick={handleClick}>
Random Progress
</Button>
</div>
</div>
);
}
Example #12
Source File: GroupCompetition.ts From discord-bot with MIT License | 6 votes |
buildContent(competition: Competition) {
const isTeamCompetition = competition.type === 'team';
const lines = [
`**Metric:**: ${getEmoji(competition.metric)} ${getMetricName(competition.metric)}`,
`**Type:**: ${capitalize(competition.type)}`,
`**Participants:** ${competition.participants.length}`,
`**Duration:** ${competition.duration}`,
`**Total gained:** ${toKMB(competition.totalGained || 0)}`,
''
];
if (isTeamCompetition) {
lines.push('**Teams:**');
lines.push(...this.getTeamData(competition));
} else {
lines.push('**Top Participants:**');
lines.push(...this.getParticipantData(competition));
}
return lines.join('\n');
}
Example #13
Source File: AnalysisDisplay.tsx From abacus with GNU General Public License v2.0 | 6 votes |
/**
* Displays the Analysis decision.
*/
export default function AnalysisDisplay({
analysis,
experiment,
}: {
analysis: Recommendation
experiment: ExperimentFull
}): JSX.Element {
const decorationClasses = useDecorationStyles()
switch (analysis.decision) {
case Decision.ManualAnalysisRequired:
return (
<Tooltip title='Contact @experimentation-review on #a8c-experiments'>
<span className={decorationClasses.tooltipped}>Manual analysis required</span>
</Tooltip>
)
case Decision.MissingAnalysis:
return <>Not analyzed yet</>
case Decision.Inconclusive:
return <>Inconclusive</>
case Decision.NoDifference:
return <>No difference</>
case Decision.VariantBarelyAhead: {
return <>{capitalize(getChosenVariation(experiment, analysis)?.name)} barely ahead</>
}
case Decision.VariantAhead: {
return <>{capitalize(getChosenVariation(experiment, analysis)?.name)} ahead</>
}
case Decision.VariantWins: {
return <>{capitalize(getChosenVariation(experiment, analysis)?.name)} wins</>
}
default:
throw new Error('Missing Decision.')
}
}
Example #14
Source File: path.ts From free-swagger with MIT License | 5 votes |
createDefaultApiName = (url: string, method: Method): string => {
return `${camelcase(last(url.split('/')) ?? '')}By${capitalize(method)}`
}
Example #15
Source File: metrics.ts From wise-old-man with MIT License | 5 votes |
function getMetricValueKey(metric: Metric) {
return `${metric}${capitalize(MetricProps[metric].measure)}`;
}
Example #16
Source File: use-grid-columns.tsx From admin with MIT License | 5 votes |
useGridColumns = (product, isEditing) => {
const defaultFields = [
{ header: "Title", field: "title" },
{ header: "SKU", field: "sku" },
{ header: "EAN", field: "ean" },
{ header: "Inventory", field: "inventory_quantity" },
]
if (isEditing) {
const optionColumns = product.options.map((o) => ({
header: o.title,
field: "options",
formatter: (variantOptions) => {
const displayVal = variantOptions.find((val) => val.option_id === o.id)
return displayVal?.value || " - "
},
}))
return [
...optionColumns,
{
header: "Prices",
field: "prices",
formatter: (prices) => `${prices.length} price(s)`,
},
...defaultFields,
]
} else {
return [
{
header: "Variant",
field: "options",
formatter: (value) => {
const options = value.map((v) => {
if (v.value) {
return capitalize(v.value)
}
return capitalize(v)
})
return options.join(" / ")
},
readOnly: true,
headCol: true,
},
...defaultFields,
]
}
}
Example #17
Source File: model-factory.ts From ts-japi with Apache License 2.0 | 5 votes |
ModelFactory = {
addArrayAttribute<T extends typeof Base, U extends typeof Base>(
name: string,
target: T,
source: U
) {
const getterName = `get${capitalize(camelCase(name))}`;
target.afterRemoveHook = target.afterRemoveHook ?? [];
target.beforeSaveHook = target.beforeSaveHook ?? [];
target.prototype = target.prototype ?? ({} as any);
(target.prototype as any)[getterName] = function <Target>(this: Target) {
return findAllExisting((this as any)[name], (id: string) => source.find(id));
};
target.afterRemoveHook.push(<Target, Source extends Base>(model: Target) => {
(model as any)[getterName]().map((m: Source) => source.remove(m));
});
target.beforeSaveHook.push(<Target>(model: Target) => {
findAllExisting((model as any)[name], (id: string) => source.find(id));
});
},
addSingleAttribute<T extends typeof Base, U extends typeof Base>(
name: string,
othername: string,
target: T,
source: U
) {
const getterName = `get${capitalize(camelCase(name))}`;
target.beforeSaveHook = target.beforeSaveHook ?? [];
target.prototype = target.prototype ?? ({} as any);
(target.prototype as any)[getterName] = function <Target>(this: Target) {
return source.find((this as any)[name]);
};
target.beforeSaveHook.push(<Target extends Base>(model: Target) => {
const sourceModel = (model as any)[getterName]();
if (!sourceModel) throw new Error(`no ${name}`);
pushIfNotExists(sourceModel[othername], model.id, (id) => id === model.id);
});
},
createModel<T extends typeof Base>(model: T) {
model.storage = [];
model.find = function (this: T, id: string) {
if (this.beforeFindHook) this.beforeFindHook.forEach((hook) => hook(id));
const result = this.storage.find((u) => u.id === id);
if (this.afterFindHook) this.afterFindHook.forEach((hook) => hook(id));
return result;
};
model.remove = function <U extends Base>(this: T, obj: U) {
if (this.beforeRemoveHook) this.beforeRemoveHook.forEach((hook) => hook(obj));
let idx = this.storage.findIndex((u) => u.id === obj.id);
if (typeof idx === "number") {
delete this.storage[idx];
}
if (this.afterRemoveHook) this.afterRemoveHook.forEach((hook) => hook(obj));
return obj;
};
model.save = function <U extends Base>(this: T, model: U) {
if (this.beforeSaveHook) this.beforeSaveHook.forEach((hook) => hook(model));
pushIfNotExists(this.storage, model, (m) => m.id === model.id);
if (this.afterSaveHook) this.afterSaveHook.forEach((hook) => hook(model));
return model;
};
},
}
Example #18
Source File: emails.ts From commonwealth with GNU General Public License v3.0 | 5 votes |
createImmediateNotificationEmailObject = async (notification_data, category_id, models) => {
if (notification_data.chainEvent && notification_data.chainEventType) {
// construct compatible CW event from DB by inserting network from type
const evt: CWEvent = {
blockNumber: notification_data.chainEvent.block_number,
data: notification_data.chainEvent.event_data as IChainEventData,
network: notification_data.chainEventType.event_network as SupportedNetwork,
};
try {
const chainEventLabel = ChainEventLabel(notification_data.chainEventType.chain, evt);
if (!chainEventLabel) return;
const subject = `${process.env.NODE_ENV !== 'production' ? '[dev] ' : ''
}${chainEventLabel.heading} event on ${capitalize(notification_data.chainEventType.chain)}`;
return {
from: 'Commonwealth <[email protected]>',
to: null,
bcc: null,
subject,
templateId: DynamicTemplate.ImmediateEmailNotification,
dynamic_template_data: {
notification: {
chainId: notification_data.chainEventType.chain,
blockNumber: notification_data.chainEvent.blockNumber,
subject,
label: subject,
path: null,
}
}
};
} catch (err) {
console.error(`Failed to label chain event: ${err.message}`);
}
} else if (category_id !== NotificationCategories.NewReaction && category_id !== NotificationCategories.ThreadEdit) {
const [
emailSubjectLine, subjectCopy, actionCopy, objectCopy, communityCopy, excerpt, proposalPath, authorPath
] = await getForumNotificationCopy(models, notification_data as IPostNotificationData, category_id);
return {
from: 'Commonwealth <[email protected]>',
to: null,
bcc: null,
subject: (process.env.NODE_ENV !== 'production' ? '[dev] ' : '') + emailSubjectLine,
templateId: DynamicTemplate.ImmediateEmailNotification,
dynamic_template_data: {
notification: {
subject: emailSubjectLine,
author: subjectCopy,
action: actionCopy,
rootObject: objectCopy,
community: communityCopy,
excerpt,
proposalPath,
authorPath,
}
}
};
}
}
Example #19
Source File: index.ts From context-mod with MIT License | 5 votes |
getActionUniqueName() {
return this.name === this.getKind() ? capitalize(this.getKind()) : `${capitalize(this.getKind())} - ${this.name}`;
}
Example #20
Source File: index.tsx From strapi-plugin-comments with MIT License | 5 votes |
DetailsEntity = ({
data = {},
schema = {},
config = {},
filters,
onFiltersChange,
}) => {
const { entryLabel = {} } = config;
const { attributes = {} } = schema;
const keys = Object.keys(attributes);
const entityLabelKey = first(entryLabel[data?.uid]);
const FIELDS_LIMIT = 5;
const itemKeys = take(
keys.filter(
(_) =>
attributes[_].type === "string" &&
!isNil(data[_]) &&
_ !== entityLabelKey
),
FIELDS_LIMIT
);
const formatLabel = (label = "") =>
label
.split("_")
.map((_) => capitalize(_))
.join(" ");
const entityIsRenderable =
data && !isEmpty(data) && (!isEmpty(itemKeys) || data[entityLabelKey]);
return (
<Box padding={4}>
{entityIsRenderable && (
<Box marginBottom={4}>
<Typography
variant="sigma"
textColor="neutral600"
id="entity-details"
>
{getMessage("page.details.panel.entity", "Details")}
</Typography>
<Box paddingTop={2} paddingBottom={4}>
<Divider />
</Box>
<Stack size={itemKeys.length}>
<Flex direction="column" alignItems="flex-start">
<Typography fontWeight="bold">
{formatLabel(entityLabelKey)}
</Typography>
<Typography>{data[entityLabelKey]}</Typography>
</Flex>
{itemKeys.map((_) => (
<Flex
key={`prop_${_}`}
direction="column"
alignItems="flex-start"
>
<Typography fontWeight="bold">{formatLabel(_)}</Typography>
<Typography>{data[_]}</Typography>
</Flex>
))}
</Stack>
</Box>
)}
<Box>
<Typography variant="sigma" textColor="neutral600" id="view-filters">
{getMessage("page.details.filters.label", "View")}
</Typography>
<Box paddingTop={2} paddingBottom={4}>
<Divider />
</Box>
<DetailsFilters data={filters} onChange={onFiltersChange} />
</Box>
</Box>
);
}
Example #21
Source File: TemplateTypePicker.test.tsx From backstage with Apache License 2.0 | 5 votes |
describe('<TemplateTypePicker/>', () => {
it('renders available entity types', async () => {
const rendered = await renderWithEffects(
<ApiProvider apis={apis}>
<MockEntityListContextProvider
value={{
filters: { kind: new EntityKindFilter('template') },
backendEntities: entities,
}}
>
<TemplateTypePicker />
</MockEntityListContextProvider>
</ApiProvider>,
);
expect(rendered.getByText('Categories')).toBeInTheDocument();
fireEvent.click(rendered.getByTestId('categories-picker-expand'));
entities.forEach(entity => {
expect(
rendered.getByLabelText(capitalize(entity.spec!.type as string)),
).toBeInTheDocument();
});
});
it('sets the selected type filters', async () => {
const rendered = await renderWithEffects(
<ApiProvider apis={apis}>
<MockEntityListContextProvider
value={{
filters: { kind: new EntityKindFilter('template') },
backendEntities: entities,
}}
>
<TemplateTypePicker />
</MockEntityListContextProvider>
</ApiProvider>,
);
fireEvent.click(rendered.getByTestId('categories-picker-expand'));
expect(rendered.getByLabelText('Service')).not.toBeChecked();
expect(rendered.getByLabelText('Website')).not.toBeChecked();
fireEvent.click(rendered.getByLabelText('Service'));
fireEvent.click(rendered.getByTestId('categories-picker-expand'));
expect(rendered.getByLabelText('Service')).toBeChecked();
expect(rendered.getByLabelText('Website')).not.toBeChecked();
fireEvent.click(rendered.getByLabelText('Website'));
fireEvent.click(rendered.getByTestId('categories-picker-expand'));
expect(rendered.getByLabelText('Service')).toBeChecked();
expect(rendered.getByLabelText('Website')).toBeChecked();
fireEvent.click(rendered.getByLabelText('Service'));
fireEvent.click(rendered.getByTestId('categories-picker-expand'));
expect(rendered.getByLabelText('Service')).not.toBeChecked();
expect(rendered.getByLabelText('Website')).toBeChecked();
fireEvent.click(rendered.getByLabelText('Website'));
fireEvent.click(rendered.getByTestId('categories-picker-expand'));
expect(rendered.getByLabelText('Service')).not.toBeChecked();
expect(rendered.getByLabelText('Website')).not.toBeChecked();
});
});
Example #22
Source File: common.tsx From reddium with MIT License | 5 votes |
unsplashCredits = (filename: string) =>
capitalize(filename.split("-").slice(0, -2).join(" "))
Example #23
Source File: my-reports.page.ts From fyle-mobile-app with MIT License | 5 votes |
async onDeleteReportClick(erpt: ExtendedReport) {
if (['DRAFT', 'APPROVER_PENDING', 'APPROVER_INQUIRY'].indexOf(erpt.rp_state) === -1) {
const cannotDeleteReportPopOver = await this.popoverController.create({
component: PopupAlertComponentComponent,
componentProps: {
title: 'Cannot Delete Report',
message: `${capitalize(replace(erpt.rp_state, '_', ' '))} report cannot be deleted.`,
primaryCta: {
text: 'Close',
action: 'continue',
},
},
cssClass: 'pop-up-in-center',
});
await cannotDeleteReportPopOver.present();
} else {
const deleteReportPopover = await this.popoverController.create({
component: FyDeleteDialogComponent,
cssClass: 'delete-dialog',
backdropDismiss: false,
componentProps: {
header: 'Delete Report',
body: 'Are you sure you want to delete this report?',
infoMessage: 'Deleting the report will not delete any of the expenses.',
deleteMethod: () => this.reportService.delete(erpt.rp_id),
},
});
await deleteReportPopover.present();
const { data } = await deleteReportPopover.onDidDismiss();
if (data && data.status === 'success') {
from(this.loaderService.showLoader())
.pipe(
tap(() => this.trackingService.deleteReport()),
finalize(async () => {
await this.loaderService.hideLoader();
this.doRefresh();
})
)
.subscribe(noop);
}
}
}
Example #24
Source File: mobile_sidebar.tsx From commonwealth with GNU General Public License v3.0 | 5 votes |
view() {
const CurrentCommunityMenu = (
<Menu class="CurrentCommunityMenu">
{app.isLoggedIn() ? (
<Menu class="NewProposalMenu">
<MenuItem
label="Create New"
iconLeft={Icons.PLUS}
onclick={(e) => {
e.stopPropagation();
this.showNewThreadOptions = !this.showNewThreadOptions;
}}
/>
{this.showNewThreadOptions && (
<NewProposalMenu candidates={[]} mobile={true} />
)}
</Menu>
) : (
<MenuItem
label="Login"
iconLeft={Icons.LOG_IN}
onclick={() => {
app.modals.create({ modal: LoginModal });
}}
/>
)}
<MenuDivider />
{app.chain && <DiscussionSection mobile={true} />}
{app.chain && <GovernanceSection mobile={true} />}
{app.chain && <ChatSection mobile={true} />}
{app.chain && <ExternalLinksModule />}
</Menu>
);
return (
<div class="MobileSidebar">
<Tabs>
{app.activeChainId() && (
<TabItem
label={capitalize(app.activeChainId())}
active={this.activeTab === MenuTabs.CurrentCommunity}
onclick={(e) => {
e.stopPropagation();
this.activeTab = MenuTabs.CurrentCommunity;
}}
/>
)}
{app.activeChainId() && (
<TabItem
label="Communities"
active={this.activeTab === MenuTabs.AllCommunities}
onclick={(e) => {
e.stopPropagation();
this.activeTab = MenuTabs.AllCommunities;
}}
/>
)}
<TabItem
label="Account"
active={this.activeTab === MenuTabs.Account}
onclick={(e) => {
e.stopPropagation();
this.activeTab = MenuTabs.Account;
}}
/>
</Tabs>
{this.activeTab === MenuTabs.CurrentCommunity ? (
CurrentCommunityMenu
) : this.activeTab === MenuTabs.AllCommunities ? (
<Menu class="AllCommunitiesMenu">
<CommunitySelector isMobile={true} />
</Menu>
) : (
<MobileAccountMenu />
)}
</div>
);
}
Example #25
Source File: status-chart.tsx From backstage with Apache License 2.0 | 4 votes |
export function StatusChart(props: StatusChartProps) {
const { analysis } = props;
const { zoomFilterValues } = useZoom();
const { zoomProps, getZoomArea } = useZoomArea();
const values = useMemo(() => {
return analysis.daily.values.map(value => {
const totTriggers = analysis.daily.triggerReasons.reduce(
(prev, cur) => prev + (value[cur as TriggerReason] ?? 0),
0,
);
if (!totTriggers) {
return value;
}
return {
...value,
...Object.fromEntries(
analysis.daily.triggerReasons.map(reason => [
reason,
(value[reason as TriggerReason] ?? 0) / totTriggers,
]),
),
};
});
}, [analysis.daily]);
const triggerReasonLegendPayload = useMemo(
(): NonNullable<LegendProps['payload']> =>
analysis.daily.triggerReasons.map(reason => ({
value: humanTriggerReason(reason),
type: 'line',
id: reason,
color: triggerColorMap[reason as TriggerReason] ?? '',
})),
[analysis.daily.triggerReasons],
);
const statusesLegendPayload = useMemo(
(): NonNullable<LegendProps['payload']> =>
analysis.daily.statuses.map(status => ({
value: capitalize(status),
type: 'line',
id: status,
color: statusColorMap[status as FilterStatusType] ?? '',
})),
[analysis.daily.statuses],
);
const legendPayload = useMemo(
(): NonNullable<LegendProps['payload']> => [
...triggerReasonLegendPayload,
...statusesLegendPayload,
],
[statusesLegendPayload, triggerReasonLegendPayload],
);
const tooltipFormatter = useMemo(() => {
const reasonSet = new Set(analysis.daily.triggerReasons);
return (percentOrCount: number, name: string) => {
const label = reasonSet.has(name)
? humanTriggerReason(name)
: capitalize(name);
const valueText = reasonSet.has(name)
? `${(percentOrCount * 100).toFixed(0)}%`
: percentOrCount;
return [
<span>
{label}: {valueText}
</span>,
null,
];
};
}, [analysis.daily.triggerReasons]);
const zoomFilteredValues = useMemo(
() => zoomFilterValues(values),
[values, zoomFilterValues],
);
const barSize = getBarSize(analysis.daily.values.length);
return (
<Accordion defaultExpanded={analysis.daily.statuses.length > 1}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography>
Build count per status over build trigger reason
</Typography>
</AccordionSummary>
<AccordionDetails>
{values.length === 0 ? (
<Alert severity="info">No data</Alert>
) : (
<ResponsiveContainer width="100%" height={140}>
<ComposedChart data={zoomFilteredValues} {...zoomProps}>
<Legend payload={legendPayload} />
<CartesianGrid strokeDasharray="3 3" />
<XAxis
dataKey="__epoch"
type="category"
tickFormatter={tickFormatterX}
/>
<YAxis yAxisId={1} type="number" tickCount={5} name="Count" />
<YAxis yAxisId={2} type="number" name="Triggers" hide />
<Tooltip
labelFormatter={labelFormatterWithoutTime}
formatter={tooltipFormatter}
/>
{triggerReasonLegendPayload.map(reason => (
<Fragment key={reason.id}>
<Area
isAnimationActive={false}
type="monotone"
dataKey={reason.id!}
stackId="triggers"
yAxisId={2}
stroke={triggerColorMap[reason.id as TriggerReason] ?? ''}
fillOpacity={0.5}
fill={triggerColorMap[reason.id as TriggerReason] ?? ''}
/>
</Fragment>
))}
{[...analysis.daily.statuses].reverse().map(status => (
<Fragment key={status}>
<Bar
isAnimationActive={false}
type="monotone"
barSize={barSize}
dataKey={status}
stackId="statuses"
yAxisId={1}
stroke={statusColorMap[status as FilterStatusType] ?? ''}
fillOpacity={0.8}
fill={statusColorMap[status as FilterStatusType] ?? ''}
/>
</Fragment>
))}
{getZoomArea({ yAxisId: 1 })}
</ComposedChart>
</ResponsiveContainer>
)}
</AccordionDetails>
</Accordion>
);
}
Example #26
Source File: index.tsx From fishbowl with MIT License | 4 votes |
function Play() {
const { t } = useTranslation()
const titleClasses = useTitleStyle()
const currentGame = React.useContext(CurrentGameContext)
const currentPlayer = React.useContext(CurrentPlayerContext)
const [startReview] = useStartReviewMutation()
const [
hasDismissedInstructionCard,
setHasDismissedInstructionCard,
] = React.useState(false)
const completedCardIds = flatMap(
currentGame.turns,
(turn) => turn.completed_card_ids
)
const activeTurn = last(currentGame.turns)
const activePlayer = currentGame.players.find(
(player) => player.id === activeTurn?.player_id
)
const [activeTurnPlayState, setActiveTurnPlayState] = React.useState(
playStateFromTurn(activeTurn)
)
React.useEffect(() => {
setActiveTurnPlayState(playStateFromTurn(activeTurn))
}, [activeTurn])
const secondsLeft = useSecondsLeft(activeTurnPlayState)
// countdown timer
React.useEffect(() => {
if (
activeTurnPlayState === ActiveTurnPlayState.Playing &&
secondsLeft <= 0
) {
setActiveTurnPlayState(ActiveTurnPlayState.Reviewing)
if (currentPlayer.id === activeTurn?.player_id && activeTurn?.id) {
startReview({
variables: {
currentTurnId: activeTurn.id,
},
})
}
}
}, [secondsLeft]) // eslint-disable-line react-hooks/exhaustive-deps
if (!activeTurn || !activePlayer) {
return null
}
const numCompletedCards = completedCardIds.length
const totalNumCards = currentGame.cards.length
const numRounds = currentGame.rounds.length
if (numCompletedCards === numRounds * totalNumCards) {
return <NoMoreRounds />
}
const roundMarkers = [...Array(numRounds).keys()]
let roundNum = Math.floor(numCompletedCards / totalNumCards)
const currentRoundId = currentGame.rounds[roundNum].id
const nextRoundId = currentGame.rounds[roundNum + 1]?.id
let roundMarker = numCompletedCards / totalNumCards
let round = ""
if (roundMarkers.includes(roundMarker)) {
const value = capitalize(currentGame.rounds[roundMarker].value)
round = GameRound[value as GameRound]
if (round) {
round = t(`howToPlay.round.${round.toLowerCase()}.name`, round)
} else {
round = value
}
}
const yourTurn = activePlayer.id === currentPlayer.id
const yourTeamTurn =
activePlayer.team ===
currentPlayerTeam(currentPlayer.id, currentGame.players)
let titleText = null
let content = null
if (yourTurn) {
titleText = t("play.yourTurn.title", "Your Turn")
content = (
<YourTurnContent
yourTeamPlayers={filter(
currentGame.players,
(player) => activePlayer.team === player.team
)}
cardsInBowl={drawableCards(currentGame.turns, currentGame.cards)}
secondsLeft={secondsLeft}
activePlayer={activePlayer}
activeTurn={activeTurn}
activeTurnPlayState={activeTurnPlayState}
onStart={() => {
setActiveTurnPlayState(ActiveTurnPlayState.Playing)
}}
onOutOfCards={() => {
setActiveTurnPlayState(ActiveTurnPlayState.Reviewing)
startReview({
variables: {
currentTurnId: activeTurn.id,
},
})
}}
currentRoundId={currentRoundId}
nextRoundId={nextRoundId}
/>
)
} else if (yourTeamTurn) {
titleText = t("play.yourTeam.title", "You're Guessin'")
content = (
<YourTeamTurnContent
activePlayer={activePlayer}
activeTurn={activeTurn}
/>
)
} else {
titleText = t("play.otherTeam.title", "You're Chillin'")
content = (
<OtherTeamContent activePlayer={activePlayer} activeTurn={activeTurn} />
)
}
return (
<Grid container direction="column" alignItems="center" spacing={2}>
<Grid item>
<Typography variant="h4" className={titleClasses.title}>
{titleText}
</Typography>
</Grid>
<Grid item>
<Divider
variant="middle"
style={{
width: 150,
height: 2,
backgroundColor:
TeamColor[
currentPlayerTeam(currentPlayer.id, currentGame.players) as Team
] || grey[600],
}}
/>
</Grid>
{round && !hasDismissedInstructionCard && (
<Grid item>
<Box mb={1}>
<GameRoundInstructionCard
round={round}
roundNumber={Number(roundMarker + 1)}
onDismiss={() => {
setHasDismissedInstructionCard(true)
}}
/>
</Box>
</Grid>
)}
<Grid item>
<TurnContextPanel
secondsLeft={Math.round(Math.max(secondsLeft, 0)) || 0}
/>
</Grid>
<Grid item>{content}</Grid>
{currentPlayer.role === PlayerRole.Host && (
<Grid item>
<HostControls
activePlayer={activePlayer}
activeTurn={activeTurn}
currentRoundId={currentRoundId}
/>
</Grid>
)}
</Grid>
)
}
Example #27
Source File: index.tsx From strapi-plugin-comments with MIT License | 4 votes |
Settings = () => {
useFocusWhenNavigate();
const { notifyStatus } = useNotifyAT();
const { trackUsage } = useTracking();
const trackUsageRef = useRef(trackUsage);
const toggleNotification = useNotification();
const { lockApp, unlockApp } = useOverlayBlocker();
const viewPermissions = useMemo(
() => ({
access: pluginPermissions.settings.read,
change: pluginPermissions.settings.change,
}),
[]
);
const {
isLoading: isLoadingForPermissions,
allowedActions: { canAccess, canChange },
} = useRBAC(viewPermissions);
const [restoreConfigmationVisible, setRestoreConfigmationVisible] =
useState(false);
const [restartRequired, setRestartRequired] = useState(false);
const [contentTypeExpanded, setContentTypeExpanded] = useState(undefined);
const { fetch, restartMutation, submitMutation, restoreMutation } =
useConfig(toggleNotification);
const {
data: configData,
isLoading: isConfigLoading,
err: configErr,
}: ToBeFixed = fetch;
const {
data: allCollectionsData,
isLoading: areCollectionsLoading,
err: collectionsErr,
}: ToBeFixed = useQuery(["get-all-content-types", canAccess], () =>
fetchAllContentTypes(toggleNotification)
);
const {
data: allRolesData,
isLoading: areRolesLoading,
err: rolesErr,
}: ToBeFixed = useQuery(["get-all-roles", canAccess], () =>
fetchRoles(toggleNotification)
);
const isLoading =
isLoadingForPermissions ||
isConfigLoading ||
areCollectionsLoading ||
areRolesLoading;
const isError = configErr || collectionsErr || rolesErr;
const preparePayload = ({
enabledCollections,
gqlAuthEnabled,
approvalFlow,
entryLabel,
clientUrl,
clientEmail,
...rest
}: ToBeFixed) => ({
...rest,
enabledCollections,
approvalFlow: approvalFlow.filter((_) => enabledCollections.includes(_)),
entryLabel: {
...Object.keys(entryLabel).reduce(
(prev, curr) => ({
...prev,
[curr]: enabledCollections.includes(curr)
? entryLabel[curr]
: undefined,
}),
{}
),
"*": entryLabel["*"],
},
reportReasons: configData?.reportReasons,
client: clientEmail || clientUrl ? {
contactEmail: clientEmail,
url: clientUrl,
} : undefined,
gql: gqlAuthEnabled ? { auth: true } : undefined,
});
if (isLoading || isError) {
return (
<LoadingIndicatorPage>
{getMessage("page.settings.loading")}
</LoadingIndicatorPage>
);
}
const regexUID = !isLoading
? new RegExp(
parseRegExp(fetch.data.regex?.uid).value,
parseRegExp(fetch.data.regex?.uid).flags
)
: null;
const allRoles = allRolesData?.data || [];
const allCollections =
!isLoading &&
allCollectionsData.filter(
({ uid }: ToBeFixed) =>
first(uid.split(regexUID).filter((s) => s && s.length > 0)) === "api"
);
const enabledCollections =
configData?.enabledCollections
?.map((uid: ToBeFixed) =>
allCollections.find((_) => _.uid === uid) ? uid : undefined
)
.filter((_: ToBeFixed) => _) || [];
const entryLabel = configData?.entryLabel || {};
const approvalFlow = configData?.approvalFlow || [];
const badWords = isNil(configData?.badWords) ? true : configData?.badWords;
const isGQLPluginEnabled = configData?.isGQLPluginEnabled;
const gqlAuthEnabled = configData?.gql?.auth || undefined;
const moderatorRoles =
configData?.moderatorRoles?.filter((code: ToBeFixed) =>
allRoles.find((_: ToBeFixed) => _.code === code)
) || [];
const clientUrl = configData?.client?.url;
const clientEmail = configData?.client?.contactEmail;
const changeApprovalFlowFor = (
uid: ToBeFixed,
current: ToBeFixed,
value: ToBeFixed
) => {
const currentSet = new Set(current);
if (value) {
currentSet.add(uid);
} else {
currentSet.delete(uid);
}
return Array.from(currentSet);
};
const changeEntryLabelFor = (
uid: ToBeFixed,
current: ToBeFixed,
value: ToBeFixed
) => ({
...current,
[uid]: value && !isEmpty(value) ? [...value] : undefined,
});
const handleUpdateConfiguration = async (form: ToBeFixed) => {
if (canChange) {
lockApp();
const payload = preparePayload(form);
await submitMutation.mutateAsync(payload);
const enabledCollectionsChanged = !isEqual(
payload.enabledCollections,
configData?.enabledCollections
);
const gqlAuthChanged = !isEqual(payload.gql?.auth, configData?.gql?.auth);
if (enabledCollectionsChanged || gqlAuthChanged) {
setRestartRequired(true);
}
unlockApp();
}
};
const handleRestoreConfirmation = () => setRestoreConfigmationVisible(true);
const handleRestoreConfiguration = async () => {
if (canChange) {
lockApp();
await restoreMutation.mutateAsync();
unlockApp();
setRestartRequired(true);
setRestoreConfigmationVisible(false);
}
};
const handleRestoreCancel = () => setRestoreConfigmationVisible(false);
const handleRestart = async () => {
if (canChange) {
lockApp();
await restartMutation.mutateAsync();
setRestartRequired(false);
unlockApp();
}
};
const handleRestartDiscard = () => setRestartRequired(false);
const handleSetContentTypeExpanded = (key: ToBeFixed) =>
setContentTypeExpanded(key === contentTypeExpanded ? undefined : key);
const boxDefaultProps = {
background: "neutral0",
hasRadius: true,
shadow: "filterShadow",
padding: 6,
};
return (
<Main>
<Formik
initialValues={{
enabledCollections,
moderatorRoles,
badWords,
approvalFlow,
entryLabel,
clientEmail,
clientUrl,
gqlAuthEnabled,
}}
enableReinitialize={true}
onSubmit={handleUpdateConfiguration}
>
{({ handleSubmit, setFieldValue, values }: ToBeFixed) => (
<Form noValidate onSubmit={handleSubmit}>
<HeaderLayout
title={getMessage("page.settings.header.title")}
subtitle={getMessage("page.settings.header.description")}
primaryAction={
<CheckPermissions
permissions={pluginPermissions.settingsChange}
>
<Button
type="submit"
startIcon={<Check />}
disabled={restartRequired}
>
{getMessage("page.settings.actions.submit")}
</Button>
</CheckPermissions>
}
/>
<ContentLayout>
<Stack size={4}>
{restartRequired && (
<RestartAlert
closeLabel={getMessage(
"page.settings.actions.restart.alert.cancel"
)}
title={getMessage(
"page.settings.actions.restart.alert.title"
)}
action={
<Box>
<Button onClick={handleRestart} startIcon={<Play />}>
{getMessage("page.settings.actions.restart")}
</Button>
</Box>
}
onClose={handleRestartDiscard}
>
{getMessage(
"page.settings.actions.restart.alert.description"
)}
</RestartAlert>
)}
<Box {...boxDefaultProps}>
<Stack size={4}>
<Typography variant="delta" as="h2">
{getMessage("page.settings.section.general")}
</Typography>
<Grid gap={4}>
<GridItem col={12}>
<Select
name="enabledCollections"
label={getMessage(
"page.settings.form.enabledCollections.label"
)}
placeholder={getMessage(
"page.settings.form.enabledCollections.placeholder"
)}
hint={getMessage(
"page.settings.form.enabledCollections.hint"
)}
onClear={() =>
setFieldValue("enabledCollections", [], false)
}
value={values.enabledCollections}
onChange={(value: ToBeFixed) =>
setFieldValue("enabledCollections", value, false)
}
disabled={restartRequired}
multi
withTags
>
{allCollections.map(
({ uid, schema: { displayName } }: ToBeFixed) => (
<Option key={uid} value={uid}>
{displayName}
</Option>
)
)}
</Select>
</GridItem>
{!isEmpty(values.enabledCollections) && (
<GridItem col={12}>
<AccordionGroup
label={getMessage(
"page.settings.form.contentTypesSettings.label"
)}
labelAction={
<Tooltip
description={getMessage(
"page.settings.form.contentTypesSettings.tooltip"
)}
>
<Information aria-hidden={true} />
</Tooltip>
}
>
{orderBy(values.enabledCollections).map((uid) => {
const {
schema: { displayName, attributes = {} },
} = allCollections.find((_) => _.uid === uid);
const stringAttributes = Object.keys(
attributes
).filter((_) => attributes[_].type === "string");
const key = `collectionSettings-${uid}`;
return (
<Accordion
expanded={contentTypeExpanded === key}
toggle={() =>
handleSetContentTypeExpanded(key)
}
key={key}
id={key}
size="S"
>
<AccordionToggle
title={displayName}
togglePosition="left"
/>
<AccordionContent>
<Box padding={6}>
<Stack size={4}>
<FormSwitch
name={`collectionSettings-${uid}-approvalFlow`}
label={getMessage(
"page.settings.form.approvalFlow.label"
)}
hint={getMessage({
id: "page.settings.form.approvalFlow.hint",
props: { name: displayName },
})}
selected={values.approvalFlow.includes(
uid
)}
onChange={() =>
setFieldValue(
"approvalFlow",
changeApprovalFlowFor(
uid,
values.approvalFlow,
!values.approvalFlow.includes(
uid
)
),
[]
)
}
onLabel={getMessage(
"compontents.toogle.enabled"
)}
offLabel={getMessage(
"compontents.toogle.disabled"
)}
disabled={restartRequired}
visibleLabels
/>
{!isEmpty(stringAttributes) && (
<Select
name={`collectionSettings-${uid}-entryLabel`}
label={getMessage(
"page.settings.form.entryLabel.label"
)}
placeholder={getMessage(
"page.settings.form.entryLabel.placeholder"
)}
hint={getMessage(
"page.settings.form.entryLabel.hint"
)}
onClear={() =>
setFieldValue(
"entryLabel",
changeEntryLabelFor(
uid,
values.entryLabel
)
)
}
value={values.entryLabel[uid] || []}
onChange={(value: ToBeFixed) =>
setFieldValue(
"entryLabel",
changeEntryLabelFor(
uid,
values.entryLabel,
value
)
)
}
multi
withTags
disabled={restartRequired}
>
{stringAttributes.map((key) => (
<Option
key={`collectionSettings-${uid}-entryLabel-${key}`}
value={key}
>
{capitalize(
key.split("_").join(" ")
)}
</Option>
))}
</Select>
)}
</Stack>
</Box>
</AccordionContent>
</Accordion>
);
})}
</AccordionGroup>
</GridItem>
)}
</Grid>
</Stack>
</Box>
<Box {...boxDefaultProps}>
<Stack size={4}>
<Typography variant="delta" as="h2">
{getMessage("page.settings.section.additional")}
</Typography>
<Grid gap={4}>
<GridItem col={6} xs={12}>
<ToggleInput
name="badWords"
label={getMessage(
"page.settings.form.badWords.label"
)}
hint={getMessage("page.settings.form.badWords.hint")}
checked={values.badWords}
onChange={({ target: { checked } }: ToBeFixed) =>
setFieldValue("badWords", checked, false)
}
onLabel={getMessage("compontents.toogle.enabled")}
offLabel={getMessage("compontents.toogle.disabled")}
disabled={restartRequired}
/>
</GridItem>
{isGQLPluginEnabled && (
<GridItem col={6} xs={12}>
<ToggleInput
name="gqlAuthEnabled"
label={getMessage(
"page.settings.form.gqlAuth.label"
)}
hint={getMessage("page.settings.form.gqlAuth.hint")}
checked={values.gqlAuthEnabled}
onChange={({ target: { checked } }: ToBeFixed) =>
setFieldValue("gqlAuthEnabled", checked, false)
}
onLabel={getMessage("compontents.toogle.enabled")}
offLabel={getMessage("compontents.toogle.disabled")}
disabled={restartRequired}
/>
</GridItem>
)}
</Grid>
</Stack>
</Box>
<Box {...boxDefaultProps}>
<Stack size={4}>
<Typography variant="delta" as="h2">
{getMessage("page.settings.section.client")}
</Typography>
<Grid gap={4}>
<GridItem col={3} xs={12}>
<TextInput
type="url"
name="clientUrl"
label={getMessage(
"page.settings.form.client.url.label"
)}
hint={getMessage("page.settings.form.client.url.hint")}
value={values.clientUrl}
onChange={({ target: { value } }: ToBeFixed) =>
setFieldValue("clientUrl", value, false)
}
disabled={restartRequired}
/>
</GridItem>
<GridItem col={3} xs={12}>
<TextInput
type="email"
name="clientEmail"
label={getMessage(
"page.settings.form.client.email.label"
)}
hint={getMessage("page.settings.form.client.email.hint")}
value={values.clientEmail}
onChange={({ target: { value } }: ToBeFixed) =>
setFieldValue("clientEmail", value, false)
}
disabled={restartRequired}
/>
</GridItem>
<GridItem col={6} xs={12}>
<Select
name="moderatorRoles"
label={getMessage(
"page.settings.form.moderatorRoles.label"
)}
placeholder={getMessage(
"page.settings.form.moderatorRoles.placeholder"
)}
hint={getMessage(
"page.settings.form.moderatorRoles.hint"
)}
onClear={() =>
setFieldValue("moderatorRoles", [], false)
}
value={values.moderatorRoles}
onChange={(value: ToBeFixed) =>
setFieldValue("moderatorRoles", value, false)
}
disabled={restartRequired}
multi
withTags
>
{allRoles.map(({ code, name }: ToBeFixed) => (
<Option key={code} value={code}>
{name}
</Option>
))}
</Select>
</GridItem>
</Grid>
</Stack>
</Box>
<CheckPermissions
permissions={pluginPermissions.settingsChange}
>
<Box {...boxDefaultProps}>
<Stack size={4}>
<Stack size={2}>
<Typography variant="delta" as="h2">
{getMessage("page.settings.section.restore")}
</Typography>
<Typography variant="pi" as="h4">
{getMessage("page.settings.section.restore.subtitle")}
</Typography>
</Stack>
<Grid gap={4}>
<GridItem col={6}>
<Button
variant="danger-light"
startIcon={<Refresh />}
onClick={handleRestoreConfirmation}
>
{getMessage("page.settings.actions.restore")}
</Button>
<ConfirmationDialog
isVisible={restoreConfigmationVisible}
isActionAsync={restoreMutation.isLoading}
header={getMessage(
"page.settings.actions.restore.confirmation.header"
)}
labelConfirm={getMessage(
"page.settings.actions.restore.confirmation.button.confirm"
)}
iconConfirm={<Refresh />}
onConfirm={handleRestoreConfiguration}
onCancel={handleRestoreCancel}
>
{getMessage(
"page.settings.actions.restore.confirmation.description"
)}
</ConfirmationDialog>
</GridItem>
</Grid>
</Stack>
</Box>
</CheckPermissions>
</Stack>
</ContentLayout>
</Form>
)}
</Formik>
</Main>
);
}
Example #28
Source File: user.ts From commonwealth with GNU General Public License v3.0 | 4 votes |
UserBlock: m.Component<{
user: Account<any> | AddressInfo | Profile;
hideIdentityIcon?: boolean;
popover?: boolean;
showRole?: boolean;
showAddressWithDisplayName?: boolean;
addressDisplayOptions?: IAddressDisplayOptions;
searchTerm?: string;
showChainName?: boolean;
hideOnchainRole?: boolean;
selected?: boolean;
compact?: boolean;
linkify?: boolean;
avatarSize?: number;
}> = {
view: (vnode) => {
const {
user,
hideIdentityIcon,
popover,
showRole,
searchTerm,
hideOnchainRole,
showAddressWithDisplayName,
showChainName,
selected,
compact,
linkify,
addressDisplayOptions,
} = vnode.attrs;
const { showFullAddress, autoTruncate, maxCharLength } =
vnode.attrs.addressDisplayOptions || {};
let profile;
if (user instanceof AddressInfo) {
if (!user.chain || !user.address) return;
profile = app.profiles.getProfile(user.chain, user.address);
} else if (user instanceof Profile) {
profile = user;
} else {
profile = app.profiles.getProfile(user.chain.id, user.address);
}
const highlightSearchTerm =
profile?.address &&
searchTerm &&
profile.address.toLowerCase().includes(searchTerm);
const highlightedAddress = highlightSearchTerm
? (() => {
const isNear = profile.address.chain === 'near';
const queryStart = profile.address.toLowerCase().indexOf(searchTerm);
const queryEnd = queryStart + searchTerm.length;
return [
m('span', profile.address.slice(0, queryStart)),
m('mark', profile.address.slice(queryStart, queryEnd)),
m('span', profile.address.slice(queryEnd, profile.address.length)),
];
})()
: null;
const children = [
m('.user-block-left', [
m(User, {
user,
avatarOnly: true,
avatarSize: vnode.attrs.avatarSize || 28,
popover,
}),
]),
m('.user-block-center', [
m('.user-block-name', [
m(User, {
user,
hideAvatar: true,
hideIdentityIcon,
showAddressWithDisplayName,
addressDisplayOptions,
popover,
showRole,
}),
]),
m(
'.user-block-address',
{
class: profile?.address ? '' : 'no-address',
},
[
m(
'',
highlightSearchTerm
? highlightedAddress
: showFullAddress
? profile.address
: formatAddressShort(profile.address, profile.chain)
),
profile?.address && showChainName && m('.address-divider', ' ยท '),
showChainName &&
m(
'',
typeof user.chain === 'string'
? capitalize(user.chain)
: capitalize(user.chain.name)
),
]
),
]),
m('.user-block-right', [
m(
'.user-block-selected',
selected ? m(CWIcon, { iconName: 'check' }) : ''
),
]),
];
const userLink = profile
? `/${app.activeChainId() || profile.chain}/account/${
profile.address
}?base=${profile.chain}`
: 'javascript:';
return linkify
? link('.UserBlock', userLink, children)
: m(
'.UserBlock',
{
class: compact ? 'compact' : '',
},
children
);
},
}
Example #29
Source File: fulfillment.tsx From admin with MIT License | 4 votes |
FormattedFulfillment = ({
setFullfilmentToShip,
order,
fulfillmentObj,
}) => {
const dialog = useImperativeDialog()
const notification = useNotification()
const cancelFulfillment = useAdminCancelFulfillment(order.id)
const cancelSwapFulfillment = useAdminCancelSwapFulfillment(order.id)
const cancelClaimFulfillment = useAdminCancelClaimFulfillment(order.id)
const { fulfillment } = fulfillmentObj
const hasLinks = !!fulfillment.tracking_links?.length
const getData = () => {
switch (true) {
case !!fulfillment?.claim_order_id:
return {
resourceId: fulfillment.claim_order_id,
resourceType: "claim",
}
case !!fulfillment?.swap_id:
return {
resourceId: fulfillment.swap_id,
resourceType: "swap",
}
default:
return { resourceId: order?.id, resourceType: "order" }
}
}
const handleCancelFulfillment = async () => {
const { resourceId, resourceType } = getData()
const shouldCancel = await dialog({
heading: "Cancel fulfillment?",
text: "Are you sure you want to cancel the fulfillment?",
})
if (!shouldCancel) {
return
}
switch (resourceType) {
case "swap":
return cancelSwapFulfillment.mutate(
{ swap_id: resourceId, fulfillment_id: fulfillment.id },
{
onSuccess: () =>
notification("Success", "Successfully canceled swap", "success"),
onError: (err) =>
notification("Error", getErrorMessage(err), "error"),
}
)
case "claim":
return cancelClaimFulfillment.mutate(
{ claim_id: resourceId, fulfillment_id: fulfillment.id },
{
onSuccess: () =>
notification("Success", "Successfully canceled claim", "success"),
onError: (err) =>
notification("Error", getErrorMessage(err), "error"),
}
)
default:
return cancelFulfillment.mutate(fulfillment.id, {
onSuccess: () =>
notification("Success", "Successfully canceled order", "success"),
onError: (err) =>
notification("Error", getErrorMessage(err), "error"),
})
}
}
return (
<div className="flex w-full justify-between">
<div className="flex flex-col space-y-1 py-2">
<div className="text-grey-90">
{fulfillment.canceled_at
? "Fulfillment has been canceled"
: `${fulfillmentObj.title} Fulfilled by ${capitalize(
fulfillment.provider_id
)}`}
</div>
<div className="flex text-grey-50">
{!fulfillment.shipped_at ? "Not shipped" : "Tracking"}
{hasLinks &&
fulfillment.tracking_links.map((tl, j) => (
<TrackingLink key={j} trackingLink={tl} />
))}
</div>
</div>
{!fulfillment.canceled_at && !fulfillment.shipped_at && (
<div className="flex items-center space-x-2">
<Actionables
actions={[
{
label: "Mark Shipped",
icon: <PackageIcon size={"20"} />,
onClick: () => setFullfilmentToShip(fulfillment),
},
{
label: "Cancel Fulfillment",
icon: <CancelIcon size={"20"} />,
onClick: () => handleCancelFulfillment(),
},
]}
/>
</div>
)}
</div>
)
}