Compare commits

...
Author SHA1 Message Date
TJWater CI f5bcf28f7e fix(map): preserve hook order while data loads
Generic Container CI/CD / test-build-publish (push) Failing after 1m50s
Frontend CI/CD v2 / build-test-publish-and-deploy (push) Failing after 1m50s
2026-08-11 10:32:18 +08:00
TJWater CI ab45c8da8e ci: add frontend v2 deployment workflow
Generic Container CI/CD / test-build-publish (push) Failing after 1m13s
Frontend CI/CD v2 / build-test-publish-and-deploy (push) Failing after 1m14s
2026-08-11 09:51:13 +08:00
6 changed files with 88 additions and 28 deletions
+21
View File
@@ -0,0 +1,21 @@
name: Frontend CI/CD v2
on:
push:
tags:
- "v*"
workflow_dispatch: {}
jobs:
build-test-publish-and-deploy:
uses: OrgTJWater/ci-templates/.gitea/workflows/container-cd.yml@main
with:
image_name: gitea.waternetwork.cn/orgtjwater/tjwaterfrontend_refine
dockerfile: Dockerfile
build_context: .
deploy_service: frontend
deploy_host: 192.168.1.114
secrets:
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
DEV_DEPLOY_SSH_KEY: ${{ secrets.DEV_DEPLOY_SSH_KEY }}
+9 -2
View File
@@ -16,9 +16,16 @@ interface LayerItem {
} }
const LayerControl: React.FC = () => { const LayerControl: React.FC = () => {
const map = useMap();
const data = useData(); const data = useData();
if (!data) return; if (!data) return null;
return <LayerControlContent data={data} />;
};
const LayerControlContent: React.FC<{
data: NonNullable<ReturnType<typeof useData>>;
}> = ({ data }) => {
const map = useMap();
const { const {
deckLayer, deckLayer,
isContourLayerAvailable, isContourLayerAvailable,
+9 -5
View File
@@ -174,15 +174,19 @@ const hexToRgba = (hex: string) => {
: "rgba(0, 0, 0, 1)"; : "rgba(0, 0, 0, 1)";
}; };
const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = (props) => {
layerStyleStates,
setLayerStyleStates,
}) => {
const map = useMap();
const data = useData(); const data = useData();
if (!data) { if (!data) {
return <div>Loading...</div>; // 或其他占位符 return <div>Loading...</div>; // 或其他占位符
} }
return <StyleEditorPanelContent {...props} data={data} />;
};
const StyleEditorPanelContent: React.FC<
StyleEditorPanelProps & { data: NonNullable<ReturnType<typeof useData>> }
> = ({ layerStyleStates, setLayerStyleStates, data }) => {
const map = useMap();
const { const {
currentJunctionCalData, currentJunctionCalData,
currentPipeCalData, currentPipeCalData,
+26 -14
View File
@@ -38,17 +38,37 @@ interface TimelineProps {
schemeType?: string; schemeType?: string;
} }
const Timeline: React.FC<TimelineProps> = ({ const Timeline: React.FC<TimelineProps> = (props) => {
const data = useData();
if (
!data ||
data.setCurrentTime === undefined ||
data.currentTime === undefined ||
data.selectedDate === undefined ||
data.setSelectedDate === undefined
) {
return <div>Loading...</div>;
}
return <TimelineContent {...props} data={data} />;
};
const TimelineContent: React.FC<
TimelineProps & { data: NonNullable<ReturnType<typeof useData>> }
> = ({
schemeDate, schemeDate,
timeRange, timeRange,
disableDateSelection = false, disableDateSelection = false,
schemeName = "", schemeName = "",
schemeType = "burst_Analysis", schemeType = "burst_Analysis",
data,
}) => { }) => {
const data = useData(); const readyData = data as typeof data & {
if (!data) { currentTime: NonNullable<typeof data.currentTime>;
return <div>Loading...</div>; // 或其他占位符 setCurrentTime: NonNullable<typeof data.setCurrentTime>;
} selectedDate: NonNullable<typeof data.selectedDate>;
setSelectedDate: NonNullable<typeof data.setSelectedDate>;
};
const { const {
currentTime, currentTime,
setCurrentTime, setCurrentTime,
@@ -58,15 +78,7 @@ const Timeline: React.FC<TimelineProps> = ({
setCurrentPipeCalData, setCurrentPipeCalData,
junctionText, junctionText,
pipeText, pipeText,
} = data; } = readyData;
if (
setCurrentTime === undefined ||
currentTime === undefined ||
selectedDate === undefined ||
setSelectedDate === undefined
) {
return <div>Loading...</div>; // 或其他占位符
}
const { open } = useNotification(); const { open } = useNotification();
const [isPlaying, setIsPlaying] = useState<boolean>(false); const [isPlaying, setIsPlaying] = useState<boolean>(false);
+11 -3
View File
@@ -27,15 +27,23 @@ interface ToolbarProps {
queryType?: string; // 可选的查询类型参数 queryType?: string; // 可选的查询类型参数
HistoryPanel?: React.FC<any>; // 可选的自定义历史数据面板 HistoryPanel?: React.FC<any>; // 可选的自定义历史数据面板
} }
const Toolbar: React.FC<ToolbarProps> = ({ const Toolbar: React.FC<ToolbarProps> = (props) => {
const data = useData();
if (!data) return null;
return <ToolbarContent {...props} data={data} />;
};
const ToolbarContent: React.FC<
ToolbarProps & { data: NonNullable<ReturnType<typeof useData>> }
> = ({
hiddenButtons, hiddenButtons,
queryType, queryType,
HistoryPanel, HistoryPanel,
data,
}) => { }) => {
const map = useMap(); const map = useMap();
const data = useData();
const { open } = useNotification(); const { open } = useNotification();
if (!data) return null;
const { currentTime, selectedDate, schemeName } = data; const { currentTime, selectedDate, schemeName } = data;
const [activeTools, setActiveTools] = useState<string[]>([]); const [activeTools, setActiveTools] = useState<string[]>([]);
const [highlightFeatures, setHighlightFeatures] = useState<Feature[]>([]); const [highlightFeatures, setHighlightFeatures] = useState<Feature[]>([]);
@@ -59,13 +59,21 @@ interface TimelineProps {
schemeName?: string; schemeName?: string;
} }
const Timeline: React.FC<TimelineProps> = ({ const Timeline: React.FC<TimelineProps> = (props) => {
disableDateSelection = false,
}) => {
const data = useData(); const data = useData();
if (!data) { if (!data) {
return <div>Loading...</div>; // 或其他占位符 return <div>Loading...</div>;
} }
return <TimelineContent {...props} data={data} />;
};
const TimelineContent: React.FC<
TimelineProps & { data: NonNullable<ReturnType<typeof useData>> }
> = ({
disableDateSelection = false,
data,
}) => {
const { open } = useNotification(); const { open } = useNotification();
const { const {
predictionResults, predictionResults,