Compare commits

...

8 Commits

Author SHA1 Message Date
dafa4242dd chore: github build cache 2024-05-30 11:18:48 +08:00
b36274db37 chore: build docker image by github actions 2024-05-30 11:18:48 +08:00
dc0550b112 feat: right-click to open menu for document/collection links 2024-05-30 11:18:48 +08:00
Tom Moor
1ceb87515d fix: Default feature flag logic 2024-05-29 21:30:42 -04:00
Tom Moor
1c4817486b Bump paragraph spacing 2024-05-29 21:29:10 -04:00
Tom Moor
4b1b87abde fix: Cannot remove user from collection in beta sharing UI 2024-05-29 20:04:20 -04:00
Tom Moor
5e841f6b16 fix: Correctly replace urls with signed versions when fully qualified 2024-05-29 19:55:54 -04:00
dependabot[bot]
6fd7e755b0 chore(deps): bump semver and @types/semver (#6954)
Bumps [semver](https://github.com/npm/node-semver) and [@types/semver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/semver). These dependencies needed to be updated together.

Updates `semver` from 7.6.0 to 7.6.2
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v7.6.0...v7.6.2)

Updates `@types/semver` from 7.5.6 to 7.5.8
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/semver)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: "@types/semver"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-29 15:50:33 -07:00
14 changed files with 148 additions and 32 deletions

46
.github/workflows/publish-docker.yml vendored Normal file
View File

@@ -0,0 +1,46 @@
name: CI/CD Pipeline
on: [push]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
# - name: Setup Node.js environment
# uses: actions/setup-node@v4
# with:
# node-version: "18"
# - name: Install Dependencies
# run: yarn install
# - name: Build Project
# run: yarn build
- name: Docker login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile.base
push: true
tags: |
yuuza/outline-base:${{ github.ref_name == 'main' && 'latest' || github.ref_name }}
cache-from: type=registry,ref=yuuza/outline-base:${{ github.ref_name == 'main' && 'latest' || github.ref_name }}
cache-to: type=inline
- run: docker tag yuuza/outline-base:${{ github.ref_name == 'main' && 'latest' || github.ref_name }} outlinewiki/outline-base:latest
- name: Build runner image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
yuuza/outline:${{ github.ref_name == 'main' && 'latest' || github.ref_name }}
cache-from: type=registry,ref=yuuza/outline:${{ github.ref_name == 'main' && 'latest' || github.ref_name }}
cache-to: type=inline

View File

