@uniai-fe/uds-templates 0.1.28 → 0.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/cctv/components/Provider.tsx +33 -12
- package/src/cctv/hooks/useCompanyData.tsx +2 -2
- package/src/cctv/hooks/useContext.ts +3 -2
- package/src/cctv/hooks/useRtcStream.ts +2 -2
- package/src/cctv/types/context.ts +31 -0
- package/src/cctv/components/__viewer.tsx +0 -99
package/package.json
CHANGED
|
@@ -3,18 +3,44 @@
|
|
|
3
3
|
import { createContext, useContext } from "react";
|
|
4
4
|
import { Form } from "@uniai-fe/uds-primitives";
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
CctvApiUrlContext,
|
|
8
|
+
CctvContext,
|
|
9
|
+
CctvProviderProps,
|
|
10
|
+
} from "../types";
|
|
7
11
|
import { CCTV_CONTEXT_DEFAULT_VALUES } from "../data";
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
/**
|
|
14
|
+
* CCTV; API 경로 컨텍스트
|
|
15
|
+
* @property {string} [listUrl] company-list API 요청 경로
|
|
16
|
+
* @property {string} [tokenUrl] token API 요청 경로
|
|
17
|
+
*/
|
|
18
|
+
const ApiUrlContext = createContext<CctvApiUrlContext>({
|
|
10
19
|
listUrl: undefined,
|
|
11
20
|
tokenUrl: undefined,
|
|
12
21
|
});
|
|
13
22
|
|
|
14
|
-
|
|
15
|
-
|
|
23
|
+
/**
|
|
24
|
+
* CCTV; API 경로 컨텍스트
|
|
25
|
+
* @return {CctvApiUrlContext}
|
|
26
|
+
* @desc
|
|
27
|
+
* - listUrl: company-list API 요청 경로
|
|
28
|
+
* - tokenUrl: token API 요청 경로
|
|
29
|
+
*/
|
|
30
|
+
export function useCctvApiUrl(): CctvApiUrlContext {
|
|
31
|
+
return useContext(ApiUrlContext);
|
|
16
32
|
}
|
|
17
33
|
|
|
34
|
+
/**
|
|
35
|
+
* CCTV; Provider props
|
|
36
|
+
* @component
|
|
37
|
+
* @property {string} [company_id] 선택된 업체 id코드
|
|
38
|
+
* @property {string} [cam_id] 선택된 카메라 id코드
|
|
39
|
+
* @property {string} [listUrl] company-list API 요청 경로
|
|
40
|
+
* @property {string} [tokenUrl] token API 요청 경로
|
|
41
|
+
* @property {string} [username] CCTV 조회시 권한 확인을 위한 계정명
|
|
42
|
+
* @property {React.ReactNode} children
|
|
43
|
+
*/
|
|
18
44
|
export default function CCTVProvider({
|
|
19
45
|
username,
|
|
20
46
|
company_id,
|
|
@@ -22,14 +48,9 @@ export default function CCTVProvider({
|
|
|
22
48
|
listUrl,
|
|
23
49
|
tokenUrl,
|
|
24
50
|
children,
|
|
25
|
-
}: {
|
|
26
|
-
username: string;
|
|
27
|
-
children: React.ReactNode;
|
|
28
|
-
listUrl?: string;
|
|
29
|
-
tokenUrl?: string;
|
|
30
|
-
} & CctvSelectedContext) {
|
|
51
|
+
}: CctvProviderProps) {
|
|
31
52
|
return (
|
|
32
|
-
<
|
|
53
|
+
<ApiUrlContext.Provider value={{ listUrl, tokenUrl }}>
|
|
33
54
|
<Form.Provider<CctvContext>
|
|
34
55
|
options={{
|
|
35
56
|
defaultValues: {
|
|
@@ -42,6 +63,6 @@ export default function CCTVProvider({
|
|
|
42
63
|
>
|
|
43
64
|
{children}
|
|
44
65
|
</Form.Provider>
|
|
45
|
-
</
|
|
66
|
+
</ApiUrlContext.Provider>
|
|
46
67
|
);
|
|
47
68
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useEffect, useMemo } from "react";
|
|
4
4
|
import { useQueryCctvCompanyList } from "../apis";
|
|
5
|
-
import {
|
|
5
|
+
import { useCctvApiUrl } from "../components/Provider";
|
|
6
6
|
import useCctvContext from "./useContext";
|
|
7
7
|
|
|
8
8
|
export default function useCctvCompanyData(params?: {
|
|
@@ -11,7 +11,7 @@ export default function useCctvCompanyData(params?: {
|
|
|
11
11
|
}) {
|
|
12
12
|
const { username, url } = params || {};
|
|
13
13
|
|
|
14
|
-
const { listUrl } =
|
|
14
|
+
const { listUrl } = useCctvApiUrl();
|
|
15
15
|
const resolvedUrl = useMemo(() => url ?? listUrl, [url, listUrl]);
|
|
16
16
|
const { username: contextUsername, setValue } = useCctvContext();
|
|
17
17
|
|
|
@@ -13,9 +13,10 @@ import type {
|
|
|
13
13
|
} from "../types";
|
|
14
14
|
import { initCompanyList } from "../utils/data";
|
|
15
15
|
import { getCam, getCamList, getCompany } from "../utils/select";
|
|
16
|
+
import { getSafePathname } from "@uniai-fe/util-functions";
|
|
16
17
|
|
|
17
|
-
export default function useCctvContext(
|
|
18
|
-
const
|
|
18
|
+
export default function useCctvContext() {
|
|
19
|
+
const pageCode = useMemo(() => getSafePathname("cctv"), []);
|
|
19
20
|
|
|
20
21
|
const setCtx = useSetAtom(cctvSelectedContext);
|
|
21
22
|
const { control, setValue, ...context } = useFormContext<CctvContext>();
|
|
@@ -4,7 +4,7 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
|
|
4
4
|
import { startWhepStream, type WhepStreamHandle } from "@uniai-fe/util-rtc";
|
|
5
5
|
|
|
6
6
|
import { useQueryCctvRtcToken } from "../apis/client";
|
|
7
|
-
import {
|
|
7
|
+
import { useCctvApiUrl } from "../components/Provider";
|
|
8
8
|
import type { CctvCompanyCameraList } from "../types";
|
|
9
9
|
import { useFormContext, useWatch } from "react-hook-form";
|
|
10
10
|
|
|
@@ -19,7 +19,7 @@ export function useCctvRtcStream({
|
|
|
19
19
|
companyId,
|
|
20
20
|
tokenUrl,
|
|
21
21
|
}: UseCctvRtcStreamParams) {
|
|
22
|
-
const { tokenUrl: contextTokenUrl } =
|
|
22
|
+
const { tokenUrl: contextTokenUrl } = useCctvApiUrl();
|
|
23
23
|
const videoRef = useRef<HTMLVideoElement | null>(null);
|
|
24
24
|
const [connectionState, setConnectionState] =
|
|
25
25
|
useState<RTCPeerConnectionState>("new");
|
|
@@ -39,6 +39,22 @@ export interface CctvSelectedContext {
|
|
|
39
39
|
cam_id?: string;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* CCTV; API 경로 컨텍스트 (optional)
|
|
44
|
+
* @property {string} [listUrl] company-list API 요청 경로
|
|
45
|
+
* @property {string} [tokenUrl] token API 요청 경로
|
|
46
|
+
*/
|
|
47
|
+
export interface CctvApiUrlContext {
|
|
48
|
+
/**
|
|
49
|
+
* company-list API 요청 경로
|
|
50
|
+
*/
|
|
51
|
+
listUrl?: string;
|
|
52
|
+
/**
|
|
53
|
+
* token API 요청 경로
|
|
54
|
+
*/
|
|
55
|
+
tokenUrl?: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
42
58
|
/**
|
|
43
59
|
* CCTV; 실시간 영상보기 컨텍스트
|
|
44
60
|
* @property {string} [company_id] 선택된 업체 id코드
|
|
@@ -66,3 +82,18 @@ export interface CctvContext extends CctvSelectedContext {
|
|
|
66
82
|
isFetching: boolean;
|
|
67
83
|
isError: boolean;
|
|
68
84
|
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* CCTV; Provider props
|
|
88
|
+
* @property {string} [company_id] 선택된 업체 id코드
|
|
89
|
+
* @property {string} [cam_id] 선택된 카메라 id코드
|
|
90
|
+
* @property {string} [listUrl] company-list API 요청 경로
|
|
91
|
+
* @property {string} [tokenUrl] token API 요청 경로
|
|
92
|
+
* @property {string} [username] CCTV 조회시 권한 확인을 위한 계정명
|
|
93
|
+
* @property {React.ReactNode} children
|
|
94
|
+
*/
|
|
95
|
+
export type CctvProviderProps = CctvSelectedContext &
|
|
96
|
+
CctvApiUrlContext & {
|
|
97
|
+
username?: string;
|
|
98
|
+
children: React.ReactNode;
|
|
99
|
+
};
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
// "use client";
|
|
2
|
-
|
|
3
|
-
// import clsx from "clsx";
|
|
4
|
-
|
|
5
|
-
// import CCTVVideoContainer from "./video/Container";
|
|
6
|
-
// import CCTVVideoContents from "./video/Video";
|
|
7
|
-
// import CCTVVideoOverlayContainer from "./video/overlay/Container";
|
|
8
|
-
// import CCTVVideoOverlayHeader from "./video/overlay/header/Container";
|
|
9
|
-
// import CCTVVideoOverlayBody from "./video/overlay/body/Container";
|
|
10
|
-
// import CCTVVideoError from "./video/overlay/body/Error";
|
|
11
|
-
// import CCTVVideoOverlayFooter from "./video/overlay/footer/Container";
|
|
12
|
-
// import { CCTVPagination } from "./pagination";
|
|
13
|
-
// import useCctvContext from "../hooks/useContext";
|
|
14
|
-
|
|
15
|
-
// export default function CCTVViewer({ className }: { className?: string }) {
|
|
16
|
-
// const { selectedCompany, selectedCam, cams, companyValidList, isFetching } =
|
|
17
|
-
// useCctvContext();
|
|
18
|
-
|
|
19
|
-
// const totalCamCount = selectedCompany?.cam_list.length ?? 0;
|
|
20
|
-
// const onlineCamCount = selectedCompany
|
|
21
|
-
// ? selectedCompany.cam_list.filter(({ cam_online }) => cam_online).length
|
|
22
|
-
// : 0;
|
|
23
|
-
|
|
24
|
-
// const renderVideoSection = () => {
|
|
25
|
-
// if (isFetching && !selectedCam) {
|
|
26
|
-
// return <ViewerPlaceholder message="CCTV 데이터를 불러오는 중입니다." />;
|
|
27
|
-
// }
|
|
28
|
-
|
|
29
|
-
// if (!selectedCam) {
|
|
30
|
-
// return <ViewerPlaceholder message="좌측 목록에서 카메라를 선택하세요." />;
|
|
31
|
-
// }
|
|
32
|
-
|
|
33
|
-
// const isCamOffline = !selectedCam.cam_online;
|
|
34
|
-
|
|
35
|
-
// return (
|
|
36
|
-
// <CCTVVideoContainer>
|
|
37
|
-
// <CCTVVideoContents />
|
|
38
|
-
// <CCTVVideoOverlayContainer>
|
|
39
|
-
// <CCTVVideoOverlayHeader
|
|
40
|
-
// activeLiveState
|
|
41
|
-
// activeTitle
|
|
42
|
-
// activeTime
|
|
43
|
-
// activeCloseButton
|
|
44
|
-
// liveStateDisabled={isCamOffline}
|
|
45
|
-
// />
|
|
46
|
-
// {isCamOffline && (
|
|
47
|
-
// <CCTVVideoOverlayBody className="is-error">
|
|
48
|
-
// <CCTVVideoError />
|
|
49
|
-
// </CCTVVideoOverlayBody>
|
|
50
|
-
// )}
|
|
51
|
-
// <CCTVVideoOverlayFooter
|
|
52
|
-
// activeTitle
|
|
53
|
-
// activeOpenButton={false}
|
|
54
|
-
// title={selectedCam.cam_name}
|
|
55
|
-
// />
|
|
56
|
-
// </CCTVVideoOverlayContainer>
|
|
57
|
-
// </CCTVVideoContainer>
|
|
58
|
-
// );
|
|
59
|
-
// };
|
|
60
|
-
|
|
61
|
-
// return (
|
|
62
|
-
// <section className={clsx("cctv-viewer", className)}>
|
|
63
|
-
// <header className="cctv-viewer-header">
|
|
64
|
-
// <div className="cctv-viewer-header-title">
|
|
65
|
-
// <p className="cctv-viewer-company-name">
|
|
66
|
-
// {selectedCompany?.company_name ?? "CCTV Viewer"}
|
|
67
|
-
// </p>
|
|
68
|
-
// <p className="cctv-viewer-company-meta">
|
|
69
|
-
// {selectedCompany
|
|
70
|
-
// ? `총 ${totalCamCount}대 중 ${onlineCamCount}대 가동`
|
|
71
|
-
// : "카메라를 선택하면 상세 정보를 볼 수 있습니다."}
|
|
72
|
-
// </p>
|
|
73
|
-
// </div>
|
|
74
|
-
// <div className="cctv-viewer-company-summary">
|
|
75
|
-
// <span>
|
|
76
|
-
// 연결된 업체 <strong>{companyValidList.length}</strong>
|
|
77
|
-
// </span>
|
|
78
|
-
// </div>
|
|
79
|
-
// </header>
|
|
80
|
-
|
|
81
|
-
// <div className="cctv-viewer-body">
|
|
82
|
-
// <div className="cctv-viewer-main">{renderVideoSection()}</div>
|
|
83
|
-
// <div className="cctv-viewer-carousel">
|
|
84
|
-
// <div className="cctv-viewer-carousel-header">
|
|
85
|
-
// <h4>카메라 목록</h4>
|
|
86
|
-
// <span>{cams.length}대</span>
|
|
87
|
-
// </div>
|
|
88
|
-
// <CCTVPagination.Container>
|
|
89
|
-
// <CCTVPagination.List.Container list={cams} />
|
|
90
|
-
// </CCTVPagination.Container>
|
|
91
|
-
// </div>
|
|
92
|
-
// </div>
|
|
93
|
-
// </section>
|
|
94
|
-
// );
|
|
95
|
-
// }
|
|
96
|
-
|
|
97
|
-
// function ViewerPlaceholder({ message }: { message: string }) {
|
|
98
|
-
// return <div className="cctv-viewer-placeholder">{message}</div>;
|
|
99
|
-
// }
|