pandorga 1.4.4 → 1.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/studio/index.html CHANGED
@@ -18,7 +18,7 @@
18
18
  rel="stylesheet"
19
19
  href="https://cdn.jsdelivr.net/gh/lipis/flag-icons@7.2.3/css/flag-icons.min.css"
20
20
  />
21
- <script type="module" crossorigin src="/studio/assets/index-Cf9OPjQU.js"></script>
21
+ <script type="module" crossorigin src="/studio/assets/index-OAmrbW7i.js"></script>
22
22
  <link rel="stylesheet" crossorigin href="/studio/assets/index-Cd1mlY_H.css">
23
23
  </head>
24
24
  <body>
@@ -73,10 +73,12 @@ export const studioApi = {
73
73
  method: "POST",
74
74
  body: JSON.stringify(payload),
75
75
  }),
76
- /** Content-pipeline run for a commit SHA (production). */
77
- pipelineStatus: (sha, workflow = null) => {
78
- const params = new URLSearchParams({ sha: String(sha || "") });
76
+ /** Content-pipeline run for a commit SHA, or latest on the branch when omitted. */
77
+ pipelineStatus: (sha = null, workflow = null) => {
78
+ const params = new URLSearchParams();
79
+ if (sha) params.set("sha", String(sha));
79
80
  if (workflow) params.set("workflow", String(workflow));
80
- return api(`pipeline-status?${params.toString()}`);
81
+ const q = params.toString();
82
+ return api(q ? `pipeline-status?${q}` : "pipeline-status");
81
83
  },
82
84
  };
@@ -892,7 +892,9 @@ function pipelineChipMeta(pipelineState) {
892
892
  icon: "cloud_off",
893
893
  className: "pipeline-chip pipeline-idle",
894
894
  spinning: false,
895
- title: "STUDIO_CONTENT_WORKFLOW is not set on the Studio API",
895
+ title:
896
+ state.pipeline.message ||
897
+ "Set pandorga.content.workflow in _config.yml (e.g. content-pipeline.yml)",
896
898
  };
897
899
  default:
898
900
  return {
@@ -940,6 +942,39 @@ function renderPipelineChip() {
940
942
  );
941
943
  }
942
944
 
945
+ function applyPipelinePayload(data) {
946
+ state.pipeline.runUrl = data.run?.html_url || state.pipeline.runUrl || "";
947
+ if (data.sha) state.pipeline.sha = String(data.sha).toLowerCase();
948
+ state.pipeline.message = "";
949
+ if (data.state === "unconfigured") {
950
+ state.pipeline.state = "unconfigured";
951
+ state.pipeline.message =
952
+ "Set pandorga.content.workflow in _config.yml (e.g. content-pipeline.yml)";
953
+ return;
954
+ }
955
+ state.pipeline.state = data.state || "idle";
956
+ if (data.state === "error") {
957
+ state.pipeline.message = "Content pipeline failed for this commit.";
958
+ }
959
+ }
960
+
961
+ /** Hydrate the always-visible chip from the latest workflow run (or a SHA). */
962
+ async function refreshPipelineStatus(sha = null) {
963
+ if (isLocalDevHost()) return;
964
+ try {
965
+ const data = await studioApi.pipelineStatus(sha || null);
966
+ applyPipelinePayload(data);
967
+ renderShell();
968
+ } catch (err) {
969
+ const code = err?.code || "";
970
+ if (code === "actions_forbidden" || code === "github_unconfigured") {
971
+ state.pipeline.state = "error";
972
+ state.pipeline.message = String(err.message || err);
973
+ renderShell();
974
+ }
975
+ }
976
+ }
977
+
943
978
  /**
944
979
  * After a production Save, poll Actions for the content-pipeline run on this SHA.
945
980
  */
