Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 13 additions & 1 deletion packages/admin/src/components/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,26 @@ body {
font: inherit;
}

.admin-actions button {
/* 「← 一覧に戻る」など詳細画面の戻るボタンもアクションボタンと同一ルールに
統合して見た目を完全一致させる(font を指定すると UA 既定より大きくなり
一回り大きく見えたため、両者で font 未指定=UA 既定に揃える)。 */
.admin-actions button,
.admin-back-button {
padding: 0.4rem 0.9rem;
border: 1px solid hsl(220, 15%, 75%);
border-radius: 0.4rem;
background: white;
cursor: pointer;
}

.admin-back-button {
margin-bottom: 1rem;
}

.admin-back-button:hover {
background: hsl(220, 15%, 96%);
}

.admin-confirm {
display: inline-flex;
align-items: center;
Expand Down
1 change: 1 addition & 0 deletions packages/admin/src/components/bug-reports-view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ const BugReportDetail = ({reportId, stage, onBack, onChanged}) => {
return (
<div data-testid="bug-admin-detail">
<button
className="admin-back-button"
data-testid="bug-admin-back"
type="button"
onClick={onBack}
Expand Down
4 changes: 4 additions & 0 deletions packages/admin/src/components/classrooms-view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ const ClassroomDetail = ({classroomId, onBack, onChanged}) => {
return (
<div data-testid="classroom-admin-detail">
<button
className="admin-back-button"
data-testid="classroom-admin-back"
type="button"
onClick={onBack}
Expand Down Expand Up @@ -360,6 +361,7 @@ const RestorePanel = ({classroomId, onBack}) => {
</p>
)}
<button
className="admin-back-button"
data-testid="restore-admin-done-back"
type="button"
onClick={onBack}
Expand All @@ -373,6 +375,7 @@ const RestorePanel = ({classroomId, onBack}) => {
<div data-testid="restore-admin-alive">
<p>{'このクラスはまだ存在しています。アーカイブからの復旧は先生自身のクラス管理画面から行えます。'}</p>
<button
className="admin-back-button"
data-testid="restore-admin-back"
type="button"
onClick={onBack}
Expand All @@ -384,6 +387,7 @@ const RestorePanel = ({classroomId, onBack}) => {
return (
<div data-testid="restore-admin-plan">
<button
className="admin-back-button"
data-testid="restore-admin-back"
type="button"
onClick={onBack}
Expand Down
21 changes: 17 additions & 4 deletions packages/admin/src/components/shared-assignments-view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ import {
setSharedStatus
} from '../lib/admin-api.js';

// 限定公開は属性・著者名・教科などを省略できる(#1109)。データ欠損では
// なく「先生が未入力」なので、運営が見て意味がわかるよう undefined を
// そのまま出さず「未指定」と明示する。
const UNSPECIFIED = '未指定';
const orUnspecified = value => {
if (typeof value === 'undefined' || value === null || value === '') return UNSPECIFIED;
return value;
};

const StatusBadge = ({status}) => (
<span className={`admin-badge ${status === 'published' ? 'admin-badge-ok' : 'admin-badge-muted'}`}>
{status === 'published' ? '公開中' : '非公開'}
Expand Down Expand Up @@ -117,6 +126,7 @@ const SharedDetail = ({sharedId, onBack, onChanged}) => {
return (
<div data-testid="shared-admin-detail">
<button
className="admin-back-button"
data-testid="shared-admin-back"
type="button"
onClick={onBack}
Expand All @@ -134,11 +144,13 @@ const SharedDetail = ({sharedId, onBack, onChanged}) => {
className="admin-meta"
data-testid="shared-admin-credit"
>
{`© ${detail.authorName}${detail.authorAffiliation ? `(${detail.authorAffiliation})` : ''} / CC BY 4.0`}
{` ・ 取り込み ${detail.reuseCount} 回`}
{`© ${orUnspecified(detail.authorName)}`}
{detail.authorAffiliation ? `(${detail.authorAffiliation})` : ''}
{` / CC BY 4.0 ・ 取り込み ${detail.reuseCount} 回`}
</p>
<p className="admin-meta">
{`${detail.schoolLevel} / ${detail.subject} / タグ: ${(detail.tags || []).join(', ') || '-'}`}
{`${orUnspecified(detail.schoolLevel)} / ${orUnspecified(detail.subject)}`}
{` / タグ: ${(detail.tags || []).join(', ') || UNSPECIFIED}`}
</p>
{detail.supplementUrl ? (
<p
Expand Down Expand Up @@ -388,7 +400,8 @@ const SharedAssignmentsView = () => {
<VisibilityBadge visibility={item.visibility} />
<RecommendedBadge recommended={item.recommended} />
<span className="admin-meta">
{`${item.authorName} ・ 取り込み ${item.reuseCount} 回 ・ ${item.createdAt}`}
{`${orUnspecified(item.authorName)} ・ 取り込み ${item.reuseCount} 回`}
{` ・ ${item.createdAt}`}
</span>
</button>
</li>
Expand Down
23 changes: 23 additions & 0 deletions packages/admin/test/unit/shared-assignments-view.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,27 @@ describe('SharedAssignmentsView (issue #1083)', () => {
expect(mockSetStatus).not.toHaveBeenCalled();
expect(screen.queryByTestId('shared-admin-confirm')).not.toBeInTheDocument();
});

test('限定公開で未入力の属性は undefined でなく「未指定」と表示する (レビュー指摘)', async () => {
// 限定公開は authorName / schoolLevel / subject 等を省略できる
// (キーそのものが無い=undefined になる)。
mockFetchDetail.mockResolvedValue({
sharedId: 's1',
title: 'smoke限定公開',
status: 'published',
visibility: 'limited',
tags: [],
reuseCount: 0,
pages: [{text: 'ページ1', imageUrl: null}],
starterUrl: null
});
render(<SharedAssignmentsView />);
await waitFor(() => screen.getByTestId('shared-admin-queue-item-s1'));
fireEvent.click(screen.getByTestId('shared-admin-queue-item-s1'));
await waitFor(() => screen.getByTestId('shared-admin-detail'));

const detailEl = screen.getByTestId('shared-admin-detail');
expect(detailEl.textContent).not.toContain('undefined');
expect(screen.getByTestId('shared-admin-credit').textContent).toContain('未指定');
});
});
Loading