@qaecy/cue-ui 0.0.1 → 0.0.3

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.
Files changed (44) hide show
  1. package/README.md +107 -22
  2. package/card/3rdpartylicenses.txt +443 -0
  3. package/card/index.html +40 -0
  4. package/card/main.js +1 -0
  5. package/card/polyfills.js +1 -0
  6. package/card/poppins-latin-400-normal.woff +0 -0
  7. package/card/poppins-latin-400-normal.woff2 +0 -0
  8. package/card/poppins-latin-ext-400-normal.woff +0 -0
  9. package/card/poppins-latin-ext-400-normal.woff2 +0 -0
  10. package/card/runtime.js +1 -0
  11. package/card/styles.css +1 -0
  12. package/document-list/3rdpartylicenses.txt +723 -0
  13. package/document-list/index.html +549 -0
  14. package/document-list/main.js +1 -0
  15. package/document-list/polyfills.js +1 -0
  16. package/document-list/poppins-latin-400-normal.woff +0 -0
  17. package/document-list/poppins-latin-400-normal.woff2 +0 -0
  18. package/document-list/poppins-latin-ext-400-normal.woff +0 -0
  19. package/document-list/poppins-latin-ext-400-normal.woff2 +0 -0
  20. package/document-list/runtime.js +1 -0
  21. package/document-list/styles.css +1 -0
  22. package/document-viewer/236.js +1 -0
  23. package/document-viewer/336.js +1 -0
  24. package/document-viewer/3rdpartylicenses.txt +50 -68
  25. package/document-viewer/560.js +1 -1
  26. package/document-viewer/741.js +1 -0
  27. package/document-viewer/{160.js → 781.js} +1 -1
  28. package/document-viewer/83.js +1 -1
  29. package/document-viewer/885.js +1 -0
  30. package/document-viewer/common.js +1 -1
  31. package/document-viewer/index.html +595 -29
  32. package/document-viewer/main.js +1 -1
  33. package/logo/index.html +86 -1
  34. package/logo/main.js +1 -1
  35. package/package.json +10 -2
  36. package/project-documents/main.js +1 -1
  37. package/document-viewer/130.js +0 -1
  38. package/document-viewer/241.js +0 -1
  39. package/document-viewer/266.js +0 -1
  40. package/document-viewer/315.js +0 -1
  41. package/document-viewer/734.js +0 -1
  42. package/document-viewer/829.js +0 -1
  43. package/document-viewer/843.js +0 -1
  44. package/document-viewer/888.js +0 -1
@@ -6,49 +6,615 @@
6
6
  <base href="./">
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1">
8
8
  <link rel="icon" type="image/x-icon" href="favicon.ico">
9
+
10
+ <script type="importmap">
11
+ {
12
+ "imports": {
13
+ "@qaecy/cue-sdk": "https://esm.sh/@qaecy/cue-sdk@0.0.17?external=firebase",
14
+ "firebase/app": "https://esm.sh/firebase@12/app",
15
+ "firebase/auth": "https://esm.sh/firebase@12/auth",
16
+ "firebase/firestore": "https://esm.sh/firebase@12/firestore",
17
+ "firebase/storage": "https://esm.sh/firebase@12/storage",
18
+ "firebase/functions": "https://esm.sh/firebase@12/functions"
19
+ }
20
+ }
21
+ </script>
22
+
23
+ <!-- Angular runtime scripts - MUST load before custom element usage -->
24
+ <script src="runtime.js" type="module"></script>
25
+ <script src="polyfills.js" type="module"></script>
26
+ <script src="main.js" type="module"></script>
27
+
9
28
  <style>
29
+ *,
30
+ *::before,
31
+ *::after {
32
+ box-sizing: border-box;
33
+ }
34
+
10
35
  body {
11
36
  margin: 0;
12
- padding: 0;
37
+ background: #141414;
38
+ color: #e0e0e0;
39
+ font-family: Poppins, system-ui, sans-serif;
40
+ font-size: 14px;
41
+ height: 100dvh;
42
+ display: flex;
43
+ flex-direction: column;
44
+ }
45
+
46
+ /* ── Login overlay ─────────────────────────────── */
47
+ #login-overlay {
48
+ position: fixed;
49
+ inset: 0;
50
+ background: #141414;
51
+ display: flex;
52
+ align-items: center;
53
+ justify-content: center;
54
+ z-index: 100;
55
+ }
56
+ #login-overlay.hidden {
57
+ display: none;
58
+ }
59
+
60
+ .login-card {
61
+ background: #1e1e1e;
62
+ border: 1px solid #333;
63
+ border-radius: 12px;
64
+ padding: 40px 48px;
65
+ text-align: center;
66
+ max-width: 360px;
67
+ width: 100%;
68
+ }
69
+ .login-card h1 {
70
+ margin: 0 0 8px;
71
+ font-size: 22px;
72
+ font-weight: 600;
73
+ }
74
+ .login-card p {
75
+ margin: 0 0 28px;
76
+ color: #888;
77
+ font-size: 13px;
78
+ }
79
+
80
+ .btn {
81
+ display: inline-flex;
82
+ align-items: center;
83
+ gap: 10px;
84
+ padding: 10px 20px;
85
+ border: none;
86
+ border-radius: 8px;
87
+ font-family: inherit;
88
+ font-size: 14px;
89
+ font-weight: 500;
90
+ cursor: pointer;
91
+ transition: opacity 0.15s;
92
+ }
93
+ .btn:hover {
94
+ opacity: 0.85;
95
+ }
96
+ .btn-google {
97
+ background: #fff;
98
+ color: #333;
99
+ }
100
+ .btn-ms {
101
+ background: #2f2f2f;
102
+ color: #e0e0e0;
103
+ border: 1px solid #444;
104
+ }
105
+ .login-actions {
106
+ display: flex;
107
+ flex-direction: column;
108
+ gap: 12px;
109
+ }
110
+
111
+ /* ── App shell ─────────────────────────────────── */
112
+ #app {
113
+ display: flex;
114
+ flex: 1;
115
+ overflow: hidden;
116
+ }
117
+ #app.hidden {
118
+ display: none;
119
+ }
120
+
121
+ /* ── Sidebar ───────────────────────────────────── */
122
+ #sidebar {
123
+ width: 280px;
124
+ min-width: 220px;
13
125
  background: #1e1e1e;
