Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: LTI Deep Linking 2.0 #980

Merged
merged 25 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2d8aa8c
feat: Deep Linking Responce JWT 取得 API
kou029w Jul 11, 2023
8b959e9
feat: /book/linking auto-submitted form の実装
kou029w Jul 11, 2023
3399695
feat: Target Link URI を LTI Resource Link として紐付ける
kou029w Jul 11, 2023
575f459
UI: Deep Linking でのリンクの選択画面でのいくつかの操作の廃止
YouheiNozaki Jul 9, 2023
ce1ef1d
LinkInfoを非表示
YouheiNozaki Jul 11, 2023
7e9f06b
refactor: useBookLinkingHandlers() にリンク提供周りのロジックを集約
kou029w Jul 12, 2023
b34a36c
feat: Deep Linking でのブック提供
kou029w Jul 12, 2023
ec6f038
feat: Deep Linking デフォルトの活動名としてブック名を設定
kou029w Jul 12, 2023
0cf1bf8
feat: Deep Linking デフォルトの説明としてブック説明を設定
kou029w Jul 12, 2023
891d411
Merge pull request #978 from npocccties/gh-977
kou029w Jul 18, 2023
eb27217
fix: 最初にアクセスした教員または管理者をltiResourceLink.creatorとして紐付けられるように変更
kou029w Jul 18, 2023
d90f990
Merge pull request #983 from npocccties/fix-lti-resource-link
kou029w Jul 18, 2023
dab03b4
feat:UI: Deep Linking でのリンクの選択画面でのいくつかの操作の廃止
YouheiNozaki Jul 18, 2023
c67bbd5
Merge pull request #984 from npocccties/lti-deep-link-check-session
YouheiNozaki Jul 19, 2023
00b7bb2
fix:Deep Linking でのリンクの選択画面のレイアウトの改善
YouheiNozaki Jul 26, 2023
4c67e53
fix: template/DeepLinkBooks
YouheiNozaki Jul 28, 2023
a890586
add storybook
YouheiNozaki Jul 28, 2023
b7bdc05
fix
YouheiNozaki Jul 28, 2023
a883fb6
Tool URL (target_link_uri) が設定されている場合、リンクの変更を禁止
kou029w Jul 31, 2023
92c692f
fix PreviewClick event
YouheiNozaki Jul 31, 2023
4e60874
Merge pull request #989 from npocccties/lti-deep-link-layout
YouheiNozaki Aug 1, 2023
516675c
Merge pull request #992 from npocccties/gh-969
kou029w Aug 2, 2023
3bb7e67
fixed lint error
kou029w Aug 2, 2023
d81bdf5
fix:DeepLink設定の場合NEXT_PUBLIC_NO_EMBEDを無視する
YouheiNozaki Sep 10, 2023
1d144f8
非表示だったリンク切り替えを表示し説明をtitle属性に追加
kou029w Sep 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion components/atoms/AuthorFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ type Props = {
sx?: SxProps;
disabled?: boolean;
onFilterChange?: (value: AuthorFilterType) => void;
row?: boolean | undefined;
};

