mirror of
https://github.com/outline/outline.git
synced 2026-05-08 02:50:30 -05:00
feat: Public sharing of collections (#9529)
* shares.info, collections.info, documents.info * shares.list, shares.create, shares.update * shares.sitemap * parity with existing document shared screen * collection share popover * parent share and table * collection scene * collection link in sidebar * sidebar and breadcrumb collection link click * collection link click in editor * meta * more meta + 404 page * map internal link, remove showLastUpdated option * fix shares.list pagination * show last updated * shareLoader tests * lint * sidebar context for collection link * badge in shares table * fix existing tests * tsc * update failing test snapshot * env * signed url for collection attachments * include collection content in SSR for screen readers * search * drafts can be shared * review * tsc, remove old shared-doc scene * tweaks * DRY * refactor loader * Remove share/collection urls * fix: Collection overview should not be editable when viewing shared link and logged in * Tweak public breadcrumb * fix: Deleted documents should never be exposed through share * empty sharedTree array where includeChildDocuments is false * revert includeChildDocs guard for logical correctness + SSR bug fix * fix: check document is part of share --------- Co-authored-by: Tom Moor <tom@getoutline.com>
This commit is contained in:
@@ -320,6 +320,13 @@ export default class Collection extends ParanoidModel {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@action
|
||||
share = async () =>
|
||||
this.store.rootStore.shares.create({
|
||||
type: "collection",
|
||||
collectionId: this.id,
|
||||
});
|
||||
|
||||
getChildrenForDocument(documentId: string) {
|
||||
let result: NavigationNode[] = [];
|
||||
|
||||
|
||||
@@ -330,7 +330,7 @@ export default class Document extends ArchivableModel implements Searchable {
|
||||
get isPubliclyShared(): boolean {
|
||||
const { shares, auth } = this.store.rootStore;
|
||||
const share = shares.getByDocumentId(this.id);
|
||||
const sharedParent = shares.getByDocumentParents(this.id);
|
||||
const sharedParent = shares.getByDocumentParents(this);
|
||||
|
||||
return !!(
|
||||
auth.team?.sharing !== false &&
|
||||
@@ -461,6 +461,7 @@ export default class Document extends ArchivableModel implements Searchable {
|
||||
@action
|
||||
share = async () =>
|
||||
this.store.rootStore.shares.create({
|
||||
type: "document",
|
||||
documentId: this.id,
|
||||
});
|
||||
|
||||
|
||||
+36
-1
@@ -1,4 +1,7 @@
|
||||
import { computed, observable } from "mobx";
|
||||
import { NavigationNode, PublicTeam } from "@shared/types";
|
||||
import SharesStore from "~/stores/SharesStore";
|
||||
import env from "~/env";
|
||||
import Collection from "./Collection";
|
||||
import Document from "./Document";
|
||||
import User from "./User";
|
||||
@@ -10,6 +13,8 @@ import { Searchable } from "./interfaces/Searchable";
|
||||
class Share extends Model implements Searchable {
|
||||
static modelName = "Share";
|
||||
|
||||
store: SharesStore;
|
||||
|
||||
@Field
|
||||
@observable
|
||||
published: boolean;
|
||||
@@ -44,6 +49,12 @@ class Share extends Model implements Searchable {
|
||||
@observable
|
||||
domain: string;
|
||||
|
||||
@observable
|
||||
sourceTitle: string;
|
||||
|
||||
@observable
|
||||
sourcePath: string;
|
||||
|
||||
@observable
|
||||
documentTitle: string;
|
||||
|
||||
@@ -71,9 +82,33 @@ class Share extends Model implements Searchable {
|
||||
@Relation(() => User, { onDelete: "null" })
|
||||
createdBy: User;
|
||||
|
||||
static sitemapUrl(shareId: string) {
|
||||
return `${env.URL}/api/shares.sitemap?shareId=${shareId}`;
|
||||
}
|
||||
|
||||
@computed
|
||||
get title(): string {
|
||||
return this.sourceTitle ?? this.documentTitle;
|
||||
}
|
||||
|
||||
@computed
|
||||
get sourcePathWithFallback(): string {
|
||||
return this.sourcePath ?? this.documentUrl;
|
||||
}
|
||||
|
||||
@computed
|
||||
get searchContent(): string[] {
|
||||
return [this.document?.title ?? this.documentTitle];
|
||||
return [this.title];
|
||||
}
|
||||
|
||||
@computed
|
||||
get team(): PublicTeam | undefined {
|
||||
return this.store.sharedCache.get(this.id)?.team;
|
||||
}
|
||||
|
||||
@computed
|
||||
get tree(): NavigationNode | undefined {
|
||||
return this.store.sharedCache.get(this.id)?.sharedTree ?? undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user