mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
first functionnal POC
Co-authored-by: hexaltation <gregoire@cutzach.com> Co-authored-by: fflorent <florent.git@zeteo.me>
This commit is contained in:
parent
e9b5b98bcb
commit
f40bd9d075
@ -29,6 +29,7 @@ import {Holder, Observable, subscribe} from 'grainjs';
|
||||
import {Computed, Disposable, dom, DomArg, DomElementArg} from 'grainjs';
|
||||
import {makeT} from 'app/client/lib/localization';
|
||||
import {logTelemetryEvent} from 'app/client/lib/telemetry';
|
||||
import {DocumentType} from 'app/common/UserAPI';
|
||||
|
||||
// tslint:disable:no-console
|
||||
|
||||
@ -87,7 +88,7 @@ export interface DocPageModel {
|
||||
isTutorialTrunk: Observable<boolean>;
|
||||
isTutorialFork: Observable<boolean>;
|
||||
isTemplate: Observable<boolean>;
|
||||
|
||||
type: Observable<DocumentType|null>;
|
||||
importSources: ImportSource[];
|
||||
|
||||
undoState: Observable<IUndoState|null>; // See UndoStack for details.
|
||||
@ -147,6 +148,8 @@ export class DocPageModelImpl extends Disposable implements DocPageModel {
|
||||
(use, doc) => doc ? doc.isTutorialFork : false);
|
||||
public readonly isTemplate = Computed.create(this, this.currentDoc,
|
||||
(use, doc) => doc ? doc.isTemplate : false);
|
||||
public readonly type = Computed.create(this, this.currentDoc,
|
||||
(use, doc) => doc?.type?? null);
|
||||
|
||||
public readonly importSources: ImportSource[] = [];
|
||||
|
||||
@ -499,7 +502,8 @@ function buildDocInfo(doc: Document, mode: OpenDocMode | undefined): DocInfo {
|
||||
const isFork = Boolean(idParts.forkId || idParts.snapshotId);
|
||||
const isBareFork = isFork && idParts.trunkId === NEW_DOCUMENT_CODE;
|
||||
const isSnapshot = Boolean(idParts.snapshotId);
|
||||
const isTutorial = doc.type === 'tutorial';
|
||||
const type = doc.type;
|
||||
const isTutorial = type === 'tutorial';
|
||||
const isTutorialTrunk = isTutorial && !isFork && mode !== 'default';
|
||||
const isTutorialFork = isTutorial && isFork;
|
||||
|
||||
@ -511,7 +515,7 @@ function buildDocInfo(doc: Document, mode: OpenDocMode | undefined): DocInfo {
|
||||
// mode. Since the document's 'openMode' has no effect, don't bother trying
|
||||
// to set it here, as it'll potentially be confusing for other code reading it.
|
||||
openMode = 'default';
|
||||
} else if (!isFork && doc.type === 'template') {
|
||||
} else if (!isFork && type === 'template') {
|
||||
// Templates should always open in fork mode by default.
|
||||
openMode = 'fork';
|
||||
} else {
|
||||
@ -521,7 +525,7 @@ function buildDocInfo(doc: Document, mode: OpenDocMode | undefined): DocInfo {
|
||||
}
|
||||
|
||||
const isPreFork = openMode === 'fork';
|
||||
const isTemplate = doc.type === 'template' && (isFork || isPreFork);
|
||||
const isTemplate = type === 'template' && (isFork || isPreFork);
|
||||
const isEditable = !isSnapshot && (canEdit(doc.access) || isPreFork);
|
||||
return {
|
||||
...doc,
|
||||
@ -534,6 +538,7 @@ function buildDocInfo(doc: Document, mode: OpenDocMode | undefined): DocInfo {
|
||||
isSnapshot,
|
||||
isTutorialTrunk,
|
||||
isTutorialFork,
|
||||
type,
|
||||
isTemplate,
|
||||
isReadonly: !isEditable,
|
||||
idParts,
|
||||
|
@ -31,6 +31,7 @@ import {getCurrency, locales} from 'app/common/Locales';
|
||||
import {isOwner, isOwnerOrEditor} from 'app/common/roles';
|
||||
import {Computed, Disposable, dom, fromKo, IDisposableOwner, makeTestId, Observable, styled} from 'grainjs';
|
||||
import * as moment from 'moment-timezone';
|
||||
import {DocumentType} from 'app/common/UserAPI';
|
||||
|
||||
const t = makeT('DocumentSettings');
|
||||
const testId = makeTestId('test-settings-');
|
||||
@ -41,6 +42,7 @@ export class DocSettingsPage extends Disposable {
|
||||
private _timezone = this._docInfo.timezone;
|
||||
private _locale: KoSaveableObservable<string> = this._docInfo.documentSettingsJson.prop('locale');
|
||||
private _currency: KoSaveableObservable<string|undefined> = this._docInfo.documentSettingsJson.prop('currency');
|
||||
// private _type: KoSaveableObservable<string|undefined> = this._docInfo.documentSettingsJson.prop('type');
|
||||
private _engine: Computed<EngineCode|undefined> = Computed.create(this, (
|
||||
use => use(this._docInfo.documentSettingsJson.prop('engine'))
|
||||
))
|
||||
@ -194,6 +196,14 @@ export class DocSettingsPage extends Disposable {
|
||||
value: cssSmallLinkButton(t('Manage webhooks'), urlState().setLinkUrl({docPage: 'webhook'})),
|
||||
}),
|
||||
]),
|
||||
dom.create(AdminSection, t('Document conversion'), [
|
||||
dom.create(AdminSectionItem, {
|
||||
id: 'document-type',
|
||||
name: t('Document type'),
|
||||
description: t('Convert the document'),
|
||||
value: dom.create(buildTypeSelect, docPageModel.type, docPageModel.currentDocId.get()),
|
||||
}),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
@ -298,7 +308,15 @@ export class DocSettingsPage extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function persistType(type: string|null, docId: string|undefined){
|
||||
docId = docId?.split("~")[0];
|
||||
return fetch(`/o/docs/api/docs/${docId}`,
|
||||
{ method:'PATCH',
|
||||
headers: {"Content-Type": "application/json"},
|
||||
credentials: 'include',
|
||||
body:JSON.stringify({type})
|
||||
}).catch((err)=>{ console.log(err); });
|
||||
}
|
||||
|
||||
function getApiConsoleLink(docPageModel: DocPageModel) {
|
||||
const url = new URL(location.href);
|
||||
@ -343,6 +361,45 @@ function buildLocaleSelect(
|
||||
);
|
||||
}
|
||||
|
||||
type DocumentTypeItem = ACSelectItem & {type?: string};
|
||||
|
||||
function buildTypeSelect(
|
||||
owner: IDisposableOwner,
|
||||
type: Observable<DocumentType|null>,
|
||||
id: string|undefined,
|
||||
) {
|
||||
const typeList: DocumentTypeItem[] = [{
|
||||
label: t('Regular'),
|
||||
type: ''
|
||||
}, {
|
||||
label: t('Template'),
|
||||
type: 'template'
|
||||
},
|
||||
{
|
||||
label: t('Tutorial'),
|
||||
type: 'tutorial'
|
||||
}].map((el) => ({
|
||||
...el,
|
||||
value: el.label,
|
||||
cleanText: el.label.trim().toLowerCase()
|
||||
}));
|
||||
const typeObs = Computed.create(owner, use => {
|
||||
const typeCode = use(type)??"";
|
||||
const typeName = typeList.find(ty => ty.type === typeCode)?.label || typeCode;
|
||||
return typeName;
|
||||
});
|
||||
const acIndex = new ACIndexImpl<DocumentTypeItem>(typeList, {maxResults: 200, keepOrder: true});
|
||||
return buildACSelect(owner, {
|
||||
acIndex, valueObs: typeObs,
|
||||
save(_value, item: DocumentTypeItem | undefined) {
|
||||
if (!item) { throw new Error("Invalid DocumentType"); }
|
||||
persistType(item.type!, id)
|
||||
.then(()=>window.location.reload())
|
||||
.catch(err=>console.log(err));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const cssContainer = styled('div', `
|
||||
overflow-y: auto;
|
||||
position: relative;
|
||||
|
Loading…
Reference in New Issue
Block a user