mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
F: Add QR feature for RSForm
This commit is contained in:
parent
97178d8114
commit
dc7cea8eaa
|
@ -42,6 +42,7 @@ This readme file is used mostly to document project dependencies and conventions
|
||||||
- reactflow
|
- reactflow
|
||||||
- js-file-download
|
- js-file-download
|
||||||
- use-debounce
|
- use-debounce
|
||||||
|
- qrcode.react
|
||||||
- html-to-image
|
- html-to-image
|
||||||
- @tanstack/react-table
|
- @tanstack/react-table
|
||||||
- @uiw/react-codemirror
|
- @uiw/react-codemirror
|
||||||
|
|
10
rsconcept/frontend/package-lock.json
generated
10
rsconcept/frontend/package-lock.json
generated
|
@ -17,6 +17,7 @@
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"html-to-image": "^1.11.11",
|
"html-to-image": "^1.11.11",
|
||||||
"js-file-download": "^0.4.12",
|
"js-file-download": "^0.4.12",
|
||||||
|
"qrcode.react": "^4.2.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-error-boundary": "^4.1.2",
|
"react-error-boundary": "^4.1.2",
|
||||||
|
@ -8666,6 +8667,15 @@
|
||||||
],
|
],
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/qrcode.react": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==",
|
||||||
|
"license": "ISC",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/queue-microtask": {
|
"node_modules/queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"html-to-image": "^1.11.11",
|
"html-to-image": "^1.11.11",
|
||||||
"js-file-download": "^0.4.12",
|
"js-file-download": "^0.4.12",
|
||||||
|
"qrcode.react": "^4.2.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-error-boundary": "^4.1.2",
|
"react-error-boundary": "^4.1.2",
|
||||||
|
|
|
@ -20,6 +20,7 @@ export { TbEye as IconShow } from 'react-icons/tb';
|
||||||
export { TbEyeX as IconHide } from 'react-icons/tb';
|
export { TbEyeX as IconHide } from 'react-icons/tb';
|
||||||
export { BiShareAlt as IconShare } from 'react-icons/bi';
|
export { BiShareAlt as IconShare } from 'react-icons/bi';
|
||||||
export { LuFilter as IconFilter } from 'react-icons/lu';
|
export { LuFilter as IconFilter } from 'react-icons/lu';
|
||||||
|
export { LuQrCode as IconQR } from 'react-icons/lu';
|
||||||
export { LuFilterX as IconFilterReset } from 'react-icons/lu';
|
export { LuFilterX as IconFilterReset } from 'react-icons/lu';
|
||||||
export {BiDownArrowCircle as IconOpenList } from 'react-icons/bi';
|
export {BiDownArrowCircle as IconOpenList } from 'react-icons/bi';
|
||||||
export { LuTriangleAlert as IconAlert } from 'react-icons/lu';
|
export { LuTriangleAlert as IconAlert } from 'react-icons/lu';
|
||||||
|
|
26
rsconcept/frontend/src/dialogs/DlgShowQR.tsx
Normal file
26
rsconcept/frontend/src/dialogs/DlgShowQR.tsx
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import { QRCodeSVG } from 'qrcode.react';
|
||||||
|
|
||||||
|
import Modal, { ModalProps } from '@/components/ui/Modal';
|
||||||
|
|
||||||
|
interface DlgShowQRProps extends Pick<ModalProps, 'hideWindow'> {
|
||||||
|
target: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function DlgShowQR({ hideWindow, target }: DlgShowQRProps) {
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
readonly
|
||||||
|
hideWindow={hideWindow}
|
||||||
|
className={clsx('w-[30rem]', 'py-12 pr-3 pl-6 flex gap-3 justify-center items-center')}
|
||||||
|
>
|
||||||
|
<div className='bg-[#ffffff] p-4 border'>
|
||||||
|
<QRCodeSVG value={target} size={256} />
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DlgShowQR;
|
|
@ -19,6 +19,7 @@ import {
|
||||||
IconNewVersion,
|
IconNewVersion,
|
||||||
IconOSS,
|
IconOSS,
|
||||||
IconOwner,
|
IconOwner,
|
||||||
|
IconQR,
|
||||||
IconReader,
|
IconReader,
|
||||||
IconReplace,
|
IconReplace,
|
||||||
IconShare,
|
IconShare,
|
||||||
|
@ -85,6 +86,11 @@ function MenuRSTabs({ onDestroy }: MenuRSTabsProps) {
|
||||||
controller.share();
|
controller.share();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleShowQR() {
|
||||||
|
schemaMenu.hide();
|
||||||
|
controller.showQR();
|
||||||
|
}
|
||||||
|
|
||||||
function handleCreateVersion() {
|
function handleCreateVersion() {
|
||||||
schemaMenu.hide();
|
schemaMenu.hide();
|
||||||
controller.createVersion();
|
controller.createVersion();
|
||||||
|
@ -155,10 +161,16 @@ function MenuRSTabs({ onDestroy }: MenuRSTabsProps) {
|
||||||
onClick={handleShare}
|
onClick={handleShare}
|
||||||
disabled={controller.schema?.access_policy !== AccessPolicy.PUBLIC}
|
disabled={controller.schema?.access_policy !== AccessPolicy.PUBLIC}
|
||||||
/>
|
/>
|
||||||
|
<DropdownButton
|
||||||
|
text='QR-код'
|
||||||
|
title='Показать QR-код схемы'
|
||||||
|
icon={<IconQR size='1rem' className='icon-primary' />}
|
||||||
|
onClick={handleShowQR}
|
||||||
|
/>
|
||||||
{user ? (
|
{user ? (
|
||||||
<DropdownButton
|
<DropdownButton
|
||||||
text='Клонировать'
|
text='Клонировать'
|
||||||
icon={<IconClone size='1rem' className='icon-primary' />}
|
icon={<IconClone size='1rem' className='icon-green' />}
|
||||||
disabled={model.isArchive}
|
disabled={model.isArchive}
|
||||||
onClick={handleClone}
|
onClick={handleClone}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -21,6 +21,7 @@ import DlgEditVersions from '@/dialogs/DlgEditVersions';
|
||||||
import DlgEditWordForms from '@/dialogs/DlgEditWordForms';
|
import DlgEditWordForms from '@/dialogs/DlgEditWordForms';
|
||||||
import DlgInlineSynthesis from '@/dialogs/DlgInlineSynthesis';
|
import DlgInlineSynthesis from '@/dialogs/DlgInlineSynthesis';
|
||||||
import DlgRenameCst from '@/dialogs/DlgRenameCst';
|
import DlgRenameCst from '@/dialogs/DlgRenameCst';
|
||||||
|
import DlgShowQR from '@/dialogs/DlgShowQR';
|
||||||
import DlgShowTypeGraph from '@/dialogs/DlgShowTypeGraph';
|
import DlgShowTypeGraph from '@/dialogs/DlgShowTypeGraph';
|
||||||
import DlgSubstituteCst from '@/dialogs/DlgSubstituteCst';
|
import DlgSubstituteCst from '@/dialogs/DlgSubstituteCst';
|
||||||
import DlgUploadRSForm from '@/dialogs/DlgUploadRSForm';
|
import DlgUploadRSForm from '@/dialogs/DlgUploadRSForm';
|
||||||
|
@ -108,6 +109,7 @@ export interface IRSEditContext extends ILibraryItemEditor {
|
||||||
substitute: () => void;
|
substitute: () => void;
|
||||||
|
|
||||||
showTypeGraph: () => void;
|
showTypeGraph: () => void;
|
||||||
|
showQR: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RSEditContext = createContext<IRSEditContext | null>(null);
|
const RSEditContext = createContext<IRSEditContext | null>(null);
|
||||||
|
@ -172,6 +174,7 @@ export const RSEditState = ({
|
||||||
const [showEditVersions, setShowEditVersions] = useState(false);
|
const [showEditVersions, setShowEditVersions] = useState(false);
|
||||||
const [showInlineSynthesis, setShowInlineSynthesis] = useState(false);
|
const [showInlineSynthesis, setShowInlineSynthesis] = useState(false);
|
||||||
const [showTypeGraph, setShowTypeGraph] = useState(false);
|
const [showTypeGraph, setShowTypeGraph] = useState(false);
|
||||||
|
const [showQR, setShowQR] = useState(false);
|
||||||
|
|
||||||
const [createInitialData, setCreateInitialData] = useState<ICstCreateData>();
|
const [createInitialData, setCreateInitialData] = useState<ICstCreateData>();
|
||||||
const [showCreateCst, setShowCreateCst] = useState(false);
|
const [showCreateCst, setShowCreateCst] = useState(false);
|
||||||
|
@ -627,6 +630,11 @@ export const RSEditState = ({
|
||||||
[model]
|
[model]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function generateQR(): string {
|
||||||
|
const currentRef = window.location.href;
|
||||||
|
return currentRef.includes('?') ? currentRef + '&qr' : currentRef + '?qr';
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RSEditContext
|
<RSEditContext
|
||||||
value={{
|
value={{
|
||||||
|
@ -679,11 +687,13 @@ export const RSEditState = ({
|
||||||
produceStructure,
|
produceStructure,
|
||||||
substitute,
|
substitute,
|
||||||
|
|
||||||
showTypeGraph: () => setShowTypeGraph(true)
|
showTypeGraph: () => setShowTypeGraph(true),
|
||||||
|
showQR: () => setShowQR(true)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{model.schema ? (
|
{model.schema ? (
|
||||||
<>
|
<>
|
||||||
|
{showQR ? <DlgShowQR hideWindow={() => setShowQR(false)} target={generateQR()} /> : null}
|
||||||
{showUpload ? <DlgUploadRSForm hideWindow={() => setShowUpload(false)} /> : null}
|
{showUpload ? <DlgUploadRSForm hideWindow={() => setShowUpload(false)} /> : null}
|
||||||
{showClone ? (
|
{showClone ? (
|
||||||
<DlgCloneLibraryItem
|
<DlgCloneLibraryItem
|
||||||
|
|
Loading…
Reference in New Issue
Block a user