@@ -81,6 +81,13 @@ function DocumentListItem(
title: document.titleWithDefault,
},
}}
onContextMenu={(e) => {
if (menuOpen) {
return;
}
e.preventDefault();
handleMenuOpen();
}}
{...rest}
>
<Content>
@@ -137,6 +144,7 @@ function DocumentListItem(
<DocumentMenu
document={document}
showPin={showPin}
visible={menuOpen}
onOpen={handleMenuOpen}
onClose={handleMenuClose}
modal={false}

View File

@@ -146,18 +146,20 @@ function CollectionMemberList({ collection, invitedInSession }: Props) {
<InputMemberPermissionSelect
style={{ margin: 0 }}
permissions={permissions}
onChange={async (permission: CollectionPermission) => {
if (permission) {
onChange={async (
permission: CollectionPermission | typeof EmptySelectValue
) => {
if (permission === EmptySelectValue) {
await memberships.delete({
collectionId: collection.id,
userId: membership.userId,
});
} else {
await memberships.create({
collectionId: collection.id,
userId: membership.userId,
permission,
});
} else {
await memberships.delete({
collectionId: collection.id,
userId: membership.userId,
});
}
}}
disabled={!can.update}

View File

@@ -131,7 +131,16 @@ const CollectionLink: React.FC<Props> = ({
return (
<>
<Relative ref={drop}>
<Relative
ref={drop}
onContextMenu={(e) => {
if (menuOpen || isEditing) {
return;
}
e.preventDefault();
handleMenuOpen();
}}
>
<DropToImport collectionId={collection.id}>
<SidebarLink
to={{
@@ -178,6 +187,7 @@ const CollectionLink: React.FC<Props> = ({
onRename={() =>
editableTitleRef.current?.setIsEditing(true)
}
visible={menuOpen}
onOpen={handleMenuOpen}
onClose={handleMenuClose}
/>

View File

@@ -310,6 +310,13 @@ function InnerDocumentLink(
$isDragging={isDragging}
$isMoving={isMoving}
onKeyDown={handleKeyDown}
onContextMenu={(e) => {
if (menuOpen || isEditing) {
return;
}
e.preventDefault();
handleMenuOpen();
}}
>
<div ref={dropToReparent}>
<DropToImport documentId={node.id} activeClassName="activeDropZone">
@@ -372,6 +379,7 @@ function InnerDocumentLink(
onRename={() =>
editableTitleRef.current?.setIsEditing(true)
}
visible={menuOpen}
onOpen={handleMenuOpen}
onClose={handleMenuClose}
/>

View File

@@ -115,7 +115,18 @@ function StarredLink({ star }: Props) {
return (
<>
<Draggable key={star.id} ref={draggableRef} $isDragging={isDragging}>
<Draggable
key={star.id}
ref={draggableRef}
$isDragging={isDragging}
onContextMenu={(e) => {
if (menuOpen) {
return;
}
e.preventDefault();
handleMenuOpen();
}}
>
<SidebarLink
depth={0}
to={{
@@ -136,6 +147,7 @@ function StarredLink({ star }: Props) {
<Fade>
<DocumentMenu
document={document}
visible={menuOpen}
onOpen={handleMenuOpen}
onClose={handleMenuClose}
/>

View File

@@ -39,6 +39,7 @@ type Props = {
collection: Collection;
placement?: Placement;
modal?: boolean;
visible?: boolean;
label?: (props: MenuButtonHTMLProps) => React.ReactNode;
onRename?: () => void;
onOpen?: () => void;
@@ -49,6 +50,7 @@ function CollectionMenu({
collection,
label,
modal = true,
visible,
placement,
onRename,
onOpen,
@@ -64,6 +66,12 @@ function CollectionMenu({
const history = useHistory();
const file = React.useRef<HTMLInputElement>(null);
React.useEffect(() => {
if (visible !== undefined && menu.visible !== visible) {
menu.setVisible(visible);
}
}, [visible]);
const handleExport = React.useCallback(() => {
dialogs.openModal({
title: t("Export collection"),

View File

@@ -61,6 +61,7 @@ type Props = {
/** Pass true if the document is currently being displayed */
showDisplayOptions?: boolean;
modal?: boolean;
visible?: boolean;
showToggleEmbeds?: boolean;
showPin?: boolean;
label?: (props: MenuButtonHTMLProps) => React.ReactNode;
@@ -74,6 +75,7 @@ function DocumentMenu({
document,
className,
modal = true,
visible,
showToggleEmbeds,
showDisplayOptions,
label,
@@ -106,6 +108,12 @@ function DocumentMenu({
})
);
React.useEffect(() => {
if (visible !== undefined && menu.visible !== visible) {
menu.setVisible(visible);
}
}, [visible]);
const handleOpen = React.useCallback(async () => {
if (!data && !loading) {
await request();

View File

@@ -28,7 +28,7 @@ export class FeatureFlags {
this.initalized = true;
}
return this.cache.has(flag) ?? FeatureDefaults[flag];
return this.cache.has(flag) ? true : FeatureDefaults[flag] ?? false;
}
public static enable(flag: Feature) {

View File

@@ -210,7 +210,7 @@
"resolve-path": "^1.4.0",
"rfc6902": "^5.1.1",
"sanitize-filename": "^1.6.3",
"semver": "^7.5.2",
"semver": "^7.6.2",
"sequelize": "^6.37.3",
"sequelize-cli": "^6.6.1",
"sequelize-encrypted": "^1.0.0",
@@ -304,7 +304,7 @@
"@types/redis-info": "^3.0.3",
"@types/refractor": "^3.4.0",
"@types/resolve-path": "^1.4.2",
"@types/semver": "^7.5.6",
"@types/semver": "^7.5.8",
"@types/sequelize": "^4.28.19",
"@types/slug": "^5.0.7",
"@types/stoppable": "^1.1.3",

View File

@@ -203,16 +203,32 @@ export class ProsemirrorHelper {
const json = doc.toJSON() as ProsemirrorData;
function getMapping(href: string) {
let relativeHref;
try {
const url = new URL(href);
relativeHref = url.toString().substring(url.origin.length);
} catch {
// Noop: Invalid url.
}
return (
mapping[href] ||
(relativeHref ? mapping[relativeHref] : undefined) ||
href
);
}
function replaceAttachmentUrls(node: ProsemirrorData) {
if (node.attrs?.src) {
node.attrs.src = mapping[node.attrs.src as string] || node.attrs.src;
node.attrs.src = getMapping(String(node.attrs.src));
} else if (node.attrs?.href) {
node.attrs.href = mapping[node.attrs.href as string] || node.attrs.href;
node.attrs.href = getMapping(String(node.attrs.href));
} else if (node.marks) {
node.marks.forEach((mark) => {
if (mark.attrs?.href) {
mark.attrs.href =
mapping[mark.attrs.href as string] || mark.attrs.href;
mark.attrs.href = getMapping(String(mark.attrs.href));
}
});
}

View File

@@ -320,8 +320,8 @@ width: 100%;
}
& > * {
margin-top: .5em;
margin-bottom: .5em;
margin-top: 0.85em;
margin-bottom: 0.85em;
&:last-child {
margin-bottom: 0;
@@ -497,8 +497,8 @@ iframe.embed {
max-width: 840px;
cursor: default;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-top: 0.85em;
margin-bottom: 0.85em;
.title,
.subtitle {
@@ -1244,7 +1244,7 @@ pre {
background: ${props.theme.codeBackground};
border-radius: 4px;
border: 1px solid ${props.theme.codeBorder};
margin: .5em 0;
margin: 0.85em 0;
-webkit-font-smoothing: initial;
font-family: ${props.theme.fontFamilyMono};

View File

@@ -80,7 +80,7 @@ export default createGlobalStyle<Props>`
font-weight: 500;
line-height: 1.25;
margin-top: 1em;
margin-bottom: 0.5em;
margin-bottom: 0.85em;
}
h1 { font-size: 36px; }
h2 { font-size: 26px; }

View File

@@ -4883,10 +4883,10 @@
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
integrity "sha1-GmL4lSVyPd4kuhsBsJK/XfitTTk= sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
"@types/semver@^7.5.0", "@types/semver@^7.5.6":
version "7.5.6"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339"
integrity "sha1-xlsr/OG+w0ZYLAdyTj+MEBeiAzk= sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A=="
"@types/semver@^7.5.0", "@types/semver@^7.5.8":
version "7.5.8"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e"
integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==
"@types/sequelize@^4.28.19":
version "4.28.19"
@@ -13416,12 +13416,10 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0, semve
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
semver@^7.5.0, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4:
version "7.6.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d"
integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==
dependencies:
lru-cache "^6.0.0"
semver@^7.5.0, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.6.2:
version "7.6.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13"
integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==
semver@~7.0.0:
version "7.0.0"