14
- font-family: Poppins, sans-serif;
15
- height: 100vh;
126
+ border-right: 1px solid #2a2a2a;
16
127
  display: flex;
17
128
  flex-direction: column;
129
+ overflow: hidden;
130
+ }
131
+
132
+ #sidebar-header {
133
+ padding: 16px;
134
+ border-bottom: 1px solid #2a2a2a;
135
+ display: flex;
136
+ align-items: center;
137
+ justify-content: space-between;
138
+ }
139
+ #sidebar-header span {
140
+ font-weight: 600;
141
+ font-size: 13px;
142
+ letter-spacing: 0.03em;
143
+ color: #aaa;
144
+ text-transform: uppercase;
145
+ }
146
+
147
+ #signout-btn {
148
+ background: none;
149
+ border: none;
150
+ color: #666;
151
+ cursor: pointer;
152
+ font-size: 12px;
153
+ font-family: inherit;
154
+ padding: 4px 8px;
155
+ border-radius: 4px;
156
+ }
157
+ #signout-btn:hover {
158
+ color: #ccc;
159
+ background: #2a2a2a;
160
+ }
161
+
162
+ .section-label {
163
+ padding: 12px 16px 6px;
164
+ font-size: 11px;
165
+ font-weight: 600;
166
+ letter-spacing: 0.06em;
167
+ text-transform: uppercase;
168
+ color: #666;
18
169
  }
19
- cue-document-viewer {
170
+
171
+ #project-select {
172
+ margin: 0 16px 4px;
173
+ padding: 8px 10px;
174
+ background: #2a2a2a;
175
+ border: 1px solid #383838;
176
+ border-radius: 6px;
177
+ color: #e0e0e0;
178
+ font-family: inherit;
179
+ font-size: 13px;
180
+ width: calc(100% - 32px);
181
+ cursor: pointer;
182
+ appearance: none;
183
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
184
+ background-repeat: no-repeat;
185
+ background-position: right 10px center;
186
+ padding-right: 28px;
187
+ }
188
+ #project-select:focus {
189
+ outline: none;
190
+ border-color: #555;
191
+ }
192
+
193
+ #sidebar-document-list-wrap {
194
+ flex: 1;
195
+ overflow: hidden;
196
+ padding: 0 8px 8px;
197
+ display: flex;
198
+ min-height: 0;
199
+ }
200
+
201
+ cue-document-list-wc#sidebar-document-list {
20
202
  display: block;
203
+ width: 100%;
204
+ height: 100%;
205
+ min-height: 0;
206
+ color: #e0e0e0;
207
+ --cue-main-foreground: #e0e0e0;
208
+ --cue-color-midgray: #8a8a8a;
209
+ --cue-color-ultralightgray: #2a2a2a;
210
+ --cue-color-lightgray: #3a465c;
211
+ }
212
+
213
+ #shuffle-btn {
214
+ margin: 8px 16px 12px;
215
+ padding: 7px;
216
+ background: #2a2a2a;
217
+ border: 1px solid #383838;
218
+ border-radius: 6px;
219
+ color: #aaa;
220
+ font-family: inherit;
221
+ font-size: 12px;
222
+ cursor: pointer;
223
+ width: calc(100% - 32px);
224
+ transition: background 0.1s;
225
+ }
226
+ #shuffle-btn:hover {
227
+ background: #333;
228
+ color: #e0e0e0;
229
+ }
230
+
231
+ /* ── Viewer area ───────────────────────────────── */
232
+ #viewer-area {
233
+ flex: 1;
234
+ display: flex;
235
+ flex-direction: column;
236
+ overflow: hidden;
237
+ position: relative;
238
+ }
239
+
240
+ /* The component host uses display:contents so it has no box itself.
241
+ A wrapper div is used to own the flex-item sizing. */
242
+ #viewer-wrapper {
21
243
  flex: 1;
244
+ min-height: 0;
22
245
  width: 100%;