function AuthorFilter({
value = options[0].value,
sx,
disabled = false,
onFilterChange,
row,
}: Props) {
const handleChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
Expand All @@ -38,7 +40,7 @@ function AuthorFilter({
return (
<FormControl component="fieldset" sx={sx}>
<FormLabel component="legend">作成者</FormLabel>
<RadioGroup value={value} onChange={handleChange}>
<RadioGroup value={value} onChange={handleChange} row={row}>
{options.map(({ value, label }) => (
<FormControlLabel
key={value}
Expand Down
4 changes: 3 additions & 1 deletion components/atoms/SharedFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ type Props = {
sx?: SxProps;
disabled?: boolean;
onFilterChange?: (value: SharedFilterType) => void;
row?: boolean | undefined;
};

function SharedFilter({
value = options[2].value,
sx,
disabled = false,
onFilterChange,
row,
}: Props) {
const handleChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
Expand All @@ -38,7 +40,7 @@ function SharedFilter({
return (
<FormControl component="fieldset" sx={sx}>
<FormLabel component="legend">共有</FormLabel>
<RadioGroup value={value} onChange={handleChange}>
<RadioGroup value={value} onChange={handleChange} row={row}>
{options.map(({ value, label }) => (
<FormControlLabel
key={value}
Expand Down
120 changes: 63 additions & 57 deletions components/organisms/AppBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const useStyles = makeStyles((theme) => ({
inner: {
display: "flex",
alignItems: "center",
justifyContent: "space-between",
maxWidth: theme.breakpoints.values.lg,
width: "100%",
margin: "0 auto",
Expand Down Expand Up @@ -88,6 +89,7 @@ function AppBar(props: Props, ref: Ref<HTMLDivElement>) {
onDashboardClick,
...others
} = props;
const isDeepLink = !!session.ltiDlSettings?.deep_link_return_url;
const appBarClasses = useAppBarStyles();
const classes = useStyles();
const [open, setOpen] = useState(false);
Expand Down Expand Up @@ -137,71 +139,75 @@ function AppBar(props: Props, ref: Ref<HTMLDivElement>) {
alt="CHiBi-CHiLO"
className={clsx(classes.margin, classes.logo)}
/>
<div className={classes.nav}>
<AppBarNavButton
color="inherit"
icon={<MenuBookOutlinedIcon />}
label="ブック"
onClick={onBooksClick}
disabled={!onBooksClick}
/>
<AppBarNavButton
color="inherit"
icon={<LibraryBooksOutlinedIcon />}
label="トピック"
onClick={onTopicsClick}
disabled={!onTopicsClick}
/>
<AppBarNavButton
color="inherit"
icon={<LinkIcon />}
label="リンク"
onClick={onCoursesClick}
disabled={!onCoursesClick}
/>
<AppBarNavButton
color="inherit"
icon={<CellTowerIcon />}
label="配信中のブック"
onClick={onBookClick}
disabled={
!onBookClick ||
!Number.isFinite(session?.ltiResourceLink?.bookId)
}
/>
{session?.systemSettings?.zoomImportEnabled && ( // TODO: zoomインポート以外の設定値が実装されたら常時表示する
{!isDeepLink && (
<div className={classes.nav}>
<AppBarNavButton
color="inherit"
icon={<SettingsIcon />}
label="設定"
onClick={handleOpenUserSettings}
icon={<MenuBookOutlinedIcon />}
label="ブック"
onClick={onBooksClick}
disabled={!onBooksClick}
/>
)}
{onDashboardClick && (
<AppBarNavButton
color="inherit"
icon={<AssessmentOutlinedIcon />}
label="学習分析"
onClick={onDashboardClick}
icon={<LibraryBooksOutlinedIcon />}
label="トピック"
onClick={onTopicsClick}
disabled={!onTopicsClick}
/>
)}
</div>
<div className={clsx(classes.user, classes.margin)}>
<p>{session.user.name}</p>
<p className={classes.roles}>{role(session)}</p>
</div>
{session && (
<>
<Button variant="text" color="primary" onClick={handleClick}>
LTI情報
</Button>
<LtiItemDialog
open={open}
onClose={handleClose}
session={session}
<AppBarNavButton
color="inherit"
icon={<LinkIcon />}
label="リンク"
onClick={onCoursesClick}
disabled={!onCoursesClick}
/>
</>
<AppBarNavButton
color="inherit"
icon={<CellTowerIcon />}
label="配信中のブック"
onClick={onBookClick}
disabled={
!onBookClick ||
!Number.isFinite(session?.ltiResourceLink?.bookId)
}
/>
{session?.systemSettings?.zoomImportEnabled && ( // TODO: zoomインポート以外の設定値が実装されたら常時表示する
<AppBarNavButton
color="inherit"
icon={<SettingsIcon />}
label="設定"
onClick={handleOpenUserSettings}
/>
)}
{onDashboardClick && (
<AppBarNavButton
color="inherit"
icon={<AssessmentOutlinedIcon />}
label="学習分析"
onClick={onDashboardClick}
/>
)}
</div>
)}
<div>
<div className={clsx(classes.user, classes.margin)}>
<p>{session.user.name}</p>
<p className={classes.roles}>{role(session)}</p>
</div>
{session && (
<>
<Button variant="text" color="primary" onClick={handleClick}>
LTI情報
</Button>
<LtiItemDialog
open={open}
onClose={handleClose}
session={session}
/>
</>
)}
</div>
</div>
</Toolbar>
<Snackbar
Expand Down
36 changes: 24 additions & 12 deletions components/organisms/ContentPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ type Props = Parameters<typeof Checkbox>[0] & {
onKeywordClick(keyword: Pick<KeywordSchema, "name">): void;
onRelatedBookClick?(id: RelatedBook): void;
linked?: boolean;
isDeepLink?: boolean;
};

export default function ContentPreview({
Expand All @@ -135,6 +136,7 @@ export default function ContentPreview({
onKeywordClick,
onRelatedBookClick,
linked = content.type === "book" ? false : undefined,
isDeepLink,
checked,
...checkboxProps
}: Props) {
Expand Down Expand Up @@ -177,7 +179,7 @@ export default function ContentPreview({
/>
))}
{content.shared && <SharedIndicator className="shared" />}
{onContentEditClick && (
{!isDeepLink && onContentEditClick && (
<EditButton
className="edit-button"
variant={content.type}
Expand All @@ -198,17 +200,27 @@ export default function ContentPreview({
/>
</CardActionArea>
<Box position="relative">
{linked !== undefined && onContentLinkClick && (
<LinkSwitch
sx={{
position: "absolute",
bottom: 0,
right: 0,
transform: "translateY(50%)",
}}
checked={linked}
onChange={handleContentLinkClick}
/>
{content.type === "book" && linked !== undefined && (
<label
title={
onContentLinkClick
? "リンクを切り替える"
: "ツールURLが指定されているため、リンクの切り替えはできません"
}
>
<LinkSwitch
sx={{
position: "absolute",
bottom: 0,
right: 0,
transform: "translateY(50%)",
filter: onContentLinkClick ? "none" : "grayscale(1)",
}}
disabled={!onContentLinkClick}
checked={linked}
onChange={handleContentLinkClick}
/>
</label>
)}
{content.license && (
<License
Expand Down
4 changes: 3 additions & 1 deletion components/templates/BookEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type { TopicSchema } from "$server/models/topic";
import type { AuthorSchema } from "$server/models/author";
import type { IsContentEditable } from "$server/models/content";
import { useConfirm } from "material-ui-confirm";
import { useSessionAtom } from "$store/session";
import useDialogProps from "$utils/useDialogProps";

const useStyles = makeStyles((theme) => ({
Expand Down Expand Up @@ -73,6 +74,7 @@ export default function BookEdit({
isContentEditable,
linked = false,
}: Props) {
const { session } = useSessionAtom();
const classes = useStyles();
const confirm = useConfirm();
const {
Expand Down Expand Up @@ -121,7 +123,7 @@ export default function BookEdit({
<BookForm
className={classes.content}
book={book}
linked={linked}
linked={Boolean(session?.ltiTargetLinkUri || linked)}
variant="update"
onSubmit={onSubmit}
onAuthorsUpdate={onAuthorsUpdate}
Expand Down
3 changes: 2 additions & 1 deletion components/templates/BookNew.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default function BookNew({
onAuthorsUpdate,
onAuthorSubmit,
}: Props) {
const { isContentEditable } = useSessionAtom();
const { session, isContentEditable } = useSessionAtom();
const forkFrom =
book && !isContentEditable(book) && book.authors.length > 0 && book.authors;
const defaultBook = book && {
Expand Down Expand Up @@ -87,6 +87,7 @@ export default function BookNew({
<BookForm
book={defaultBook}
topics={topics}
linked={Boolean(session?.ltiTargetLinkUri)}
variant="create"
onSubmit={onSubmit}
onAuthorsUpdate={onAuthorsUpdate}
Expand Down
2 changes: 1 addition & 1 deletion components/templates/Books.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export type Props = {
loading?: boolean;
onContentPreviewClick(content: ContentSchema): void;
onContentEditClick(content: ContentSchema): void;
onContentLinkClick(content: ContentSchema, checked: boolean): void;
onContentLinkClick?(content: ContentSchema, checked: boolean): void;
onLinkedBookClick?(book: BookSchema): void;
onBookNewClick(): void;
onBooksImportClick(): void;
Expand Down
28 changes: 28 additions & 0 deletions components/templates/DeepLInkBooks.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { Story } from "@storybook/react";
import DeepLinkBooks from "./DeepLinkBooks";
import { book, books } from "samples";

export default {
title: "templates/DeepLinkBooks",
parameters: { layout: "fullscreen" },
component: DeepLinkBooks,
};

const linkedBook = { ...book, editable: true };

const Template: Story<Parameters<typeof DeepLinkBooks>[0]> = (args) => (
<DeepLinkBooks {...args} />
);

export const Default = Template.bind({});
Default.args = {
linkedBook,
totalCount: 123,
contents: books.map((book) => ({ type: "book", ...book })),
};

export const Empty = Template.bind({});
Empty.args = {
totalCount: 0,
contents: [],
};
Loading