Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentSchippefilt committed Jul 19, 2024
1 parent 190765b commit 9838b47
Show file tree
Hide file tree
Showing 146 changed files with 1,752 additions and 1,359 deletions.
26 changes: 18 additions & 8 deletions demo/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const {
onError,
} = owl;

const { Spreadsheet, Model } = o_spreadsheet;
const { Spreadsheet, Model, LongRunner } = o_spreadsheet;
const { topbarMenuRegistry } = o_spreadsheet.registries;
const { useStoreProvider } = o_spreadsheet.stores;

Expand Down Expand Up @@ -207,7 +207,7 @@ class Demo extends Component {
});
});

onWillStart(() => this.initiateConnection());
onWillStart(async () => await this.initiateConnection());

onMounted(() => console.log("Mounted: ", Date.now() - start));
onWillUnmount(this.leaveCollaborativeSession.bind(this));
Expand Down Expand Up @@ -237,17 +237,25 @@ class Demo extends Component {
this.transportService = undefined;
this.stateUpdateMessages = [];
}
this.createModel(data || demoData);
// this.createModel(makePivotDataset(10_000));

for (let i = 0; i < 500; i++) {
let newSheet = Object.assign({}, demoData.sheets[3]);
newSheet.id = "newsheet" + i;
newSheet.name = "newsheet" + i;
demoData.sheets.push(newSheet);
}

await this.createModel(data || demoData);
// this.createModel(makePivotDataset(100_000));
// this.createModel(makeLargeDataset(26, 10_000, ["numbers"]));
// this.createModel(makeLargeDataset(26, 10_000, ["formulas"]));
// this.createModel(makeLargeDataset(26, 10_000, ["arrayFormulas"]));
// this.createModel(makeLargeDataset(26, 10_000, ["vectorizedFormulas"]));
// this.createModel({});
// await this.createModel(makeLargeDataset(26, 1000, ["vectorizedFormulas"]));
// await this.createModel({});
}

