@fortawesome/free-solid-svg-icons#faSpinner TypeScript Examples
The following examples show how to use
@fortawesome/free-solid-svg-icons#faSpinner.
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: Spinner.tsx From sync-party with GNU General Public License v3.0 | 6 votes |
export default function Spinner({ size }: Props): ReactElement {
return (
<FontAwesomeIcon
className="m-auto"
icon={faSpinner}
spin
size={size ? size : '5x'}
></FontAwesomeIcon>
);
}
Example #2
Source File: LoadingIcon.tsx From solo with MIT License | 6 votes |
LoadingIcon: React.FC<LoadingStatus> = ({ loading, error }) => (
<span>
<FontAwesomeIcon
spin={loading}
icon={loading ? faSpinner : error ? faExclamationCircle : faCheck}
className={classNames({
[classes.error]: error
})}
/>
</span>
)
Example #3
Source File: fontawesome-config.ts From covidnet_ui with GNU Affero General Public License v3.0 | 6 votes |
// Description: add icons to be used in the app as needed
// Some are solid and some are from regular svg (hollow icons)
library.add(
faSearch,
faSearchPlus,
faHome,
faSpinner,
faExclamationTriangle,
faTrash,
faTrashAlt,
faEdit,
faUser,
faUserEdit,
faUserPlus,
faUserTimes,
faUserMinus,
faKey,
faCheck,
faCheckCircle,
faCalendarDay,
faClock,
faCalendarAlt,
farUser,
faFileAlt
);
Example #4
Source File: VideoInputControl.tsx From amazon-chime-sdk-smart-video-sending-demo with Apache License 2.0 | 5 votes |
VideoInputControl: React.FC = () => {
const meetingManager = useMeetingManager();
const audioVideo = useAudioVideo();
const { isLocalVideoEnabled, toggleVideo, nameplate, setNameplate } = useLocalVideoContext();
const videoEl = useRef<HTMLVideoElement>(null);
const canSendLocalVideo = useVideoSendingCommand();
const attendeeName = meetingManager.attendeeName!;
useEffect(() => {
if (!audioVideo) {
return;
}
const sendLocalVideo = async () => {
await audioVideo.chooseVideoInputDevice(meetingManager.selectedVideoInputDevice);
audioVideo.startLocalVideoTile();
setNameplate(attendeeName);
}
const sendLocalVideoPreview = async () => {
await audioVideo.chooseVideoInputDevice(meetingManager.selectedVideoInputDevice);
if (videoEl.current) {
audioVideo.startVideoPreviewForVideoInput(videoEl.current);
setNameplate(`${attendeeName} - preview`);
}else {
throw new Error('No video preview element to show preview!');
}
}
if (canSendLocalVideo && isLocalVideoEnabled !== 'disabled') {
if (videoEl.current) {
audioVideo.stopVideoPreviewForVideoInput(videoEl.current);
}
sendLocalVideo();
}
if (!canSendLocalVideo && isLocalVideoEnabled === 'enabled') {
audioVideo.stopLocalVideoTile();
sendLocalVideoPreview();
}
}, [audioVideo, canSendLocalVideo]);
return (
<>
<ButtonGroup>
<IconButton
icon={isLocalVideoEnabled === 'enabled' ? faVideo : isLocalVideoEnabled === 'disabled' ? faVideoSlash : faSpinner}
disabled={isLocalVideoEnabled === 'pending'}
onClick={() => toggleVideo(videoEl.current)} />
</ButtonGroup>
<LocalVideo
nameplate={nameplate}
videoEl={videoEl}
style={{ width: "20rem", position: "absolute", top: "3.5rem", background: "#1c1c1c" }}
/>
</>
);
}
Example #5
Source File: spinner.component.tsx From MyWay-client with MIT License | 5 votes |
export default function Spinner() {
return <FontAwesomeIcon icon={faSpinner} className='w-6 animate-spin m-auto' />
}
Example #6
Source File: components.tsx From MagicUI with Apache License 2.0 | 5 votes |
export function NewPageModal(props: INewPageModalProps) {
const [name, setName] = useState('');
const [description, setDescription] = useState('');
const [creating, setCreating] = useState(false);
const handleNameChange = (e: any) => {
setName(e.target.value);
};
const handleDescriptionChange = (e: any) => {
setDescription(e.target.value);
};
const handleCreateNewPage = () => {
setCreating(true);
createNewPage(props.email, name, description).then((v) => {
setCreating(false);
props.dispatch(selectWebGLPage(
v.pageId,
name,
null,
v.id
));
props.cancel();
toast('create new page!');
}).catch(() => {
props.cancel();
toast('create page fail!');
});
};
return (
<div className={style.new_page_modal}>
<div className={style.header}>
Create Page
</div>
<div className={style.content}>
<div className={style.input}>
<div>Name</div>
<input type='text' value={name} onChange={handleNameChange}/>
</div>
<div className={cls(style.input, style.textarea)}>
<div>Description</div>
<textarea value={description} onChange={handleDescriptionChange}/>
</div>
</div>
<div className={style.foot}>
<button onClick={props.cancel}>CANCEL</button>
<button onClick={handleCreateNewPage}>
{creating ? <FontAwesomeIcon icon={faSpinner} spin/> : 'CREATE'}
</button>
</div>
</div>
);
}
Example #7
Source File: icons.font-awesome-solid.ts From dayz-server-manager with MIT License | 5 votes |
fontAwesomeSolidIcons = { faAngleDown, faAngleRight, faArrowLeft, faBars, faBookOpen, faChartArea, faChartBar, faChartPie, faChevronDown, faChevronUp, faColumns, faSearch, faTable, faTachometerAlt, faUser, faExclamationTriangle, faSignOutAlt, faCalendarAlt, faCogs, faClipboardList, faHammer, faTools, faSync, faLock, faLockOpen, faTrash, faPlusCircle, faSpinner, faMap, faAnchor, faCity, faChessRook, faMountain, faCampground, faHome, faUniversity, faCrosshairs, faPlane, faWrench, }
Example #8
Source File: index.tsx From portable with Apache License 2.0 | 5 votes |
render() {
const {
clusters,
error,
selectedCommand,
selectedCluster,
isLoading,
isCustomConfig,
} = this.state
return (
<div className='ClusterScreen-container'>
<div className={cx('title', { error: error })}>
{this.renderTitle()}
<div className='loading-box'>
{isLoading && <FontAwesomeIcon icon={faSpinner} spin />}
</div>
</div>
<div
className='close-clusters'
onClick={() => this.props.handleCloseClusters()}
>
x
</div>
{!error && !isCustomConfig && (
<div
className='add-config'
onClick={() => this.addCustomConfig()}
>
<span className='add-config-icon'>+</span>
<span className='add-config-text'>
Add custom kube config
</span>
</div>
)}
{!isEmptyArray(clusters) && !error && !isCustomConfig && (
<ClusterList
clusters={clusters}
selectedCluster={selectedCluster}
selectCluster={this.selectCluster}
addCustomConfig={this.addCustomConfig}
/>
)}
{error && (
<ClusterError
error={error}
backToList={this.backToList}
selectedCommand={selectedCommand}
selectCommand={this.selectCommand}
/>
)}
{isCustomConfig && (
<CustomConfig
backToList={this.backToList}
createCustomConfig={this.createCustomConfig}
/>
)}
</div>
)
}
Example #9
Source File: CORInputForm.tsx From solo with MIT License | 5 votes |
ReceivedByInputCell: React.FC<CORInputFormProps> = ({
onSubmitCOR,
onReceivedByChange,
value,
loading,
error,
message,
actionText = "Submit",
className,
...rest
}) => {
const onSubmitEvent: React.FormEventHandler<HTMLFormElement> = e => {
e.preventDefault();
onSubmitCOR(value);
};
return (
<div className="display-flex flex-column">
<form
onSubmit={onSubmitEvent}
className={classNames(
"display-flex",
"flex-row",
"flex-align-center",
className
)}
{...rest}
>
<input
className={classNames("usa-input", classes.receivedByInput, {
"usa-input--error": error
})}
placeholder="Rank Lastname, Firstname MI"
disabled={loading}
value={value}
onChange={e => onReceivedByChange(e.currentTarget.value)}
/>
<Button
type="submit"
disabled={loading || !value}
color={error ? "secondary" : undefined}
className={classes.btn}
>
{loading ? <FontAwesomeIcon icon={faSpinner} spin /> : actionText}
</Button>
</form>
{error && (
<div className="usa-error-message text-center" role="alert">
{message}
</div>
)}
</div>
);
}
Example #10
Source File: CommentForm.tsx From 3Speak-app with GNU General Public License v3.0 | 5 votes |
export function CommentForm(props) {
const [postingStatus, setPostingStatus] = useState(false)
const commentBodyRef = useRef() as any
const { parent_reflink } = props
const postComment = useCallback(async () => {
setPostingStatus(true)
const [networkId, parent_author, parent_permlink] = (RefLink.parse(parent_reflink) as any).link
const [reflink, finishOpt] = await AccountService.postComment({
accountType: 'hive',
body: commentBodyRef.current.value,
parent_author,
parent_permlink,
username: 'sisy',
permlink: `re-${parent_permlink}-${randomstring
.generate({
length: 8,
charset: 'alphabetic',
})
.toLowerCase()}`,
title: '',
json_metadata: {},
})
if (typeof props.onCommentPost === 'function') {
props.onCommentPost()
}
commentBodyRef.current.value = ''
setPostingStatus(false)
}, [parent_reflink])
return (
<>
<textarea
id="new-comment-body"
className="form-control w-100"
ref={commentBodyRef}
placeholder="Comment here..."
maxLength={25000}
></textarea>
<button
id="new-comment-btn"
className="btn mt-1 btn-primary float-right"
disabled={postingStatus}
onClick={postComment}
>
{postingStatus ? <FontAwesomeIcon icon={faSpinner as any} spin /> : <span>Comment</span>}
</button>
</>
)
}
Example #11
Source File: Spinner.tsx From amazon-chime-sdk-smart-video-sending-demo with Apache License 2.0 | 5 votes |
Spinner: React.FC = () => {
return (
<FontAwesomeIcon icon={faSpinner} spin />
);
}
Example #12
Source File: icon.tsx From NetStatus with MIT License | 5 votes |
Spinner = (styling={}) => ComponentForIconName(faSpinner.iconName, 'animateRotate', styling)
Example #13
Source File: ImagePicker.tsx From frontend.ro with MIT License | 5 votes |
ImagePicker = ({
src,
inputId,
inputName,
onChange,
alt = '',
loading,
disabled = false,
className = '',
showInput = false,
acceptMimeTypes = IMAGES_MIME_TYPES,
}: Props) => {
return (
<label className={`${styles.ImagePicker} ${className} relative d-block`}>
{!disabled && (
<>
{!loading && (
<span className={`${styles.overlay} pin-full d-flex align-items-center justify-content-center`}>
<FontAwesomeIcon width="48" icon={faCamera} className="text-white" />
</span>
)}
{loading && (
<span className={`${styles['spinner-overlay']} pin-full d-flex align-items-center justify-content-center`}>
<FontAwesomeIcon width="48" icon={faSpinner} className="text-white rotate" />
</span>
)}
</>
)}
<img src={src} alt={alt} />
<input
id={inputId}
type="file"
name={inputName}
multiple={false}
hidden={!showInput}
disabled={disabled || loading}
accept={acceptMimeTypes.join(',')}
onChange={(e) => onChange(e.target.files[0])}
/>
</label>
);
}
Example #14
Source File: UsernameInput.tsx From frontend.ro with MIT License | 5 votes |
function UsernameInput({ name }: any) {
const ref = useRef<HTMLInputElement>(null);
const checkFn = useRef<DebouncedFunc<(value: string) => void>>(debounce(checkUsername, 250));
const [username, setUsername] = useState(null);
const [usernameExists, setUsernameExists] = useState(undefined);
const onUsernameChange = (e) => {
let value: string = e.target.value ?? '';
value = value.trim();
setUsername(value);
setUsernameExists(undefined);
if (!value) {
return;
}
checkFn.current.cancel();
checkFn.current(value);
};
function checkUsername(value: string) {
return UserService.checkUsername(value)
.then(() => {
setUsernameExists(true);
ref.current.setCustomValidity('Acest username există deja');
})
.catch(() => {
ref.current.setCustomValidity('');
setUsernameExists(false);
});
}
return (
<InputWithIcon
required
type="text"
name={name}
ref={ref}
onChange={onUsernameChange}
>
{usernameExists && <FontAwesomeIcon width="1em" className="text-red" icon={faTimes} />}
{usernameExists === false && <FontAwesomeIcon width="1em" className="text-green" icon={faCheck} />}
{usernameExists === undefined && username && <FontAwesomeIcon width="1em" className="rotate" icon={faSpinner} />}
</InputWithIcon>
);
}
Example #15
Source File: NotificationTooltip.tsx From frontend.ro with MIT License | 4 votes |
NotificationsTooltip = ({
className, tooltipClassName, theme = 'default', user, dispatch,
}: Props) => {
const [error, setError] = useState(false);
const [isOpen, setIsOpen] = useState(false);
const [loading, setLoading] = useState(false);
const hiddenRef = useRef<HTMLDivElement>(null);
const componentRef = useRef<HTMLDivElement>(null);
const notifications = user.notifications.list || [];
const toggle = () => setIsOpen(!isOpen);
const loadNextPage = async () => {
setLoading(true);
try {
const newNotifications = await NotificationService.fetchAll();
dispatch(replaceNotificationsSuccess(newNotifications));
} catch (err) {
setError(true);
console.error('NotificationsTooltip.loadNextPage', err);
} finally {
setLoading(false);
}
};
const markAsRead = async (id) => {
const { notifications } = user;
if (notifications.list.find((n) => n._id === id).read === false) {
try {
dispatch(markNotificationAsRead(id));
await NotificationService.markAsRead(id);
} catch (err) {
dispatch(markNotificationAsUnread(id));
}
}
};
const markAllAsRead = async () => {
try {
dispatch(markAllAsReadAction());
await NotificationService.markAllAsRead();
} catch (err) {
SweetAlertService.toast({ type: 'error', text: err });
}
};
useEffect(() => {
if (isOpen && !user.notifications.list) {
loadNextPage();
}
}, [isOpen]);
useOutsideClick(componentRef, () => setIsOpen(false));
/** For the moment disable pagination */
// const observer = useRef<IntersectionObserver>(null);
// const initIntersectionObserver = () => {
// const options = {
// threshold: 0.3,
// };
// observer.current = new IntersectionObserver(loadMore, options);
// observer.current.observe(hiddenRef.current);
// };
// const loadMore = (entries) => {
// entries.forEach((entry) => {
// if (entry.isIntersecting) {
// loadNextPage();
// }
// });
// };
// useEffect(() => {
// if (user.notifications.end && observer.current) {
// observer.current.disconnect();
// }
// }, [user.notifications.end]);
// useEffect(() => {
// if (isOpen && !user.notifications.end) {
// initIntersectionObserver();
// return () => observer.current.disconnect();
// }
// return noop;
// }, [isOpen, user.notifications.end]);
return (
<div ref={componentRef} className={`${className ?? ''} ${styles[`theme-${theme}`]} relative`}>
<Button
onClick={toggle}
variant="transparent"
className={`${styles.icon} relative`}
>
<FontAwesomeIcon style={{ minWidth: '20px' }} width="20px" icon={loading ? faSpinner : faBell} />
{user.notifications.unreadCount > 0 && (
<span className={`${styles['unread-badge']} text-white text-center text-xs`}>
{user.notifications.unreadCount}
</span>
)}
</Button>
{isOpen && (
<div className={`${styles.tooltip} ${tooltipClassName ?? ''} bg-white`}>
{notifications.length > 0 && (
<div className="text-right p-3 text-xs text-blue">
<Button
variant="transparent"
onClick={markAllAsRead}
>
Marchează notificările drept citite
</Button>
</div>
)}
{notifications.length > 0 && (
<List>
{notifications.map((notificationProps) => (
<Notification
key={notificationProps._id}
notification={notificationProps}
onMarkAsRead={() => markAsRead(notificationProps._id)}
/>
))}
</List>
)}
{loading && (<SkeletonNotificationList />)}
{notifications.length === 0 && !loading && (
<p className="font-light text-center"> Deocamdată nu ai notificări... </p>
)}
{error && (
<div className="font-light text-center">
<p className="mb-4">
Nu am putut încărca notificările...?
</p>
<p>
Încearcă să refresh-uiești pagina
</p>
</div>
)}
<div className="invisible" ref={hiddenRef} />
</div>
)}
</div>
);
}
Example #16
Source File: Login.tsx From frontend.ro with MIT License | 4 votes |
render() {
const {
mode,
loading,
serverError,
usernameExists,
username,
} = this.state;
const { className } = this.props;
return (
<div className={`${styles['login-form']} ${className || ''}`}>
{(mode === 'login' || mode === 'register') && (
<Form onSubmit={this.submit} onInput={() => this.setState({ serverError: null })}>
<FormGroup className="mb-4">
<label>
<span className="label">
{mode === 'register'
? 'Email'
: 'Email sau username'}
</span>
<input
required
type="text"
autoCapitalize="none"
name={mode === 'register' ? 'email' : 'emailOrUsername'}
/>
</label>
</FormGroup>
{mode === 'register' && (
<FormGroup className="mb-4">
<label>
<span className="label"> Username </span>
<InputWithIcon
required
type="text"
name="username"
onChange={this.onUsernameChange}
>
{usernameExists && <FontAwesomeIcon width="1em" className="text-red" icon={faTimes} />}
{usernameExists === false && <FontAwesomeIcon width="1em" className="text-green" icon={faCheck} />}
{usernameExists === undefined && username && <FontAwesomeIcon width="1em" className="rotate" icon={faSpinner} />}
</InputWithIcon>
</label>
</FormGroup>
)}
<FormGroup className="mb-4">
<label>
<span className="label"> Parola </span>
<PasswordReveal />
</label>
</FormGroup>
{(mode === 'register') && (
<Checkbox
required
name="confirm"
className="d-flex mb-4"
>
<span style={{ fontSize: '0.85em' }}>
Am citit și sunt de acord cu
{' '}
<a href="/termeni-si-conditii" className="link">
Termenii și Condițiile
</a>
{' '}
de utilizare.
</span>
</Checkbox>
)}
{serverError && <p className={`${styles['server-error']} text-red text-bold`}>{serverError}</p>}
<LoginButtons
mode={mode}
loading={loading}
onLogin={() => this.changeMode('login')}
onRegister={() => this.changeMode('register')}
onResetPassword={() => this.changeMode('getResetCode')}
/>
</Form>
)}
{(mode === 'getResetCode' || mode === 'resetPassword') && (
<>
<Form
onSubmit={this.generateResetCode}
onInput={() => this.setState({ serverError: null })}
>
<FormGroup className="mb-4">
<label>
<span className="label">
Email
</span>
<input
required
type="email"
name="email"
autoCapitalize="none"
/>
</label>
</FormGroup>
{serverError && (
<p className={`${styles['server-error']} text-red text-bold`}>
{serverError}
</p>
)}
<Button
type="submit"
className="w-100"
variant={mode === 'getResetCode' ? 'blue' : 'light'}
loading={mode === 'getResetCode' && loading}
disabled={mode === 'resetPassword' || loading}
>
Generează cod de resetare
</Button>
</Form>
<HorizontalSeparator className="my-5" />
<PasswordReset
buttonVariant={mode === 'getResetCode' ? 'light' : 'blue'}
onReset={this.resetPassword}
loading={mode === 'resetPassword' && loading}
disabled={mode === 'getResetCode' || loading}
characterCount={+process.env.RESET_CODE_LENGTH}
/>
<div className="text-right mt-4 text-xs">
<Button variant="link" type="button" onClick={() => this.changeMode('login')}>
Login/Register?
</Button>
</div>
</>
)}
</div>
);
}
Example #17
Source File: GitGithubChallenge.tsx From frontend.ro with MIT License | 4 votes |
function GitGithubChallenge({ user }: ConnectedProps<typeof connector>) {
const router = useRouter();
const [lastDoneTask, setLastDoneTask] = useState(null);
const [errorForTask, setErrorForTask] = useState<{id: string, message: string}>(null);
const [githubUsername, setGithubUsername] = useState(null);
const [taskIdBeingVerified, setTaskIdBeingVerified] = useState(null);
const indexOfLastDoneTask = tasks.findIndex((task) => task.id === lastDoneTask);
const metaRef = useRef({});
const verifyTask = async (task: Task) => {
setTaskIdBeingVerified(task.id);
setErrorForTask(null);
try {
const { isDone, errMessage, meta } = await task.verify({
repo: REPO,
owner: OWNER,
username: githubUsername,
// meta from previous task
meta: metaRef.current[lastDoneTask],
});
if (isDone) {
metaRef.current[task.id] = meta;
setLastDoneTask(task.id);
// TODO: what if this fails!!!???
await ChallengesService.putLastDoneTask(CHALLENGE_ID, task.id, metaRef.current);
} else {
delete metaRef.current[task.id];
setLastDoneTask(tasks[tasks.indexOf(task) - 1]?.id);
setErrorForTask({
id: task.id,
message: errMessage,
});
}
} catch (err) {
// TODO: add error directly in the task
console.error(err);
}
setTaskIdBeingVerified(null);
};
const handleGitHubRedirect = () => {
if (router.query.error_description) {
const errorDescription = Array.isArray(router.query.error_description)
? router.query.error_description[0]
: router.query.error_description;
SweetAlertService.toast({
text: errorDescription,
type: 'error',
timer: 4000,
});
}
router.replace(router.pathname);
};
useEffect(handleGitHubRedirect, []);
useEffect(() => {
if (user.info) {
// If user is logged in then let's get his github credentials!
setTaskIdBeingVerified(tasks[0].id);
UserService
.getGithubAccount()
.then(async (githubUser) => {
setGithubUsername(githubUser.login);
GitHubService.init(githubUser.access_token);
const { lastDoneTask, meta } = await ChallengesService.getLastDoneTask(CHALLENGE_ID);
if (lastDoneTask) {
metaRef.current = meta || {};
setLastDoneTask(lastDoneTask);
} else {
await ChallengesService.startTask(CHALLENGE_ID);
setLastDoneTask(tasks[0].id);
}
})
.catch((err) => {
console.log('ERROR', err);
setLastDoneTask(null);
})
.finally(() => setTaskIdBeingVerified(null));
}
}, [user.info]);
return (
<PageContainer>
<h1> Git & GitHub challenge ?</h1>
<p>
Dacă ai ajuns la acestă pagină înseamnă că faci parte
din grupul de Alpha Testeri care ne ajută cu feedback,
sau ne-ai stalkuit pe repo-ul din GitHub să vezi cum
se numesc rutele ?
</p>
<p>
Mai jos găsești primul challenge interactiv al platformei noastre.
Acesta conține challenge-uri ce se auto-validează ;)
</p>
{!user.info && (
<Button variant="success" onClick={withAuthModal(!!user.info, noop)}>
Autentifica-te ca sa incepi provocarea
</Button>
)}
<List className={styles['task-list']}>
{tasks.map((task, index) => {
let state: TaskState = 'available';
const isDisabled = !user.info
|| indexOfLastDoneTask < index - 1
|| indexOfLastDoneTask >= index;
if (isDisabled) {
state = 'disabled';
}
if (indexOfLastDoneTask >= index) {
state = 'done';
} else if (taskIdBeingVerified === task.id) {
state = 'loading';
} else if (errorForTask?.id === task.id) {
state = 'error';
}
let icon = <FontAwesomeIcon icon={faSync} />;
if (state === 'done') {
icon = <FontAwesomeIcon icon={faCheck} />;
} else if (state === 'disabled') {
icon = <FontAwesomeIcon icon={faBan} />;
} else if (state === 'loading') {
icon = <FontAwesomeIcon className="rotate" icon={faSpinner} />;
} else if (state === 'error') {
icon = <FontAwesomeIcon icon={faTimes} />;
}
return (
<li className={`${styles.task} ${styles[`task--${state}`]}`} key={task.id}>
<Button disabled={isDisabled} onClick={() => verifyTask(task)}>
{icon}
</Button>
<div>
{task.title}
{/* <Button
style={{ marginLeft: '1em' }}
variant={indexOfLastDoneTask >= index ? 'success' : 'blue'}
loading={taskIdBeingVerified === task.id}
disabled={isDisabled}
onClick={() => verifyTask(task)}
>
{indexOfLastDoneTask >= index ? 'DONE' : 'DO IT'}
</Button> */}
{errorForTask?.id === task.id && (
<p className={styles.task__error}>
{errorForTask.message}
</p>
)}
</div>
</li>
);
})}
</List>
{lastDoneTask === tasks[tasks.length - 1].id && (
<>
<hr />
<h2> Hooooray! You're ALL DONE! ??? </h2>
</>
)}
</PageContainer>
);
}
Example #18
Source File: index.tsx From portable with Apache License 2.0 | 4 votes |
render() {
const {
showSettings,
hasNotifications,
isLoading,
cluster
} = this.state
return (
<div className='header'>
<a className='logo' href='/' />
<div className='loading-icon'>
{isLoading && <FontAwesomeIcon icon={faSpinner} spin />}
</div>
<div className='selected-cluster'>
{!cluster && (
<div className='cluster'>
<div
className='not-selected-text'
onClick={this.props.handleOpenCluster}
>
no cluster selected
</div>
</div>
)}
{cluster && (
<div className='cluster'>
<img
className='cluster-logo'
src={`/img/clusters/${cluster.kind}.svg`}
alt={cluster.kind}
/>
<div
className='cluster-name'
onClick={this.props.handleOpenCluster}
>
{cluster.name}
</div>
</div>
)}
</div>
<div className='actions'>
{hasNotifications && (
<div className="btn-container">
<button
id="btnNotifications"
type="button"
className="btn btn-notifications"
onClick={this.openNotifications}
></button>
<span className="tooltiptext">Notifications</span>
</div>
)}
<div className="btn-container">
<button
id="btnHeaderSearch"
type="button"
className="btn btn-search"
onClick={this.openSearch}
/>
<span className="tooltiptext">Object Search</span>
</div>
<div className="btn-container">
<button
className="btn btn-settings"
onMouseEnter={() =>
this.setState({ showSettings: true })
}
onMouseLeave={() =>
this.setState({ showSettings: false })
}
/>
{showSettings && this.renderSettings()}
</div>
<div className="btn-container">
<button
id="btnHeaderAbout"
type="button"
className="btn btn-about"
onClick={this.openAbout}
></button>
<span className="tooltiptext">About Kubevious</span>
</div>
<div className="btn-container">
<a
href="https://github.com/kubevious/kubevious/issues/new/choose"
target="_blank"
className="btn btn-bug"
>
<img src={bugImg} alt="bug" />
</a>
<span className="tooltiptext">Report Issues</span>
</div>
<div className="btn-container">
<a
href="https://github.com/kubevious/kubevious"
target="_blank"
className="btn btn-github"
>
<img src={githubImg} alt="github" />
</a>
<span className="tooltiptext">GitHub Project</span>
</div>
<div className="btn-container">
<a
href="https://kubevious.io/slack"
target="_blank"
className="btn btn-slack"
>
<img src={slackImg} alt="slack" />
</a>
<span className="tooltiptext">Slack Channel</span>
</div>
</div>
</div>
)
}
Example #19
Source File: AttachmentUploader.tsx From AttachmentUploader with MIT License | 4 votes |
AttachmentUploader: React.FC<UploadProps> = (uploadProps: UploadProps) => {
const [uploadIcn,setuploadIcn]=React.useState(uploadProps.uploadIcon);
const [totalFileCount, setTotalFileCount] = React.useState(0);
const [currentUploadCount, setCurrentUploadCount] = React.useState(0);
const translate = (name:string) => uploadProps.context?.resources.getString(name);
const onDrop = React.useCallback((acceptedFiles:any) => {
if(acceptedFiles && acceptedFiles.length){
setTotalFileCount(acceptedFiles.length);
}
const toBase64 = async (file:any) => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onabort = () => reject();
reader.onerror = error => reject(error);
});
const uploadFileToRecord = async (id: string, entity: string,entitySetName:string,
fileInfo: FileInfo,context: ComponentFramework.Context<IInputs>)=>{
let isActivityMimeAttachment = (entity.toLowerCase() === "email" || entity.toLowerCase() === "appointment");
let attachmentRecord: ComponentFramework.WebApi.Entity = {};
if (isActivityMimeAttachment) {
attachmentRecord["[email protected]"] = `/activitypointers(${id})`;
attachmentRecord["body"] = fileInfo.body;
}
else {
attachmentRecord[`objectid_${entity}@odata.bind`] = `/${entitySetName}(${id})`;
attachmentRecord["documentbody"] = fileInfo.body;
}
if(fileInfo.type && fileInfo.type!==""){
attachmentRecord["mimetype"] =fileInfo.type;
}
attachmentRecord["filename"] = fileInfo.name;
attachmentRecord["objecttypecode"] = entity;
let attachmentEntity = isActivityMimeAttachment ? "activitymimeattachment" : "annotation";
await context.webAPI.createRecord(attachmentEntity, attachmentRecord)
}
const uploadFilesToCRM = async (files: any) => {
try{
for(let i=0;i<acceptedFiles.length;i++)
{
setCurrentUploadCount(i);
let file=acceptedFiles[i] as any;
let base64Data=await toBase64(acceptedFiles[i]);
let base64DataStr=base64Data as string;
let base64IndexOfBase64 = base64DataStr.indexOf(';base64,') + ';base64,'.length;
var base64 = base64DataStr.substring(base64IndexOfBase64);
let fileInfo:FileInfo ={name:file.name,type:file.type,body:base64};
let entityId = uploadProps.id;
let entityName = uploadProps.entityName;
if (entityId == null || entityId === "") {//this happens when the record is created and the user tries to upload
let currentPageContext = uploadProps.context as any;
currentPageContext = currentPageContext ? currentPageContext["page"] : undefined;
entityId = currentPageContext.entityId;
entityName = currentPageContext.entityTypeName;
}
await uploadFileToRecord(entityId,entityName,uploadProps.entitySetName, fileInfo,uploadProps.context!!);
}
}
catch(e: any){
let errorMessagePrefix=(acceptedFiles.length===1) ? translate("error_while_uploading_attachment") : translate("error_while_uploading_attachments");
let errOptions={message:`${errorMessagePrefix} ${e.message}`};
uploadProps.context?.navigation.openErrorDialog(errOptions)
}
setTotalFileCount(0);
let xrmObj: any = (window as any)["Xrm"];
if (xrmObj && xrmObj.Page && uploadProps.controlToRefresh) {
var controlToRefresh = xrmObj.Page.getControl(uploadProps.controlToRefresh);
if (controlToRefresh) {
controlToRefresh.refresh();
}
}
}
uploadFilesToCRM(acceptedFiles);
}, [totalFileCount,currentUploadCount])
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop })
if (uploadProps.id==null ||uploadProps.id === "") {
return (
<div className={"defaultContentCont"}>
{translate("save_record_to_enable_content")}
</div>
);
}
let fileStats = null;
if (totalFileCount > 0) {
fileStats = (
<div className={"filesStatsCont uploadDivs"}>
<div>
<FontAwesomeIcon icon={faSpinner} inverse size="2x" spin />
</div>
<div className={"uploadStatusText"}>
{translate("uploading")} ({currentUploadCount}/{totalFileCount})
</div>
</div>
);
}
return (
<div className={"dragDropCont"}>
<div className={"dropZoneCont uploadDivs"} {...getRootProps()} style={{ backgroundColor: isDragActive ? '#F8F8F8' : 'white' }}>
<input {...getInputProps()} />
<div>
<img className={"uploadImgDD"} src={uploadIcn} alt="Upload" />
</div>
<div>
{
isDragActive ?
<p>{translate("drop_files_here")}</p> :
<p>{translate("drop_files_here_or_click_to_upload")}</p>
}
</div>
</div>
{ fileStats }
</div>
)
}
Example #20
Source File: MarkdownTextarea.tsx From frontend.ro with MIT License | 4 votes |
function MarkdownTextarea({
title = 'Modifică',
markdown = '',
className = '',
disabled = false,
initialTab = 'EDIT',
onInput,
onUpload,
}: Props) {
const previewRef = useRef(null);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const fileInputRef = useRef<HTMLInputElement>(null);
const [isPreview, setIsPreview] = useState(initialTab === 'PREVIEW');
const [isFechingMarked, setIsFetchingMarked] = useState(false);
const [isUploading, setIsUploading] = useState(false);
const textareaInput = (e) => {
const text = e.target.value;
onInput(text);
};
const fileInput = (e: React.ChangeEvent<HTMLInputElement>) => uploadFiles([...e.target.files]);
const uploadFiles = async (files: File[]) => {
const validFiles = filterFiles(files, IMAGES_MIME_TYPES);
if (!validFiles.length) {
return;
}
setIsUploading(true);
const cursorPosition = textareaRef.current.selectionStart;
try {
await onUpload(validFiles, cursorPosition);
} catch (err) {
SweetAlertService.toast({
text: err.message || 'Oops! Nu am putut încărca poza ta. Încearcă din nou!',
type: 'error',
});
} finally {
setIsUploading(false);
fileInputRef.current.value = null;
}
};
const paste = (e: React.ClipboardEvent<HTMLTextAreaElement>) => {
const first = e.clipboardData.items[0];
if (first?.kind === 'file') {
uploadFiles([first.getAsFile()]);
}
};
useEffect(() => {
if (isPreview) {
setIsFetchingMarked(true);
import('marked')
.then((module) => {
const { marked } = module;
previewRef.current.innerHTML = marked.parse(markdown);
})
.catch((err) => {
previewRef.current.innerHTML = '<p style="color: red;"> Oops! Verifică conexiunea la net și încearcă din nou </p>';
})
.finally(() => setIsFetchingMarked(false));
}
}, [isPreview]);
return (
<div className={`${styles['markdown-textarea']} ${className}`}>
<label className={`${styles.label} ${isPreview ? '' : `${styles['is--checked']}`}`}>
{title}
<input checked={!isPreview} onChange={() => setIsPreview(false)} type="radio" name="nav" hidden />
</label>
<label className={`${styles.label} ${isPreview ? `${styles['is--checked']}` : ''}`}>
{isFechingMarked
? <FontAwesomeIcon width="20" className="text-white rotate" icon={faSpinner} />
: 'Preview'}
<input checked={isPreview} onChange={() => setIsPreview(true)} type="radio" name="nav" hidden />
</label>
<div>
<div className="relative">
<textarea
placeholder="Editează folosing Markdown..."
ref={textareaRef}
disabled={isPreview || disabled}
className={`${isPreview ? 'd-none absolute' : ''}`}
value={markdown}
rows={10}
onChange={textareaInput}
onPaste={paste}
/>
<div ref={previewRef} className={`${isPreview ? '' : 'd-none absolute'}`} />
</div>
{!disabled && (
<footer className="text-right relative">
{!isPreview && (
<label className="absolute">
{isUploading ? <FontAwesomeIcon className="rotate" icon={faSpinner} /> : 'Adaugă imagini'}
<input
ref={fileInputRef}
disabled={isUploading || disabled}
type="file"
multiple={false}
accept={IMAGES_MIME_TYPES.join(',')}
onChange={fileInput}
hidden
/>
</label>
)}
<FontAwesomeIcon icon={faMarkdown} width="20" />
</footer>
)}
</div>
</div>
);
}
Example #21
Source File: LoginView.tsx From 3Speak-app with GNU General Public License v3.0 | 4 votes |
export function LoginView() {
const submitRef = useRef<any>()
const [username, setUsername] = useState('')
const [key, setKey] = useState('')
const [profile, setProfile] = useState('')
const [encryption, setEncryption] = useState(false)
const [symKey, setSymKey] = useState('')
const [accountType, setAccountType] = useState('hive')
const [submitting, setSubmitting] = useState(false)
const resetForm = () => {
console.log(`resetting form`)
setUsername('')
setKey('')
}
const onUsernameChange = useCallback(async (event) => {
console.log(`username change ${event.target.value}`)
setUsername(event.target.value)
}, [])
const onKeyChange = useCallback(async (event) => {
setKey(event.target.value)
}, [])
const onProfileChange = useCallback(async (event) => {
setProfile(event.target.value)
}, [])
const onEncryptionChange = useCallback(async (event) => {
setEncryption(event.target.checked)
}, [])
const onSymKeyChange = useCallback(async (event) => {
setSymKey(event.target.value)
}, [])
const handleSubmit = useCallback(
async (event) => {
event.preventDefault()
const login = {
username: username,
key: key,
profile: profile,
accountType: accountType,
symKey: symKey,
isEncrypted: encryption,
}
setSubmitting(true)
submitRef?.current?.setAttribute('disabled', 'disabled')
try {
const loginHandler = (await AccountService.login(login)) as any
console.log(loginHandler)
if (loginHandler.nickname === login.username) {
window.location.reload()
} else {
console.log({ loginHandler, response: 'unsucessful' })
}
} catch (ex) {
NotificationManager.error(ex.toString())
throw ex
}
setSubmitting(false)
resetForm()
submitRef.current.removeAttribute('disabled')
},
[username, key, profile, accountType, symKey, encryption],
)
return (
<>
<Form
id="contact-form"
onSubmit={(event) => {
void handleSubmit(event)
}}
style={{
maxWidth: '600px',
width: '100%',
padding: '20px',
alignItems: 'center',
}}
>
<div className="p-3" style={{ width: '100%' }}>
<Form.Label className="text-secondary">Account type</Form.Label>
<Dropdown className="mb-2">
<Dropdown.Toggle variant="secondary">{accountType}</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item
onClick={() => {
setAccountType('hive')
}}
>
Hive
</Dropdown.Item>
<Dropdown.Item
onClick={() => {
setAccountType('IDX')
}}
>
IDX
</Dropdown.Item>
<Dropdown.Item
onClick={() => {
setAccountType('other')
}}
>
Other
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
{accountType !== 'hive' ? (
<OverlayTrigger
placement={'top'}
overlay={<Tooltip id="coming-soon">Disabled (Coming Soon!)</Tooltip>}
>
<div>
<Form.Group>
<Form.Label className="text-secondary">Profile name</Form.Label>
<Form.Control
type="text"
value={profile}
onChange={onProfileChange}
className="bg-secondary text-light"
disabled
required
/>
</Form.Group>
<Form.Group>
<Form.Label className="text-secondary">Username</Form.Label>
<Form.Control
type="text"
value={username}
onChange={onUsernameChange}
className="bg-secondary text-light"
disabled
required
/>
</Form.Group>
</div>
</OverlayTrigger>
) : (
<>
<Form.Group>
<Form.Label className="text-secondary">Profile name</Form.Label>
<Form.Control
type="text"
value={profile}
onChange={onProfileChange}
className="bg-secondary text-light"
required
/>
</Form.Group>
<Form.Group>
<Form.Label className="text-secondary">Username</Form.Label>
<Form.Control
type="text"
value={username}
onChange={onUsernameChange}
className="bg-secondary text-light"
required
/>
</Form.Group>
</>
)}
{accountType === 'hive' && (
<Form.Group>
<Form.Label className="text-secondary">Hive Private Posting Key</Form.Label>
<Form.Control
type="password"
value={key}
onChange={onKeyChange}
className="bg-secondary text-light"
pattern="5[HJK][1-9A-HJ-NP-Za-km-z]{49}"
required
/>
</Form.Group>
)}
<OverlayTrigger
placement={'top'}
overlay={<Tooltip id="coming-soon">Disabled (Coming Soon!)</Tooltip>}
>
<div>
<label className="text-secondary mr-2" htmlFor="enable-encryption">
Enable Encryption
</label>
<input
name="enable-encryption"
type="checkbox"
checked={encryption}
disabled
onChange={onEncryptionChange}
/>
</div>
</OverlayTrigger>
{encryption && (
<Form.Group>
<Form.Label className="text-secondary">Symmetric Key</Form.Label>
<Form.Control
type="text"
value={symKey}
onChange={onSymKeyChange}
className="bg-secondary text-light"
/>
</Form.Group>
)}
<br />
<span className="tag-wrap">
<Button type="submit" ref={submitRef} variant="secondary">
{submitting ? <FontAwesomeIcon icon={faSpinner as any} spin /> : 'Submit'}
</Button>
</span>
</div>
</Form>
</>
)
}