Skip to content

Commit 6ba902f

Browse files
Merge pull request #12 from CrowdStrike/remove-remaining-deprecated-apis
Remove remaining deprecated apis
2 parents 907b9bc + 38c1d9f commit 6ba902f

File tree

22 files changed

+1285
-89
lines changed

22 files changed

+1285
-89
lines changed

CONTRIBUTING.md

+7
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,10 @@
2626

2727
* `cd docs-app`
2828
* `pnpm start` – starts the test app and tests are available at `/tests`
29+
30+
## Notes, Caveats, and Bugs
31+
32+
Until [this pnpm issue#4965](https://github.com/pnpm/pnpm/issues/4965) is fixed,
33+
with the peer-dependency requirements of this repo, every time you re-build the addon,
34+
you'll need to re-run `pnpm install` to re-create the links in the local `node_modules/.pnpm` store.
35+
Thankfully, this is pretty fast.

docs-app/package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@
3434
"@embroider/webpack": "^1.9.0",
3535
"@glimmer/component": "^1.1.2",
3636
"@glimmer/tracking": "^1.1.2",
37-
"@glint/core": "^0.9.5",
38-
"@glint/environment-ember-loose": "^0.9.5",
39-
"@glint/environment-ember-template-imports": "^0.9.5",
40-
"@glint/template": "^0.9.5",
37+
"@glint/core": "^0.9.6",
38+
"@glint/environment-ember-loose": "^0.9.6",
39+
"@glint/environment-ember-template-imports": "^0.9.6",
40+
"@glint/template": "^0.9.6",
4141
"@html-next/vertical-collection": "^4.0.0",
4242
"@nullvoxpopuli/eslint-configs": "^2.2.59",
4343
"@tailwindcss/typography": "^0.5.7",
@@ -114,13 +114,13 @@
114114
"edition": "octane"
115115
},
116116
"dependencies": {
117-
"@crowdstrike/ember-oss-docs": "^1.0.29",
117+
"@crowdstrike/ember-oss-docs": "^1.1.0",
118118
"@ember/test-waiters": "^3.0.2",
119119
"@embroider/router": "^1.9.0",
120120
"dompurify": "^2.4.0",
121121
"ember-browser-services": "^4.0.3",
122122
"ember-cached-decorator-polyfill": "^1.0.1",
123-
"ember-headless-table": "workspace:*",
123+
"ember-headless-table": "workspace:../ember-headless-table",
124124
"ember-modifier": "^3.2.7",
125125
"ember-resources": "^5.4.0",
126126
"highlight.js": "^11.6.0",

docs/demos/index.md

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
categoryOrder: 3
3+
---
4+
5+
# Demos and examples
6+
7+
While each plugin has its own demo for how to use the plugin (and in combination with other plugins),
8+
there are common behaviors and patterns that can be acheived with the plugin system (with the existing plugins)
9+
that fit more in to a "kitchen-sink" style collection of demos.
10+
11+
If you have an idea for a demo, please [open an issue](https://github.com/CrowdStrike/ember-headless-table/issues)
12+
requesting the demo, or even better, submit a pull request adding your demo.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
```hbs template
2+
3+
FPS: {{this.fps}}<br>
4+
<div data-container class="h-full overflow-auto" {{this.table.modifiers.container}}>
5+
<table>
6+
<thead>
7+
<tr>
8+
{{#each this.table.columns as |column|}}
9+
<th {{this.table.modifiers.columnHeader column}}>
10+
{{column.name}}
11+
</th>
12+
{{/each}}
13+
</tr>
14+
</thead>
15+
<tbody>
16+
{{#each this.table.rows as |row|}}
17+
<tr class="{{row.countClassName}}">
18+
{{#each this.table.columns as |column|}}
19+
<td>
20+
{{#if column.Cell}}
21+
<column.Cell @row={{row}} @column={{column}} />
22+
{{else}}
23+
{{column.getValueForRow row}}
24+
{{/if}}
25+
</td>
26+
{{/each}}
27+
</tr>
28+
{{/each}}
29+
</tbody>
30+
</table>
31+
</div>
32+
<style>
33+
[data-container] {
34+
height: 500px;
35+
overflow: scroll;
36+
position: relative;
37+
}
38+
[data-container] thead {
39+
position: sticky;
40+
top: 0;
41+
background: var(--basement);
42+
}
43+
[data-container] .label {
44+
padding: 0.2rem 0.6rem 0.3rem;
45+
font-size: 75%;
46+
color: white;
47+
border-radius: 0.25rem;
48+
}
49+
[data-container] th {
50+
/* styling the table isn't the focus of this demo (perf is the focus) */
51+
width: calc(100% / 7);
52+
}
53+
[data-container] th:first-child {
54+
min-width: 190px;
55+
}
56+
[data-container] .label-success { background-color: #5cb85c; }
57+
[data-container] .label-warning { background-color:#f0ad4e; }
58+
[data-container] .label-danger { background-color:#d9534f; }
59+
</style>
60+
```
61+
```js component
62+
import Component from '@glimmer/component';
63+
import { tracked, cached } from '@glimmer/tracking';
64+
import { cell, use, resource, resourceFactory } from 'ember-resources';
65+
import { map } from 'ember-resources/util/map';
66+
67+
import { headlessTable } from 'ember-headless-table';
68+
69+
export default class extends Component {
70+
table = headlessTable(this, {
71+
columns: () => [
72+
{ name: 'dbname', key: 'db.id' },
73+
{ name: 'query count', key: 'queries.length', Cell: QueryStatus },
74+
{ name: '', key: 'topFiveQueries.0.elapsed' },
75+
{ name: '', key: 'topFiveQueries.1.elapsed' },
76+
{ name: '', key: 'topFiveQueries.2.elapsed' },
77+
{ name: '', key: 'topFiveQueries.3.elapsed' },
78+
{ name: '', key: 'topFiveQueries.4.elapsed' },
79+
],
80+
data: () => this.data,
81+
});
82+
83+
@use dbData = DBMonitor;
84+
85+
@use fps = FPS.of(() => this.dbData.databases);
86+
87+
get data() {
88+
return this.mappedData.values();
89+
}
90+
91+
mappedData = map(this, {
92+
data: () => this.dbData.databases,
93+
map: (databaseData) => new Database(databaseData),
94+
})
95+
}
96+
97+
const FPS = {
98+
of: resourceFactory((ofWhat) => {
99+
let updateInterval = 500; // ms
100+
let multiplier = 1000 / updateInterval;
101+
let framesSinceUpdate = 0;
102+
103+
return resource(({ on }) => {
104+
let value = cell(0);
105+
let interval = setInterval(() => {
106+
value.current = framesSinceUpdate * multiplier;
107+
framesSinceUpdate = 0;
108+
}, updateInterval);
109+
110+
on.cleanup(() => clearInterval(interval));
111+
112+
return () => {
113+
ofWhat();
114+
framesSinceUpdate++;
115+
116+
return value.current;
117+
}
118+
});
119+
})
120+
}
121+
122+
const DBMonitor = resource(({ on }) => {
123+
let value = cell(getData(20));
124+
let frame;
125+
let generateData = () => {
126+
// simulate receiving data as fast as possible
127+
frame = requestAnimationFrame(() => {
128+
value.current = getData(20);
129+
generateData();
130+
});
131+
}
132+
133+
on.cleanup(() => cancelAnimationFrame(frame));
134+
135+
// Start the infinite requestAnimationFrame chain
136+
generateData();
137+
138+
return () => value.current;
139+
});
140+
141+
class Database {
142+
constructor(db) {
143+
this.db = db;
144+
}
145+
146+
get queries() {
147+
return this.db.queries;
148+
}
149+
150+
@cached
151+
get topFiveQueries() {
152+
let queries = this.queries || [];
153+
let topFiveQueries = queries.slice(0, 5);
154+
155+
while (topFiveQueries.length < 5) {
156+
topFiveQueries.push({ query: '' });
157+
}
158+
159+
return topFiveQueries.map(function(query, index) {
160+
return {
161+
key: String(index),
162+
query: query.query,
163+
elapsed: query.elapsed ? formatElapsed(query.elapsed) : '',
164+
className: elapsedClass(query.elapsed)
165+
};
166+
});
167+
}
168+
169+
@cached
170+
get countClassName() {
171+
let queries = this.queries || [];
172+
let countClassName = 'label';
173+
174+
if (queries.length >= 20) {
175+
countClassName += ' label-important';
176+
} else if (queries.length >= 10) {
177+
countClassName += ' label-warning';
178+
} else {
179+
countClassName += ' label-success';
180+
}
181+
182+
return countClassName;
183+
}
184+
185+
186+
}
187+
188+
function elapsedClass(elapsed) {
189+
if (elapsed >= 10.0) {
190+
return 'elapsed warn_long';
191+
} else if (elapsed >= 1.0) {
192+
return 'elapsed warn';
193+
} else {
194+
return 'elapsed short';
195+
}
196+
}
197+
198+
function leftPad(str, padding, toLength) {
199+
return padding.repeat((toLength - str.length) / padding.length).concat(str);
200+
};
201+
202+
function formatElapsed(value) {
203+
let str = parseFloat(value).toFixed(2);
204+
205+
if (value > 60) {
206+
const minutes = Math.floor(value / 60);
207+
const comps = (value % 60).toFixed(2).split('.');
208+
const seconds = leftPad(comps[0], '0', 2);
209+
str = `${minutes}:${seconds}.${comps[1]}`;
210+
}
211+
212+
return str;
213+
}
214+
215+
/**
216+
* Temporary work-around because docfy.dev doesn't support gjs
217+
*/
218+
import { setComponentTemplate } from '@ember/component';
219+
import templateOnly from '@ember/component/template-only';
220+
import { hbs } from 'ember-cli-htmlbars';
221+
222+
const QueryStatus = templateOnly();
223+
setComponentTemplate(hbs`
224+
<td>
225+
<span class="{{@row.data.countClassName}}">
226+
{{@row.data.queries.length}}
227+
</span>
228+
</td>
229+
`, QueryStatus);
230+
231+
/**
232+
* dbmon code copied from
233+
* https://github.com/html-next/vertical-collection/blob/master/tests/dummy/app/lib/get-data.js
234+
*/
235+
const DEFAULT_ROWS = 20;
236+
237+
function getData(ROWS) {
238+
ROWS = ROWS || DEFAULT_ROWS;
239+
240+
// generate some dummy data
241+
const data = {
242+
start_at: new Date().getTime() / 1000,
243+
databases: []
244+
};
245+
246+
for (let i = 1; i <= ROWS; i++) {
247+
248+
data.databases.push({
249+
id: `cluster${i}`,
250+
queries: []
251+
});
252+
253+
data.databases.push({
254+
id: ` ↳ cluster${i}-secondary`,
255+
queries: []
256+
});
257+
258+
}
259+
260+
data.databases.forEach(function(info) {
261+
const r = Math.floor((Math.random() * 10) + 1);
262+
263+
for (let i = 0; i < r; i++) {
264+
const q = {
265+
canvas_action: null,
266+
canvas_context_id: null,
267+
canvas_controller: null,
268+
canvas_hostname: null,
269+
canvas_job_tag: null,
270+
canvas_pid: null,
271+
elapsed: Math.random() * 15,
272+
query: 'SELECT blah FROM something',
273+
waiting: Math.random() < 0.5
274+
};
275+
276+
if (Math.random() < 0.2) {
277+
q.query = '<IDLE> in transaction';
278+
}
279+
280+
if (Math.random() < 0.1) {
281+
q.query = 'vacuum';
282+
}
283+
284+
info.queries.push(q);
285+
}
286+
287+
info.queries = info.queries.sort(function(a, b) {
288+
return b.elapsed - a.elapsed;
289+
});
290+
});
291+
292+
return data;
293+
}
294+
```
295+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Lots of data (no virtualization)
2+
3+
This demo is the same as "[Lots of Data](/docs/demos/lots-of-data)",
4+
but without virtualization and no use of [@html-next/vertical-collection][gh-vc]
5+
6+
[gh-vc]: https://github.com/html-next/vertical-collection
7+
8+
In this demo, 6 columns x 40 rows are updating as quickly as requestAnimationFrame allows.
9+

0 commit comments

Comments
 (0)