chore: update live chat and work server changes

This commit is contained in:
2026-04-26 16:37:06 +09:00
parent 63e5d263a7
commit 20a6333ed2
38 changed files with 2078 additions and 2281 deletions

View File

@@ -164,6 +164,7 @@ type PlanNoteResource = {
sourcePath: string;
publicUrl: string;
previewType: 'image' | 'document' | 'link';
isProbablyOpenable: boolean;
};
const PLAN_NOTE_RESOURCE_LINE_PATTERN =
@@ -242,6 +243,22 @@ function resolvePlanNoteResourcePreviewType(sourcePath: string): PlanNoteResourc
return 'link';
}
function isProbablyOpenablePlanNoteResource(sourcePath: string) {
const normalized = normalizePlanNoteResourceSourcePath(sourcePath).replace(/^\/+/, '');
if (!normalized || normalized.endsWith('/')) {
return false;
}
const baseName = getPlanNoteResourceBaseName(normalized).trim().toLowerCase();
if (!baseName || baseName === 'resource' || baseName === 'uploads' || baseName === '.codex_chat') {
return false;
}
return baseName.includes('.');
}
function extractPlanNoteResources(note: string) {
const normalizedNote = String(note ?? '');
const lineEntries = normalizedNote
@@ -283,6 +300,7 @@ function extractPlanNoteResources(note: string) {
sourcePath: item.sourcePath,
publicUrl: normalizePlanNoteResourceUrl(item.sourcePath),
previewType: resolvePlanNoteResourcePreviewType(item.sourcePath),
isProbablyOpenable: isProbablyOpenablePlanNoteResource(item.sourcePath),
}));
}
@@ -501,14 +519,36 @@ function ExpandableDetailText({
}
function PlanNoteResourcePanel({ resources }: { resources: PlanNoteResource[] }) {
const [hideInvalidResources, setHideInvalidResources] = useState(true);
const visibleResources = useMemo(
() => resources.filter((resource) => !hideInvalidResources || resource.isProbablyOpenable),
[hideInvalidResources, resources],
);
const hiddenResourceCount = resources.length - visibleResources.length;
return (
<div className="plan-board-page__note-resources">
<Flex justify="space-between" align="center" gap={8} wrap>
<Text strong> </Text>
<Text type="secondary">{resources.length}</Text>
<Space size={8} wrap>
<Text strong> </Text>
<Text type="secondary">{visibleResources.length}</Text>
{hiddenResourceCount > 0 ? (
<Text type="secondary" className="plan-board-page__note-resource-summary">
{hiddenResourceCount}
</Text>
) : null}
</Space>
<Checkbox
checked={hideInvalidResources}
onChange={(event) => {
setHideInvalidResources(event.target.checked);
}}
>
</Checkbox>
</Flex>
<div className="plan-board-page__note-resource-list">
{resources.map((resource) => (
{visibleResources.map((resource) => (
<div key={resource.id} className="plan-board-page__note-resource-card">
<Flex justify="space-between" align="start" gap={12} wrap>
<Space direction="vertical" size={2} style={{ minWidth: 0, flex: 1 }}>
@@ -549,6 +589,9 @@ function PlanNoteResourcePanel({ resources }: { resources: PlanNoteResource[] })
</div>
))}
</div>
{visibleResources.length === 0 ? (
<Text type="secondary"> .</Text>
) : null}
</div>
);
}

View File

@@ -619,7 +619,7 @@ function PlanScheduleDetail({
onCopyText: (text: string) => Promise<void>;
}) {
return (
<Space direction="vertical" size={14} style={{ width: '100%' }}>
<div className="plan-schedule-page__detail">
{selectedItem ? (
<Alert
showIcon
@@ -865,6 +865,6 @@ function PlanScheduleDetail({
/>
</div>
</div>
</Space>
</div>
);
}

View File

@@ -1,13 +1,18 @@
.plan-schedule-page {
display: flex;
flex: 1 1 auto;
flex-direction: column;
gap: 16px;
min-width: 0;
min-height: 0;
}
.plan-schedule-page__overview,
.plan-schedule-page__list-card,
.plan-schedule-page__editor-card {
display: flex;
flex-direction: column;
min-height: 0;
border: 0;
border-radius: 20px;
box-shadow: none;
@@ -15,9 +20,12 @@
.plan-schedule-page__split {
display: grid;
flex: 1 1 auto;
grid-template-columns: minmax(320px, 420px) minmax(0, 1fr);
gap: 16px;
min-width: 0;
min-height: 0;
align-items: stretch;
}
.plan-schedule-page__split--stacked {
@@ -27,7 +35,12 @@
.plan-schedule-page__list-card .ant-card-body,
.plan-schedule-page__editor-card .ant-card-body,
.plan-schedule-page__detail-card .ant-card-body {
display: flex;
flex: 1 1 auto;
flex-direction: column;
min-width: 0;
min-height: 0;
overflow: hidden;
}
.plan-schedule-page__detail-actions.ant-space {
@@ -55,8 +68,14 @@
.plan-schedule-page__list {
display: flex;
flex: 1 1 auto;
flex-direction: column;
gap: 10px;
min-height: 0;
overflow: auto;
overscroll-behavior: contain;
-webkit-overflow-scrolling: touch;
padding-right: 4px;
}
.plan-schedule-page__list-item {
@@ -92,9 +111,22 @@
.plan-schedule-page__form {
width: 100%;
display: grid;
flex: 0 0 auto;
gap: 14px;
}
.plan-schedule-page__detail {
display: flex;
flex: 1 1 auto;
flex-direction: column;
gap: 14px;
min-height: 0;
overflow: auto;
overscroll-behavior: contain;
-webkit-overflow-scrolling: touch;
padding-right: 4px;
}
.plan-schedule-page__form > div {
display: flex;
flex-direction: column;
@@ -146,6 +178,7 @@
.plan-schedule-page__notepad.ant-input {
padding: 20px 18px;
padding-bottom: 26px;
line-height: 1.85;
border-radius: 22px;
border: 1px solid rgba(22, 93, 255, 0.1);
@@ -160,9 +193,10 @@
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.82),
0 18px 40px rgba(23, 61, 130, 0.06);
box-sizing: border-box;
overflow-y: auto;
scrollbar-gutter: stable;
resize: vertical;
resize: none;
}
.plan-schedule-page__notepad.ant-input:focus,
@@ -175,6 +209,8 @@
.plan-schedule-page__notepad-frame {
width: 100%;
min-height: 0;
overflow: hidden;
}
.plan-schedule-page__notepad-frame .ant-input-textarea,