@@ -976,32 +1011,17 @@ async function pollPipelineStatus(gen, sha) {
976
1011
  const data = await studioApi.pipelineStatus(sha);
977
1012
  if (gen !== state.pipeline.pollGen) return;
978
1013
  softFails = 0;
979
- state.pipeline.runUrl = data.run?.html_url || state.pipeline.runUrl || "";
980
- state.pipeline.message = "";
1014
+ applyPipelinePayload(data);
981
1015
 
982
- if (data.state === "unconfigured") {
983
- state.pipeline.state = "unconfigured";
1016
+ if (data.state === "unconfigured" || data.state === "ok" || data.state === "error") {
984
1017
  renderShell();
985
1018
  return;
986
1019
  }
987
- if (data.state === "ok" || data.state === "error") {
988
- state.pipeline.state = data.state;
989
- if (data.state === "error") {
990
- state.pipeline.message = "Content pipeline failed for this commit.";
991
- }
1020
+ if (data.state === "awaiting_run" && elapsed > STALL_MS) {
1021
+ state.pipeline.state = "stalled";
992
1022
  renderShell();
993
1023
  return;
994
1024
  }
995
- if (data.state === "running") {
996
- state.pipeline.state = "running";
997
- } else if (data.state === "awaiting_run") {
998
- if (elapsed > STALL_MS) {
999
- state.pipeline.state = "stalled";
1000
- renderShell();
1001
- return;
1002
- }
1003
- state.pipeline.state = "awaiting_run";
1004
- }
1005
1025
  renderShell();
1006
1026
  } catch (err) {
1007
1027
  if (gen !== state.pipeline.pollGen) return;
@@ -1114,8 +1134,35 @@ function renderStudioToolbar({ brand = null, menuToggle = null } = {}) {
1114
1134
  : null,
1115
1135
  ]);
1116
1136
 
1117
- const actions = [
1118
- renderThemeMenu(),
1137
+ const actions = [renderThemeMenu()];
1138
+
1139
+ // Theme → pipeline/Export → Revert → Save. Pipeline chip is always present.
1140
+ if (isLocalDevHost()) {
1141
+ const exportBusy = state.reexporting || state.pipeline.state === "syncing";
1142
+ actions.push(
1143
+ toolbarActionButton({
1144
+ className:
1145
+ "btn btn-tool btn-reexport" +
1146
+ (exportBusy ? " pipeline-running" : "") +
1147
+ (state.pipeline.state === "ok" && !exportBusy ? " pipeline-ok" : "") +
1148
+ (state.pipeline.state === "error" && !exportBusy ? " pipeline-error" : ""),
1149
+ title: exportBusy
1150
+ ? "Exporting content JSON locally"
1151
+ : "Export content JSON locally and reload",
1152
+ ariaLabel: exportBusy ? "Exporting locally" : "Export locally",
1153
+ action: "reexport",
1154
+ disabled: exportBusy,
1155
+ onClick: () => reexportLocalContent(),
1156
+ icon: exportBusy ? "progress_activity" : "sync",
1157
+ label: exportBusy ? "Exporting…" : "Export",
1158
+ spinning: exportBusy,
1159
+ })
1160
+ );
1161
+ } else {
1162
+ actions.push(renderPipelineChip());
1163
+ }
1164
+
1165
+ actions.push(
1119
1166
  toolbarActionButton({
1120
1167
  className: "btn btn-tool",
1121
1168
  title: "Revert all edits to the last loaded or saved version",
@@ -1140,45 +1187,8 @@ function renderStudioToolbar({ brand = null, menuToggle = null } = {}) {
1140
1187
  icon: saveIcon,
1141
1188
  label: saveLabel,
1142
1189
  spinning: state.saving,
1143
- }),
1144
- ];
1145
- if (state.file && collectionAllowsDelete()) {
1146
- actions.push(
1147
- toolbarActionButton({
1148
- className: "btn btn-tool btn-danger",
1149
- title: "Delete this entry from the repository",
1150
- ariaLabel: "Delete entry",
1151
- action: "delete",
1152
- onClick: () => deleteCurrentEntry(),
1153
- icon: "delete",
1154
- label: "Delete",
1155
- })
1156
- );
1157
- }
1158
- if (isLocalDevHost()) {
1159
- const exportBusy = state.reexporting || state.pipeline.state === "syncing";
1160
- actions.push(
1161
- toolbarActionButton({
1162
- className:
1163
- "btn btn-tool btn-reexport" +
1164
- (exportBusy ? " pipeline-running" : "") +
1165
- (state.pipeline.state === "ok" && !exportBusy ? " pipeline-ok" : "") +
1166
- (state.pipeline.state === "error" && !exportBusy ? " pipeline-error" : ""),
1167
- title: exportBusy
1168
- ? "Exporting content JSON locally"
1169
- : "Export content JSON locally and reload",
1170
- ariaLabel: exportBusy ? "Exporting locally" : "Export locally",
1171
- action: "reexport",
1172
- disabled: exportBusy,
1173
- onClick: () => reexportLocalContent(),
1174
- icon: exportBusy ? "progress_activity" : "sync",
1175
- label: exportBusy ? "Exporting…" : "Export",
1176
- spinning: exportBusy,
1177
- })
1178
- );
1179
- } else if (state.pipeline.state !== "idle") {
1180
- actions.push(renderPipelineChip());
1181
- }
1190
+ })
1191
+ );
1182
1192
 
1183
1193
  const kids = [
1184
1194
  brandCluster,
@@ -4257,6 +4267,7 @@ async function bootApp(clerk) {
4257
4267
  }
4258
4268
 
4259
4269
  renderShell();
4270
+ void refreshPipelineStatus();
4260
4271
 
4261
4272
  scheduleTreePrefetch();
4262
4273
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pandorga
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.4
4
+ version: 1.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Pandorga contributors
@@ -450,7 +450,7 @@ files:
450
450
  - studio-app/src/styles/studio.css
451
451
  - studio-app/vite.config.js
452
452
  - studio/assets/index-Cd1mlY_H.css
453
- - studio/assets/index-Cf9OPjQU.js
453
+ - studio/assets/index-OAmrbW7i.js
454
454
  - studio/index.html
455
455
  - studio/schema.yml
456
456
  - templates/articles/README.md