246
+ overflow: hidden;
247
+ position: relative;
248
+ }
249
+
250
+ cue-document-viewer-wc {
251
+ display: block;
252
+ height: 100%;
253
+ width: 100%;
254
+ }
255
+
256
+ #placeholder {
257
+ flex: 1;
258
+ display: flex;
259
+ align-items: center;
260
+ justify-content: center;
261
+ color: #444;
262
+ font-size: 15px;
263
+ }
264
+ #placeholder.hidden {
265
+ display: none;
266
+ }
267
+
268
+ /* ── Loading spinner ───────────────────────────── */
269
+ .spinner {
270
+ display: inline-block;
271
+ width: 18px;
272
+ height: 18px;
273
+ border: 2px solid #333;
274
+ border-top-color: #888;
275
+ border-radius: 50%;
276
+ animation: spin 0.7s linear infinite;
277
+ vertical-align: middle;
278
+ margin-right: 8px;
279
+ }
280
+ @keyframes spin {
281
+ to {
282
+ transform: rotate(360deg);
283
+ }
23
284
  }
24
285
  </style>
25
286
  <style>@font-face{font-family:Poppins;font-style:normal;font-display:swap;font-weight:400;src:url(poppins-latin-ext-400-normal.woff2) format("woff2"),url(poppins-latin-ext-400-normal.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Poppins;font-style:normal;font-display:swap;font-weight:400;src:url(poppins-latin-400-normal.woff2) format("woff2"),url(poppins-latin-400-normal.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--agent-plan-edge-default:var(--cue-color-lightgray);--agent-plan-edge-running:var(--cue-color-blue);--agent-plan-edge-finished:var(--cue-color-blue);--agent-plan-node-active-outline:var(--cue-color-blue);--agent-plan-node-finished-box-shadow:0 0 12px var(--cue-color-green)}:root{--cue-font-family:"Poppins";--cue-font-weight-regular:400;--cue-font-weight-medium:500;--cue-font-weight-semibold:600;--cue-font-xs-size:56.25% ;--cue-font-xs-line-height:calc(16 / 11);--cue-font-xs-letter-spacing:.075em;--cue-font-s-size:68.75% ;--cue-font-s-line-height:calc(16 / 11);--cue-font-s-letter-spacing:.05em;--cue-font-m-size:87.5% ;--cue-font-m-line-height:calc(20 / 14);--cue-font-m-letter-spacing:.04em;--cue-font-l-size:112.5% ;--cue-font-l-line-height:calc(24 / 18);--cue-font-l-letter-spacing:.01em;--cue-font-xl-size:150% ;--cue-font-xl-line-height:calc(32 / 24);--cue-font-xl-letter-spacing:.01em}:root{--cue-color-blue:#2859e1;--cue-color-darkblue:#1744c2;--cue-color-ultralightgray:#f5f6f9;--cue-color-lightgray:#d9d9d9;--cue-color-midgray:#8394b0;--cue-color-darkmidgray:#404955;--cue-color-darkgray:#121c2b;--cue-color-black:#0e1827;--cue-color-white:#ffffff;--cue-color-green:#e2f552;--cue-main-background:var(--cue-color-ultralightgray);--cue-main-foreground:var(--cue-color-darkgray);--cue-default:var(--cue-color-white);--cue-defaultContrast:var(--cue-color-darkgray);--cue-primary:var(--cue-color-blue);--cue-primaryContrast:var(--cue-color-white);--cue-accent:var(--cue-color-green);--cue-accentContrast:var(--cue-color-darkgray);--cue-secondary:var(--cue-color-darkblue);--cue-secondaryContrast:var(--cue-color-white);--cue-neutral:var(--cue-color-midgray);--cue-neutralContrast:var(--cue-color-darkgray);--cue-info:var(--cue-color-darkblue);--cue-infoContrast:var(--cue-color-white);--cue-error:#fc2626;--cue-errorContrast:var(--cue-color-white);--cue-success:#4caf50;--cue-successContrast:var(--cue-color-white);--cue-warning:#ffc107;--cue-warningContrast:var(--cue-color-white);--cue-border-color:var(--cue-color-lightgray);--cue-scrollbar-thumb-color:var(--cue-color-lightgray);--cue-scrollbar-track-color:transparent}:root{--cue-chart-text-color:var(--cue-color-darkgray);--cue-chart-text-color-select:var(--cue-color-black);--cue-chart-border-background-color:var(--cue-color-white);--chart-graph-edge-color:var(--cue-color-darkgray)}:root{--cue-dim-gap-xs:.25em ;--cue-dim-gap-s:.5em ;--cue-dim-gap-m:1em ;--cue-dim-gap-l:1.875em ;--cue-dim-gap-xl:2.5em ;--cue-dim-elem-xs:1.5em ;--cue-dim-elem-s:2em ;--cue-dim-elem-m:2.75em ;--cue-dim-elem-l:3.5em ;--cue-dim-s-gap-s:.375em ;--cue-dim-s-gap-m:.625em ;--cue-dim-s-gap-l:1em ;--cue-dim-s-elem-xs:1em ;--cue-dim-s-elem-s:1.25em ;--cue-dim-s-elem-m:1.75em ;--cue-dim-padding-main:.625em ;--cue-dim-padding-sub:.625em }@media(min-width:20em){:root{--cue-dim-padding-main:1.25em ;--cue-dim-padding-sub:.625em }}@media(min-width:40em){:root{--cue-dim-padding-main:2em ;--cue-dim-padding-sub:1em }}:root{--cue-card-border-radius:1.875em ;--cue-card-padding-x:1em ;--cue-card-padding-y:1em ;--cue-card-border-color:var(--cue-border-color);--cue-card-box-shadow:0 1px 1.5em rgba(0, 0, 0, .2)}:root{--cue-button-gap:.5em ;--cue-button-xs-height:var(--cue-dim-elem-xs);--cue-button-xs-padding-x:.1875em ;--cue-button-xs-icon-width:1.125em ;--cue-button-s-height:var(--cue-dim-elem-s);--cue-button-s-padding-x:.375em ;--cue-button-s-icon-width:1.25em ;--cue-button-m-height:var(--cue-dim-elem-m);--cue-button-m-padding-x:.625em ;--cue-button-m-icon-width:1.5em ;--cue-button-l-height:var(--cue-dim-elem-l);--cue-button-l-padding-x:.75em ;--cue-button-l-icon-width:1.75em ;--cue-button-border-radius:var(--button-height);--cue-button-border-width:1px;--cue-button-border-style:solid;--cue-button-primary-background:var(--cue-color-blue);--cue-button-primary-foreground:var(--cue-color-white);--cue-button-primary-focus-color:var(--cue-color-blue);--cue-button-primary-border-color:var(--cue-color-blue);--cue-button-primary-disabled-foreground:var(--background-color, --cue-main-background);--cue-button-primary-disabled-foreground:var(--cue-color-lightgray);--cue-button-primary-disabled-background:var(--cue-color-ultralightgray);--cue-button-primary-disabled-border-color:var(--cue-color-ultralightgray);--cue-button-accent-background:var(--cue-accent);--cue-button-accent-foreground:var(--cue-accentContrast);--cue-button-accent-focus-color:var(--cue-accent);--cue-button-accent-border-color:var(--cue-accent);--cue-button-accent-disabled-foreground:var(--background-color, --cue-main-background);--cue-button-accent-disabled-foreground:var(--cue-color-lightgray);--cue-button-accent-disabled-background:var(--cue-color-ultralightgray);--cue-button-accent-disabled-border-color:var(--cue-color-ultralightgray);--cue-button-secondary-background:transparent;--cue-button-secondary-foreground:currentColor;--cue-button-secondary-focus-color:currentColor;--cue-button-secondary-border-color:currentColor;--cue-button-secondary-disabled-background:transparent;--cue-button-secondary-disabled-foreground:var(--cue-color-midgray);--cue-button-secondary-disabled-border-color:var(--cue-color-midgray);--cue-button-tertiary-background:transparent;--cue-button-tertiary-foreground:currentColor;--cue-button-tertiary-focus-color:currentColor;--cue-button-tertiary-border-color:transparent;--cue-button-tertiary-disabled-background:transparent;--cue-button-tertiary-disabled-foreground:var(--cue-color-midgray);--cue-button-tertiary-disabled-border-color:transparent;--cue-button-ghost-background:transparent;--cue-button-ghost-foreground:currentColor;--cue-button-ghost-focus-color:transparent;--cue-button-ghost-border-color:transparent;--cue-button-ghost-disabled-background:transparent;--cue-button-ghost-disabled-foreground:var(--cue-color-midgray);--cue-button-ghost-disabled-border-color:transparent;--cue-button-danger-background:transparent;--cue-button-danger-foreground:var(--cue-error);--cue-button-danger-focus-color:var(--cue-error);--cue-button-danger-border-color:transparent;--cue-button-danger-disabled-foreground:transparent;--cue-button-danger-disabled-background:var(--cue-color-midgray);--cue-button-danger-disabled-border-color:transparent;--cue-button-dim-background:transparent;--cue-button-dim-foreground:var(--cue-color-midgray);--cue-button-dim-focus-color:var(--cue-color-midgray);--cue-button-dim-border-color:var(--cue-color-lightgray);--cue-button-dim-disabled-background:transparent;--cue-button-dim-disabled-foreground:var(--cue-color-lightgray);--cue-button-dim-disabled-border-color:var(--cue-color-lightgray);--cue-button-xs-label-padding-x:.75em ;--cue-button-s-label-padding-x:1em ;--cue-button-m-label-padding-x:1.5em ;--cue-button-l-label-padding-x:3em }@media(prefers-color-scheme:dark){:root{--cue-button-primary-disabled-foreground:var(--cue-color-midgray);--cue-button-primary-disabled-border-color:var(--cue-color-midgray);--cue-button-primary-disabled-background:var(--cue-color-lightgray);--cue-button-secondary-disabled-foreground:var(--cue-color-darkmidgray);--cue-button-secondary-disabled-border-color:var(--cue-color-darkmidgray);--cue-button-tertiary-disabled-foreground:var(--cue-color-darkmidgray)}}:root{--cue-input-switch-background:var(--cue-color-midgray);--cue-input-switch-indicator-background:var(--cue-color-white);--cue-input-switch-indicator-foreground:var(--cue-color-black);--cue-input-switch-focus-color:var(--cue-color-white);--cue-input-switch-checked-background:var(--cue-color-darkblue);--cue-input-switch-checked-indicator-background:var(--cue-color-white);--cue-input-switch-checked-indicator-foreground:var(--cue-color-black);--cue-input-switch-disabled-background:var(--cue-color-midgray);--cue-input-switch-disabled-indicator-background:var(--cue-color-lightgray);--cue-input-switch-disabled-indicator-foreground:var(--cue-color-midgray)}:root{--cue-chip-delete-background-color:var(--cue-color-midgray);--cue-chip-delete-hover-background-color:var(--cue-color-darkmidgray);--cue-chip-delete-icon-color:var(--cue-color-ultralightgray)}:root{--cue-input-value-color:var(--cue-main-foreground);--cue-input-label-color:var(--cue-main-foreground);--cue-input-border-color:var(--cue-border-color);--cue-input-border-bottom-color:var(--cue-main-foreground);--cue-input-placeholder-color:var(--cue-color-darkmidgray);--cue-input-xs-padding:.75em .375em .25em .375em ;--cue-input-xs-font-size:.8125em ;--cue-input-xs-label-top:.75em ;--cue-input-xs-label-left:.375em ;--cue-input-xs-label-focused-top:.125em ;--cue-input-xs-label-focused-font-size:.625em ;--cue-input-s-padding:.875em .4375em .3125em .4375em ;--cue-input-s-font-size:.875em ;--cue-input-s-label-top:.875em ;--cue-input-s-label-left:.4375em ;--cue-input-s-label-focused-top:.1875em ;--cue-input-s-label-focused-font-size:.6875em ;--cue-input-m-padding:1em .5em .375em .5em ;--cue-input-m-font-size:1em ;--cue-input-m-label-top:1em ;--cue-input-m-label-left:.5em ;--cue-input-m-label-focused-top:.25em ;--cue-input-m-label-focused-font-size:.75em ;--cue-input-l-padding:1.125em .625em .5em .625em ;--cue-input-l-font-size:1.125em ;--cue-input-l-label-top:1.125em ;--cue-input-l-label-left:.625em ;--cue-input-l-label-focused-top:.3125em ;--cue-input-l-label-focused-font-size:.875em }:root{--cue-menu-border-radius:.9375em ;--cue-menu-padding-x:.5em ;--cue-menu-padding-y:.5em ;--cue-menu-gap:.5em ;--cue-menu-background-color:var(--cue-color-white);--cue-menu-foreground-color:var(--cue-color-black);--cue-menu-border-color:var(--cue-border-color);--cue-menu-box-shadow:0 1px 1.25em rgba(0, 0, 0, .1);--cue-menu-max-height:300px;--cue-menu-item-background-color:var(--cue-color-white);--cue-menu-item-selected-background-color:var(--cue-color-lightgray);--cue-menu-item-focus-background-color:var(--cue-color-ultralightgray);--cue-menu-item-height:var(--cue-dim-elem-m);--cue-menu-item-border-radius:.9375em ;--cue-menu-item-padding-x:1em ;--cue-menu-item-gap:1em ;--cue-menu-item-icon-size:1.25em ;--cue-menu-item-xs-min-width:3em;--cue-menu-item-s-min-width:6em;--cue-menu-item-m-min-width:12em}@container cue-container (width < 20em){:root{--cue-menu-item-xs-min-width:3em;--cue-menu-item-s-min-width:6em;--cue-menu-item-m-min-width:12em}}:root{--cue-grid-gap-s:var(--cue-dim-gap-s);--cue-grid-gap-m:var(--cue-dim-gap-m);--cue-grid-gap-l:var(--cue-dim-gap-l)}:root{--cue-flex-gap-xs:var(--cue-dim-gap-xs);--cue-flex-gap-s:var(--cue-dim-gap-s);--cue-flex-gap-m:var(--cue-dim-gap-m);--cue-flex-gap-l:var(--cue-dim-gap-l);--cue-flex-gap-xl:var(--cue-dim-gap-xl)}:root{--cue-table-row-border-bottom:1px solid;--cue-table-row-border-bottom-color:var(--cue-color-midgray);--cue-table-text-color:var(--cue-main-foreground);--cue-table-secondary-text-color:var(--cue-color-midgray);--cue-table-highlight-color:var(--cue-color-ultralightgray);--cue-table-highlight-text-color:var(--cue-color-darkgray);--cue-table-selected-color:var(--cue-color-green);--cue-table-selected-text-color:var(--cue-color-darkgray);--cue-table-border-color:var(--cue-border-color);--cue-table-row-hover-bg:var(--cue-color-ultralightgray);--cue-table-xs-height:200px;--cue-table-s-height:300px;--cue-table-m-height:400px;--cue-table-l-height:500px;--cue-table-xl-height:600px;--cue-table-font-xs-size:var(--cue-font-xs-size);--cue-table-font-s-size:var(--cue-font-s-size);--cue-table-font-m-size:var(--cue-font-m-size);--cue-table-font-l-size:var(--cue-font-l-size);--cue-table-data-font-xs-size:var(--cue-font-xs-size);--cue-table-data-font-s-size:var(--cue-font-s-size);--cue-table-data-font-m-size:var(--cue-font-m-size);--cue-table-data-font-l-size:var(--cue-font-l-size);--cue-table-data-font-xl-size:var(--cue-font-xl-size)}:root{--cue-paginator-text-color:var(--cue-main-foreground)}:root{--cue-modal-overlay-color:rgba(245, 246, 249, .7)}:root{--cue-icon-width:var(--cue-dim-elem-xs)}:root{--cue-stepper-border-color:var(--cue-main-foreground);--cue-stepper-fill-color:var(--cue-main-foreground);--cue-stepper-connector-color:var(--cue-main-foreground)}:root{color-scheme:light}html{padding:0;margin:0;height:100%;width:100%}body{display:flex;flex-direction:column;background-color:var(--cue-main-background);color:var(--cue-main-foreground)}body>*{scrollbar-color:var(--cue-scrollbar-thumb-color) var(--cue-scrollbar-track-color);scrollbar-width:thin;scroll-behavior:smooth}</style><link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.css"></noscript></head>
26
287
  <body>
27
- <div id="host"></div>
28
-
29
- <script>
30
- // The `cue` property must be set programmatically — it accepts an
31
- // already-authenticated Cue SDK instance (not an HTML attribute).
32
- //
33
- // Example (assuming @qaecy/cue-sdk is available on the page):
34
- //
35
- // import { Cue } from '@qaecy/cue-sdk';
36
- // const cue = new Cue();
37
- // await cue.auth.signIn('google');
38
- //
39
- // customElements.whenDefined('cue-document-viewer').then(() => {
40
- // const el = document.createElement('cue-document-viewer');
41
- // el.cue = cue;
42
- // el.uuid = 'abc-123?page=2';
43
- // el.projectId = 'my-project';
44
- // document.getElementById('host').appendChild(el);
45
- // });
46
- //
47
- // For this static demo page the UUID and projectId are read from
48
- // the URL query string so you can test without rebuilding.
49
- console.info(
50
- 'cue-document-viewer: set el.cue to an authenticated Cue instance before appending to DOM.'
51
- );
288
+ <!-- ── Login overlay ──────────────────────────────────── -->
289
+ <div id="login-overlay">
290
+ <div class="login-card">
291
+ <h1>Cue Document Viewer</h1>
292
+ <p>Sign in to browse your projects and documents</p>
293
+ <div class="login-actions">
294
+ <button class="btn btn-google" id="btn-google">
295
+ <svg width="18" height="18" viewBox="0 0 18 18">
296
+ <path fill="#4285F4" d="M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.875 2.684-6.615z"/>
297
+ <path fill="#34A853" d="M9 18c2.43 0 4.467-.806 5.956-2.184l-2.908-2.258c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z"/>
298
+ <path fill="#FBBC05" d="M3.964 10.707A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.707V4.961H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.039l3.007-2.332z"/>
299
+ <path fill="#EA4335" d="M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.961L3.964 7.293C4.672 5.163 6.656 3.58 9 3.58z"/>
300
+ </svg>
301
+ Continue with Google
302
+ </button>
303
+ <button class="btn btn-ms" id="btn-ms">
304
+ <svg width="18" height="18" viewBox="0 0 21 21">
305
+ <rect x="1" y="1" width="9" height="9" fill="#f25022"/>
306
+ <rect x="11" y="1" width="9" height="9" fill="#7fba00"/>
307
+ <rect x="1" y="11" width="9" height="9" fill="#00a4ef"/>
308
+ <rect x="11" y="11" width="9" height="9" fill="#ffb900"/>
309
+ </svg>
310
+ Continue with Microsoft
311
+ </button>
312
+ </div>
313
+ </div>
314
+ </div>
315
+
316
+ <!-- ── App shell ──────────────────────────────────────── -->
317
+ <div id="app" class="hidden">
318
+ <aside id="sidebar">
319
+ <div id="sidebar-header">
320
+ <span>Cue</span>
321
+ <button id="signout-btn">Sign out</button>
322
+ </div>
323
+ <div class="section-label">Project</div>
324
+ <select id="project-select">
325
+ <option value>Loading…</option>
326
+ </select>
327
+ <div class="section-label">Documents</div>
328
+ <div id="sidebar-document-list-wrap">
329
+ <cue-document-list-wc id="sidebar-document-list"></cue-document-list-wc>
330
+ </div>
331
+ <button id="shuffle-btn">&#8635; Shuffle 5 documents</button>
332
+ </aside>
333
+
334
+ <div id="viewer-area">
335
+ <div id="placeholder">Select a document to view</div>
336
+ </div>
337
+ </div>
338
+
339
+ <!-- ── Bootstrap error display ──────────────────────── -->
340
+ <div id="bootstrap-error" style="
341
+ display: none;
342
+ padding: 20px;
343
+ background: #c44;
344
+ color: white;
345
+ position: fixed;
346
+ inset: 0;
347
+ z-index: 1000;
348
+ overflow: auto;
349
+ font-family: monospace;
350
+ ">
351
+ <h2 style="margin-top: 0">Angular Bootstrap Failed</h2>
352
+ <p>The cue-document-viewer-wc web component failed to initialize.</p>
353
+ <pre id="bootstrap-error-details" style="background: #333; padding: 12px; border-radius: 4px; overflow-x: auto"></pre>
354
+ <p style="margin-bottom: 0; opacity: 0.9">
355
+ Check the browser console (F12) for more details.
356
+ </p>
357
+ </div>
358
+
359
+ <script type="module">
360
+ // ── Angular bootstrap health check ───────────────────
361
+ // Fires 4 s after page load. If Angular hasn't registered
362
+ // the custom element by then, it failed to bootstrap.
363
+ window.addEventListener('load', () => {
364
+ setTimeout(() => {
365
+ if (customElements.get('cue-document-viewer-wc')) {
366
+ console.log('[demo] ✓ cue-document-viewer-wc registered OK');
367
+ } else {
368
+ const errorMsg =
369
+ 'Angular failed to bootstrap. Check the Network tab for failed script loads (runtime.js / polyfills.js / main.js).';
370
+ console.error(
371
+ '[demo] ✗ cue-document-viewer-wc NOT registered after 4 s.\n' + errorMsg
372
+ );
373
+
374
+ // Display error on page
375
+ const errorDiv = document.getElementById('bootstrap-error');
376
+ const errorDetails = document.getElementById('bootstrap-error-details');
377
+ if (errorDiv && errorDetails) {
378
+ errorDetails.textContent =
379
+ errorMsg + '\n\nCheck browser console (F12) for detailed logs.';
380
+ errorDiv.style.display = 'flex';
381
+ errorDiv.style.flexDirection = 'column';
382
+ }
383
+ }
384
+ }, 4000);
385
+ });
386
+ </script>
387
+
388
+ <script type="module">
389
+ import { Cue } from 'https://esm.sh/@qaecy/cue-sdk@0.0.17?external=firebase';
390
+
391
+ const PREFIXES = `
392
+ PREFIX qcy: <https://dev.qaecy.com/ont#>
393
+ `;
394
+
395
+ const DOCS_QUERY =
396
+ PREFIXES +
397
+ `
398
+ SELECT ?content ?name ?suffix WHERE {
399
+ ?content a qcy:FileContent ;
400
+ qcy:hasFileLocation ?loc .
401
+ ?loc qcy:value ?name ;
402
+ qcy:suffix ?suffix .
403
+ }
404
+ ORDER BY ?name
405
+ `;
406
+
407
+ // ── State ────────────────────────────────────────────
408
+ const DEMO_DEBUG = true;
409
+ const cue = new Cue();
410
+ let allDocs = [];
411
+ let shownDocs = [];
412
+ let activeProjectId = null;
413
+ let viewer = null;
414
+ let currentUser = null;
415
+
416
+ // ── UI helpers ───────────────────────────────────────
417
+ const $ = (id) => document.getElementById(id);
418
+ const debug = (...args) => {
419
+ if (DEMO_DEBUG) console.debug('[demo:list]', ...args);
420
+ };
421
+
422
+ function showLogin() {
423
+ $('login-overlay').classList.remove('hidden');
424
+ $('app').classList.add('hidden');
425
+ }
426
+
427
+ function showApp() {
428
+ $('login-overlay').classList.add('hidden');
429
+ $('app').classList.remove('hidden');
430
+ }
431
+
432
+ function uuidFromIri(iri) {
433
+ return iri.split('/').pop();
434
+ }
435
+
436
+ function sidebarList() {
437
+ return $('sidebar-document-list');
438
+ }
439
+
440
+ function pickRandom(arr, n) {
441
+ const copy = [...arr];
442
+ for (let i = copy.length - 1; i > 0; i--) {
443
+ const j = Math.floor(Math.random() * (i + 1));
444
+ [copy[i], copy[j]] = [copy[j], copy[i]];
445
+ }
446
+ return copy.slice(0, n);
447
+ }
448
+
449
+ // ── Sidebar document list ─────────────────────────────
450
+ async function renderFileList(docs) {
451
+ shownDocs = docs;
452
+ await customElements.whenDefined('cue-document-list-wc');
453
+ const list = sidebarList();
454
+ if (!list) return;
455
+
456
+ debug('renderFileList', {
457
+ projectId: activeProjectId,
458
+ docsCount: docs.length,
459
+ uuids: docs.map((doc) => doc.uuid),
460
+ language: cue.api.language || 'en',
461
+ });
462
+
463
+ list.projectId = activeProjectId;
464
+ list.uuids = docs.map((doc) => doc.uuid);
465
+ list.sdkState = { cue, language: cue.api.language || 'en' };
466
+ }
467
+
468
+ // ── Open document in viewer ──────────────────────────
469
+ async function openDocument(docOrRow) {
470
+ const uuid = docOrRow?.uuid ?? docOrRow?.id;
471
+ if (!uuid) return;
472
+
473
+ $('placeholder').classList.add('hidden');
474
+
475
+ // Remove old wrapper + viewer
476
+ const oldWrapper = $('viewer-wrapper');
477
+ if (oldWrapper) oldWrapper.remove();
478
+ viewer = null;
479
+
480
+ await customElements.whenDefined('cue-document-viewer-wc');
481
+
482
+ // Wrap in a div because :host{display:contents} removes the
483
+ // custom element from the box model — the wrapper owns the size.
484
+ const wrapper = document.createElement('div');
485
+ wrapper.id = 'viewer-wrapper';
486
+
487
+ viewer = document.createElement('cue-document-viewer-wc');
488
+
489
+ // CRITICAL: Append to DOM FIRST before setting inputs.
490
+ // Angular needs to initialize the element in the DOM context
491
+ // before property setters will work properly with signals.
492
+ wrapper.appendChild(viewer);
493
+ const viewerArea = $('viewer-area');
494
+ viewerArea.appendChild(wrapper);
495
+
496
+ // Wait for Angular to hydrate and settle
497
+ await new Promise((resolve) => requestAnimationFrame(resolve));
498
+ await new Promise((resolve) => setTimeout(resolve, 100));
499
+
500
+ // Now set properties after DOM insertion and Angular initialization
501
+ viewer.cue = cue;
502
+ viewer.projectId = activeProjectId;
503
+ viewer.uuid = uuid;
504
+ }
505
+
506
+ // ── Load documents for a project ─────────────────────
507
+ async function loadDocuments(projectId) {
508
+ activeProjectId = projectId;
509
+ debug('loadDocuments:start', { projectId });
510
+ const list = sidebarList();
511
+ if (list) {
512
+ list.projectId = projectId;
513
+ list.uuids = [];
514
+ // Keep sdkState unset while project documents are being resolved,
515
+ // so simple mode stays in loading state instead of flashing "No documents".
516
+ list.sdkState = undefined;
517
+ }
518
+
519
+ try {
520
+ const result = await cue.api.sparql(DOCS_QUERY, projectId);
521
+ allDocs = result.results.bindings.map((b) => ({
522
+ uuid: uuidFromIri(b.content.value),
523
+ name: b.name.value,
524
+ suffix: b.suffix?.value ?? '',
525
+ }));
526
+ debug('loadDocuments:sparql:ok', {
527
+ projectId,
528
+ totalDocs: allDocs.length,
529
+ });
530
+ await renderFileList(pickRandom(allDocs, 5));
531
+ } catch (err) {
532
+ console.error('Failed to load documents', err);
533
+ debug('loadDocuments:sparql:error', { projectId, err });
534
+ const listOnError = sidebarList();
535
+ if (listOnError) listOnError.uuids = [];
536
+ }
537
+ }
538
+
539
+ // ── Load projects into selector ───────────────────────
540
+ async function loadProjects() {
541
+ const sel = $('project-select');
542
+ sel.innerHTML = '<option value="">Loading…</option>';
543
+
544
+ try {
545
+ const projects = await cue.projects.listProjects();
546
+ sel.innerHTML = projects
547
+ .map((p) => `<option value="${p.id}">${p.name}</option>`)
548
+ .join('');
549
+
550
+ if (projects.length) {
551
+ await loadDocuments(projects[0].id);
552
+ }
553
+ } catch (err) {
554
+ console.error('Failed to load projects', err);
555
+ sel.innerHTML = '<option value="">Error loading projects</option>';
556
+ }
557
+ }
558
+
559
+ // ── Event listeners ──────────────────────────────────
560
+ $('btn-google').addEventListener('click', () => cue.auth.signIn('google'));
561
+ $('btn-ms').addEventListener('click', () => cue.auth.signIn('microsoft'));
562
+ $('signout-btn').addEventListener('click', () => cue.auth.signOut());
563
+
564
+ $('project-select').addEventListener('change', (e) => {
565
+ if (e.target.value) loadDocuments(e.target.value);
566
+ });
567
+
568
+ $('shuffle-btn').addEventListener('click', () => {
569
+ if (allDocs.length) {
570
+ debug('shuffle', { totalDocs: allDocs.length });
571
+ renderFileList(pickRandom(allDocs, 5));
572
+ }
573
+ });
574
+
575
+ customElements.whenDefined('cue-document-list-wc').then(() => {
576
+ const list = sidebarList();
577
+ if (!list) return;
578
+ debug('custom element ready', { id: 'cue-document-list-wc' });
579
+ list.simple = true;
580
+ list.pageSize = 5;
581
+ list.prefetchPages = 3;
582
+ list.showOpenInDocumentViewerAction = false;
583
+ list.showOpenInFileManagerAction = false;
584
+ list.addEventListener('clickedDocument', (event) => {
585
+ debug('clickedDocument event', { detail: event.detail });
586
+ openDocument(event.detail);
587
+ });
588
+ });
589
+
590
+ // ── Auth state ───────────────────────────────────────
591
+ cue.auth.onAuthStateChanged((user) => {
592
+ // Guard: only proceed if auth state actually changed
593
+ if (currentUser === user) return;
594
+ currentUser = user;
595
+ debug('auth state changed', { isSignedIn: !!user });
596
+
597
+ if (user) {
598
+ showApp();
599
+ loadProjects();
600
+ } else {
601
+ showLogin();
602
+ const list = sidebarList();
603
+ if (list) {
604
+ list.projectId = undefined;
605
+ list.uuids = [];
606
+ list.sdkState = undefined;
607
+ }
608
+ }
609
+ });
610
+
611
+ // ── Global error logging ───────────────────────────
612
+ window.addEventListener('error', (evt) => {
613
+ console.error('[demo] Global error:', evt.error);
614
+ });
615
+ window.addEventListener('unhandledrejection', (evt) => {
616
+ console.error('[demo] Unhandled promise rejection:', evt.reason);
617
+ });
52
618
  </script>
53
619
  <script src="runtime.js" type="module"></script><script src="polyfills.js" type="module"></script><script src="main.js" type="module"></script></body>
54
620
  </html>