forked from aws-samples/generative-ai-use-cases-jp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request aws-samples#227 from aws-samples/fearure/inter-use…
…-case-demo ユースケース間連携デモ
- Loading branch information
Showing
17 changed files
with
502 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export type InterUseCaseState<T extends Record<string, unknown> = any> = { | ||
// key に設定先の画面項目を設定 | ||
// useLocationのstateで管理している項目のみ指定可能 | ||
[key in keyof T]: { | ||
// value に設定したい値を設定 | ||
// 遷移元の画面項目の値を埋め込みたい場合は、{interUseCasesKey}を設定することで埋め込み可能 | ||
// 例) contextに設定されている値を埋め込みたい場合は、{context}を設定する | ||
value: string; | ||
}; | ||
}; | ||
export type InterUseCase = { | ||
title: string; | ||
description: string; | ||
path: string; | ||
state?: InterUseCaseState; | ||
}; | ||
|
||
export type ChatPageLocationState = { | ||
content: string; | ||
}; | ||
|
||
export type EditorialPageLocationState = { | ||
sentence: string; | ||
}; | ||
|
||
export type GenerateImagePageLocationState = { | ||
content: string; | ||
}; | ||
|
||
export type GenerateTextPageLocationState = { | ||
information: string; | ||
context: string; | ||
}; | ||
|
||
export type RagPageLocationState = { | ||
content: stiring; | ||
}; | ||
|
||
export type SummarizePageLocationState = { | ||
sentence: string; | ||
additionalContext: string; | ||
}; | ||
|
||
export type TranslatePageLocationState = { | ||
sentence: string; | ||
additionalContext: string; | ||
language: string; | ||
}; | ||
|
||
export type WebContentPageLocationState = { | ||
url: string; | ||
context: string; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import React, { useState } from 'react'; | ||
import { BaseProps } from '../@types/common'; | ||
import { PiArrowFatRightFill, PiCaretDown, PiX } from 'react-icons/pi'; | ||
import ButtonIcon from './ButtonIcon'; | ||
import useInterUseCases from '../hooks/useInterUseCases'; | ||
|
||
type Props = BaseProps; | ||
|
||
const PopupInterUseCasesDemo: React.FC<Props> = () => { | ||
const { | ||
setIsShow, | ||
title, | ||
useCases, | ||
currentIndex, | ||
setCurrentIndex, | ||
navigateUseCase, | ||
} = useInterUseCases(); | ||
const [isOpen, setIsOpen] = useState(true); | ||
|
||
return ( | ||
<div className="fixed top-0 z-50 ml-10 w-11/12 pt-1 lg:left-1/3 lg:w-1/2 lg:p-3"> | ||
<div className="border-aws-squid-ink/50 relative rounded border bg-white p-3 shadow-lg"> | ||
<div className="flex w-full"> | ||
<div | ||
className=" flex w-full cursor-pointer items-center rounded font-bold hover:bg-gray-200" | ||
onClick={() => { | ||
setIsOpen(!isOpen); | ||
}}> | ||
<PiCaretDown | ||
className={`transition ${!isOpen && 'rotate-180'} mr-2`} | ||
/> | ||
{title} | ||
</div> | ||
<ButtonIcon | ||
className={`right-1 top-1 -m-1 `} | ||
onClick={() => { | ||
setIsShow(false); | ||
}}> | ||
<PiX /> | ||
</ButtonIcon> | ||
</div> | ||
|
||
<div | ||
className={`origin-top transition ${ | ||
isOpen ? 'visible mt-3 ' : 'h-0 scale-y-0' | ||
}`}> | ||
<div className=" grid grid-cols-3 gap-2 text-sm"> | ||
{useCases.map((usecase, idx) => ( | ||
<div | ||
key={idx} | ||
className={`${ | ||
idx === currentIndex && | ||
'border-aws-squid-ink border font-bold' | ||
} | ||
${ | ||
idx > currentIndex + 1 || idx < currentIndex - 1 | ||
? 'opacity-50 hover:brightness-100' | ||
: 'cursor-pointer hover:brightness-75 ' | ||
} | ||
bg-aws-smile relative mx-2 rounded p-1 px-2 text-white shadow `} | ||
onClick={() => { | ||
if (idx > currentIndex + 1 || idx < currentIndex - 1) { | ||
return; | ||
} | ||
setCurrentIndex(idx); | ||
navigateUseCase(idx); | ||
}}> | ||
<div>{usecase.title}</div> | ||
<PiArrowFatRightFill | ||
className={`text-aws-squid-ink absolute -right-5 top-2 ${ | ||
useCases.length - 1 === idx && 'invisible' | ||
}`} | ||
/> | ||
</div> | ||
))} | ||
</div> | ||
<div className="mt-2 rounded border p-2 text-xs"> | ||
{useCases[currentIndex].description && | ||
useCases[currentIndex].description | ||
.split('\n') | ||
.map((s, idx) => <div key={idx}>{s}</div>)} | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default PopupInterUseCasesDemo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { produce } from 'immer'; | ||
import { useNavigate } from 'react-router-dom'; | ||
import { create } from 'zustand'; | ||
import { InterUseCase } from '../@types/navigate'; | ||
|
||
const useInterUseCasesState = create<{ | ||
isShow: boolean; | ||
setIsShow: (b: boolean) => void; | ||
title: string; | ||
useCases: InterUseCase[]; | ||
setUseCases: (title: string, usecases: InterUseCase[]) => void; | ||
currentIndex: number; | ||
setCurrentIndex: (n: number) => void; | ||
copyTemporary: { | ||
[key: string]: string; | ||
}; | ||
setCopyTemporary: (key: string, value: string) => void; | ||
}>((set, get) => { | ||
return { | ||
isShow: false, | ||
setIsShow: (b) => { | ||
set(() => ({ | ||
isShow: b, | ||
})); | ||
}, | ||
title: '', | ||
useCases: [], | ||
setUseCases: (title, useCases) => { | ||
set(() => ({ | ||
title, | ||
useCases, | ||
})); | ||
}, | ||
currentIndex: -1, | ||
setCurrentIndex: (n: number) => { | ||
set(() => ({ | ||
currentIndex: n, | ||
})); | ||
}, | ||
copyTemporary: {}, | ||
setCopyTemporary: (key, value) => { | ||
const tmp = produce(get().copyTemporary, (draft) => { | ||
draft[key] = value; | ||
}); | ||
set(() => ({ | ||
copyTemporary: tmp, | ||
})); | ||
}, | ||
}; | ||
}); | ||
|
||
const useInterUseCases = () => { | ||
const navigate = useNavigate(); | ||
const { | ||
isShow, | ||
setIsShow, | ||
title, | ||
useCases, | ||
setUseCases, | ||
currentIndex, | ||
setCurrentIndex, | ||
copyTemporary, | ||
setCopyTemporary, | ||
} = useInterUseCasesState(); | ||
|
||
const navigateUseCase_ = (usecase: InterUseCase) => { | ||
const state: Record<string, string> = {}; | ||
|
||
Object.entries(usecase.state ?? {}).forEach(([key, { value }]) => { | ||
let replacedValue = value; | ||
|
||
// 遷移元の画面項目の値を埋め込む処理 | ||
// value 内の{}で囲われたキー名を取得し、copyTemporary から当該のキー名の値を取得して、置換する | ||
// 例) {context} が設定されている場合は、copyTemporary から context の値を取得し、{context} をその値で置換する。 | ||
const matches = value.match(/\{(.+?)\}/g); | ||
matches?.forEach((m) => { | ||
replacedValue = replacedValue.replace( | ||
m, | ||
copyTemporary[m.replace(/({|})/g, '')] | ||
); | ||
}); | ||
|
||
state[key] = replacedValue; | ||
}); | ||
|
||
navigate(usecase.path, { | ||
state, | ||
}); | ||
}; | ||
|
||
return { | ||
isShow, | ||
setIsShow, | ||
title, | ||
useCases, | ||
setUseCases, | ||
currentIndex, | ||
setCurrentIndex, | ||
setCopyTemporary, | ||
navigateUseCase: (idx: number) => { | ||
navigateUseCase_(useCases[idx]); | ||
}, | ||
init: (title: string, usecasesList: InterUseCase[]) => { | ||
setCurrentIndex(0); | ||
setUseCases(title, usecasesList); | ||
navigateUseCase_(usecasesList[0]); | ||
}, | ||
}; | ||
}; | ||
|
||
export default useInterUseCases; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.