createModel(data) {
this.model = new Model(
async createModel(data) {
this.model = await Model.Build(
data,
{
external: {
Expand All @@ -258,6 +266,7 @@ class Demo extends Component {
transportService: this.transportService,
client: this.client,
mode: "normal",
longRunner: new LongRunner(),
},
this.stateUpdateMessages
);
Expand Down Expand Up @@ -334,4 +343,5 @@ async function setup() {
rootApp.addTemplates(templates);
rootApp.mount(document.body);
}

whenReady(setup);
2 changes: 1 addition & 1 deletion doc/add_function.md
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ Let's say you have a `user` service with the currently logged in user.
The example below shows how the service can be used in a custom function.
```ts
const model = new Model(data, {
const model = Model.BuildSync(data, {
custom: {
userService: services.user,
},
Expand Down
2 changes: 1 addition & 1 deletion doc/extending/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const col = 0;
const row = 0;
const sheetId = "1";

const model = new Model();
const model = Model.BuildSync();

// Update A1's content by dispatching a command
model.dispatch("UPDATE_CELL", {
Expand Down
4 changes: 2 additions & 2 deletions doc/extending/plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class MyPlugin extends CorePlugin {
MyPlugin.getters = ["getSomething"];

// add the new "MyPlugin" to the plugin registry.
// It will be automatically instantiated by o-spreadsheet when you mount the spreadsheet component or when you create a new Model()
// It will be automatically instantiated by o-spreadsheet when you mount the spreadsheet component or when you create a Model.BuildSync()
const pluginRegistry = spreadsheet.registries.pluginRegistry;
pluginRegistry.add("MyPlugin", MyPlugin);
```
Expand Down Expand Up @@ -199,7 +199,7 @@ Let's say you have a `user` service with the currently logged in user.
The example below shows how the service can be used in a custom plugin.

```ts
const model = new Model(data, {
const model = Model.BuildSync(data, {
custom: {
userService: services.user,
},
Expand Down
2 changes: 1 addition & 1 deletion doc/integrating/collaborative/collaborative.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Realtime collaboration edition can be enabled to synchronize a spreadsheet acros
It is enabled by providing a way to communicate with other connected clients to the `<Spreadsheet/>` component. We call it the _transport service_. Its interface and how it should be implemented is described in a [dedicated section](#transport-service). An optional [client](tsdoc/interfaces/client.md) can also be provided to display the names of connected clients.

```ts
const model = new Model(data, {
const model = Model.BuildSync(data, {
transportService,
client: { id: 456, name: "Raoul" },
});
Expand Down
10 changes: 5 additions & 5 deletions doc/integrating/integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Here is the shortest example to use o-spreadsheet.
```typescript
const { Spreadsheet, Model } = o_spreadsheet;

const model = new Model();
const model = Model.BuildSync();
const templates = await(await fetch("../dist/o_spreadsheet.xml")).text();
const app = new owl.App(Spreadsheet, {
props: {
Expand Down Expand Up @@ -53,7 +53,7 @@ Spreadsheet model can be created with the following arguments, all optionals:

```ts
const { Model } = o_spreadsheet;
const model = new Model(data, config);
const model = Model.BuildSync(data, config);
```

- `data`
Expand Down Expand Up @@ -99,7 +99,7 @@ Your file store instance should implements the [`FileStore`](https://github.com/
```ts
const fileStore = new MyFileStore(...);

const model = new Model(data, {
const model = Model.BuildSync(data, {
external: {
fileStore,
},
Expand All @@ -121,7 +121,7 @@ async function loadCurrencies() {
];
}

const model = new Model(data, {
const model = Model.BuildSync(data, {
external: {
loadCurrencies,
},
Expand Down Expand Up @@ -149,7 +149,7 @@ async function loadLocales() {
return [ locale, locale2, ...];
}

const model = new Model(data, {
const model = Model.BuildSync(data, {
external: {
loadLocales,
},
Expand Down
23 changes: 16 additions & 7 deletions src/collaborative/session.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DEBOUNCE_TIME, DEFAULT_REVISION_ID, MESSAGE_VERSION } from "../constants";
import { UuidGenerator } from "../helpers";
import { EventBus } from "../helpers/event_bus";
import { ILongRunner, SynchronousLongRunner } from "../helpers/long_runner";
import { debounce, isDefined } from "../helpers/misc";
import { SelectiveHistory as RevisionLog } from "../history/selective_history";
import { CoreCommand, HistoryChange, UID, WorkbookData } from "../types";
Expand Down Expand Up @@ -50,6 +51,7 @@ export class Session extends EventBus<CollaborativeEvent> {

private uuidGenerator = new UuidGenerator();
private lastLocalOperation: Revision | undefined;
private longRunner: ILongRunner;
/**
* Manages the collaboration between multiple users on the same spreadsheet.
* It can forward local state changes to other users to ensure they all eventually
Expand All @@ -60,15 +62,17 @@ export class Session extends EventBus<CollaborativeEvent> {
* @param revisions
* @param transportService communication channel used to send and receive messages
* between all connected clients
* @param client the client connected locally
* @param serverRevisionId
* @param longRunner
*/
constructor(
private revisions: RevisionLog<Revision>,
private transportService: TransportService<CollaborationMessage>,
private serverRevisionId: UID = DEFAULT_REVISION_ID
private serverRevisionId: UID = DEFAULT_REVISION_ID,
longRunner: ILongRunner = new SynchronousLongRunner()
) {
super();
this.longRunner = longRunner;

this.debouncedMove = debounce(this._move.bind(this), DEBOUNCE_TIME) as Session["move"];
}
Expand Down Expand Up @@ -155,11 +159,16 @@ export class Session extends EventBus<CollaborativeEvent> {
0
);
this.isReplayingInitialRevisions = true;
for (const message of messages) {
this.onMessageReceived(message);
}
this.isReplayingInitialRevisions = false;
console.info("Replayed", numberOfCommands, "commands in", performance.now() - start, "ms");
return this.longRunner.queueJob(
"Replaying revisions",
messages,
this.onMessageReceived.bind(this),
50,
() => {
this.isReplayingInitialRevisions = false;
console.info("Replayed", numberOfCommands, "commands in", performance.now() - start, "ms");
}
);
}

/**
Expand Down
80 changes: 80 additions & 0 deletions src/components/progress_bar/progress_bar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Component, onMounted, onWillUnmount, useState } from "@odoo/owl";
import { SCROLLBAR_WIDTH } from "../../constants";
import { LongRunner } from "../../helpers/long_runner";
import { SpreadsheetChildEnv, UID } from "../../types";
import { css, cssPropertiesToCss } from "../helpers";

css/* scss */ `
.o-progressBar-container {
position: absolute;
right: ${SCROLLBAR_WIDTH}px;
bottom: 52px;
min-width: 200px;
.o-progressBar {
.o-progressBar-text {
text-wrap: nowrap;
text-overflow: ellipsis;
}
}
}
`;

interface ProgressBarProps {
longRunner: LongRunner;
}

export class SpreadsheetProgressBar extends Component<ProgressBarProps, SpreadsheetChildEnv> {
static template = "o-spreadsheet-ProgressBar";
static props = {
longRunner: Object,
};
private progressBars = useState<{ id: UID; name: string; progress: number }[]>([]);

setup() {
onMounted(() => {
this.props.longRunner.on("job-queued", this, this.jobQueued);
this.props.longRunner.on("job-started", this, this.jobStarted);
this.props.longRunner.on("job-continued", this, this.jobContinued);
this.props.longRunner.on("job-done", this, this.jobDone);
});
onWillUnmount(() => {
this.props.longRunner.off("job-queued", this);
this.props.longRunner.off("job-started", this);
this.props.longRunner.off("job-continued", this);
this.props.longRunner.off("job-done", this);
});
}

jobQueued(e) {
this.progressBars.push({ id: e.id, name: e.name, progress: 0 });
}

jobStarted(e) {
let progress = this.progressBars.find((x) => x.id === e.id);
if (!progress) {
this.progressBars.push({ id: e.id, name: e.name, progress: 0 });
}
}

jobContinued(e) {
let progress = this.progressBars.find((x) => x.id === e.id);
if (!progress) {
this.progressBars.push({ id: e.id, name: e.name, progress: e.progress });
} else {
progress.progress = e.progress;
}
}

jobDone(e) {
let progressIndex = this.progressBars.findIndex((x) => x.id === e.id);
if (progressIndex !== -1) {
this.progressBars.splice(progressIndex, 1);
}
}

getStyle(progressBar) {
return cssPropertiesToCss({
width: progressBar.progress + "%",
});
}
}
22 changes: 22 additions & 0 deletions src/components/progress_bar/progress_bar.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<t t-name="o-spreadsheet-ProgressBar">
<div class="o-progressBar-container" t-if="progressBars.length">
<t t-foreach="progressBars" t-as="progressBar" t-key="progressBar.id">
<div class="o-progressBar">
<span
class="o-progressBar-text"
t-out="progressBar.name + ' ('+progressBar.progress + ' %)'"
/>
</div>
<div class="progress">
<div
class="progress-bar"
role="progressbar"
t-att-aria-valuenow="progressBar.progress"
aria-valuemin="0"
aria-valuemax="100"
t-att-style="getStyle(progressBar)"
/>
</div>
</t>
</div>
</t>
4 changes: 3 additions & 1 deletion src/components/spreadsheet/spreadsheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { HeaderGroupContainer } from "../header_group/header_group_container";
import { css, cssPropertiesToCss } from "../helpers/css";
import { isCtrlKey } from "../helpers/dom_helpers";
import { useSpreadsheetRect } from "../helpers/position_hook";
import { SpreadsheetProgressBar } from "../progress_bar/progress_bar";
import { SidePanel } from "../side_panel/side_panel/side_panel";
import { SidePanelStore } from "../side_panel/side_panel/side_panel_store";
import { TopBar } from "../top_bar/top_bar";
Expand Down Expand Up @@ -270,6 +271,7 @@ export class Spreadsheet extends Component<SpreadsheetProps, SpreadsheetChildEnv
SidePanel,
SpreadsheetDashboard,
HeaderGroupContainer,
SpreadsheetProgressBar,
};

sidePanel!: Store<SidePanelStore>;
Expand Down Expand Up @@ -454,7 +456,7 @@ export class Spreadsheet extends Component<SpreadsheetProps, SpreadsheetChildEnv
}

get gridHeight(): Pixel {
const { height } = this.env.model.getters.getSheetViewDimension();
const { height } = this.env.model.getters?.getSheetViewDimension();
return height;
}

Expand Down
1 change: 1 addition & 0 deletions src/components/spreadsheet/spreadsheet.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
</div>
<SidePanel/>
<BottomBar onClick="() => this.focusGrid()"/>
<SpreadsheetProgressBar t-props="{longRunner: model.longRunner}"/>
</t>
</div>
</t>
Expand Down
Loading

0 comments on commit 9838b47

Please sign in to comment.