mirror of https://github.com/Squidex/squidex.git
19 changed files with 410 additions and 10 deletions
@ -0,0 +1,154 @@ |
|||||
|
<div class="modal" *sqxModalView="modalView;onRoot:true;closeAuto:false" @fade> |
||||
|
<div class="modal-backdrop"></div> |
||||
|
<div class="modal-dialog"> |
||||
|
<div class="modal-content"> |
||||
|
<a class="header-right modal-close" (click)="modalView.hide()">Skip Tour</a> |
||||
|
|
||||
|
<div class="onboarding-step" *ngIf="step === 0"> |
||||
|
<img @fade class="header-left" src="/images/logo-white-small.png" /> |
||||
|
|
||||
|
<div class="onboarding-enter-leave" @slide> |
||||
|
<h1>Welcome to <span class="header-focus">Squidex CMS</span></h1> |
||||
|
|
||||
|
<p> |
||||
|
You can start managing and distributing your content right away, but we we'd like to walk you through some basics first... |
||||
|
</p> |
||||
|
<p> |
||||
|
How's that? |
||||
|
</p> |
||||
|
|
||||
|
<button (click)="next()" class="btn btn-success">Let'ts take a look around</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="onboarding-step" *ngIf="step === 1"> |
||||
|
<h1 class="header-left header-focus" @fade>Apps</h1> |
||||
|
|
||||
|
<div @slide> |
||||
|
<div class="row"> |
||||
|
<div class="col"> |
||||
|
<div class="onboarding-text"> |
||||
|
<p> |
||||
|
An App is the repository for your project, e.g. (blog, webshop or mobile app). You can assign contributors to your app to |
||||
|
work together. |
||||
|
</p> |
||||
|
<p> |
||||
|
You can create an unlimited number of Apps in Squidex to manage multiple projects at the same time. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col col-auto"> |
||||
|
<img src="/images/onboarding-step1.png" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="footer"> |
||||
|
<button (click)="next()" class="btn btn-success">Continue</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="onboarding-step" *ngIf="step === 2"> |
||||
|
<h1 class="header-left header-focus" @fade>Schemas</h1> |
||||
|
|
||||
|
<div @slide> |
||||
|
<div class="row"> |
||||
|
<div class="col"> |
||||
|
<div class="onboarding-text"> |
||||
|
<p> |
||||
|
Schemas define the structure of your content, the fields and the data types of a content item. |
||||
|
</p> |
||||
|
<p> |
||||
|
Beforew you can add content to your schema, make sure to hit the 'Publish' button at the top to make the schema availabel |
||||
|
to your content editors. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col col-auto"> |
||||
|
<img src="/images/onboarding-step2.png" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="footer"> |
||||
|
<button (click)="next()" class="btn btn-success">Keep going!</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="onboarding-step" *ngIf="step === 3"> |
||||
|
<h1 @fade class="header-left header-focus">Contents</h1> |
||||
|
|
||||
|
<div @slide> |
||||
|
<div class="row"> |
||||
|
<div class="col"> |
||||
|
<div class="onboarding-text"> |
||||
|
<p> |
||||
|
Content is the actual data in your app which is grouped by the schema. |
||||
|
</p> |
||||
|
<p> |
||||
|
Select a published schema first, then add content for this schema. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col col-auto"> |
||||
|
<img src="/images/onboarding-step3.png" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="footer"> |
||||
|
<button (click)="next()" class="btn btn-success">Almost there!</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="onboarding-step" *ngIf="step === 4"> |
||||
|
<h1 @fade class="header-left header-focus">Assets</h1> |
||||
|
|
||||
|
<div @slide> |
||||
|
|
||||
|
<div class="row"> |
||||
|
<div class="col"> |
||||
|
<div class="onboarding-text"> |
||||
|
<p> |
||||
|
The assets contains all files that can also be linked to your content. For example images, videos or documents. |
||||
|
</p> |
||||
|
<p> |
||||
|
You can upload the assets here and use them later or also upload them directly when you create a new content item with an |
||||
|
asset field. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col col-auto"> |
||||
|
<img src="/images/onboarding-step4.png" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="footer"> |
||||
|
<button (click)="next()" class="btn btn-success">Got It!</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="onboarding-step" *ngIf="step === 5"> |
||||
|
<img @fade class="header-left" src="/images/logo-white-small.png" /> |
||||
|
|
||||
|
<div class="onboarding-enter-leave" @slide> |
||||
|
<h1>Awesome, now you know the basics!</h1> |
||||
|
|
||||
|
<p> |
||||
|
But that's not all of the support we can provide. <br />You can go to <a href="https://docs.squidex.io/" |
||||
|
target="_blank">https://docs.squidex.io/</a> to read more. |
||||
|
</p> |
||||
|
<p> |
||||
|
Do you want to join our community? |
||||
|
</p> |
||||
|
|
||||
|
<div> |
||||
|
<a class="btn btn-success" href="https://squidex.slack.com/signup" target="_blank"> |
||||
|
Join us on Slack |
||||
|
</a> |
||||
|
|
||||
|
<a class="btn btn-success" href="https://github.com/squidex/squidex" target="_blank"> |
||||
|
Join us on Github |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,78 @@ |
|||||
|
@import '_vars'; |
||||
|
@import '_mixins'; |
||||
|
|
||||
|
$size-width: 825px; |
||||
|
$size-height: 576px; |
||||
|
|
||||
|
$size-image: 476px; |
||||
|
|
||||
|
h1 { |
||||
|
font-size: 1.6rem; |
||||
|
} |
||||
|
|
||||
|
p { |
||||
|
line-height: 1.8rem; |
||||
|
} |
||||
|
|
||||
|
.modal { |
||||
|
&-content, |
||||
|
&-dialog { |
||||
|
min-height: $size-height; |
||||
|
max-height: $size-height; |
||||
|
min-width: $size-width; |
||||
|
max-width: $size-width; |
||||
|
} |
||||
|
|
||||
|
&-content { |
||||
|
color: $color-dark-foreground; |
||||
|
background-color: $color-dark-onboarding; |
||||
|
background-image: url('/images/onboarding-background.png'); |
||||
|
overflow: hidden; |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
&-close { |
||||
|
text-decoration: underline !important; |
||||
|
cursor: pointer; |
||||
|
color: $color-dark-foreground; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.header-focus { |
||||
|
color: $color-theme-blue; |
||||
|
} |
||||
|
|
||||
|
.header-left { |
||||
|
@include absolute(-70px, auto, auto, 2rem); |
||||
|
} |
||||
|
|
||||
|
.header-right { |
||||
|
@include absolute(2rem, 2rem, auto, auto); |
||||
|
} |
||||
|
|
||||
|
.footer { |
||||
|
@include absolute(auto, auto, 5rem, 2rem); |
||||
|
} |
||||
|
|
||||
|
.onboarding { |
||||
|
&-enter-leave { |
||||
|
& { |
||||
|
text-align: center; |
||||
|
margin: 4rem auto 0; |
||||
|
max-width: 28rem; |
||||
|
min-width: 28rem; |
||||
|
} |
||||
|
|
||||
|
p { |
||||
|
margin: 2rem 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&-text { |
||||
|
padding-left: 2rem; |
||||
|
} |
||||
|
|
||||
|
&-step { |
||||
|
@include absolute($size-height - $size-image, 0, 0, 0); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import { Component, Input } from '@angular/core'; |
||||
|
|
||||
|
import { |
||||
|
fadeAnimation, |
||||
|
ModalView, |
||||
|
slideAnimation |
||||
|
} from 'framework'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'sqx-onboarding-dialog', |
||||
|
styleUrls: ['./onboarding-dialog.component.scss'], |
||||
|
templateUrl: './onboarding-dialog.component.html', |
||||
|
animations: [ |
||||
|
fadeAnimation, slideAnimation |
||||
|
] |
||||
|
}) |
||||
|
export class OnboardingDialogComponent { |
||||
|
public step = 0; |
||||
|
|
||||
|
@Input() |
||||
|
public modalView = new ModalView(); |
||||
|
|
||||
|
public next() { |
||||
|
this.step = this.step + 1; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,70 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import { OnboardingService, OnboardingServiceFactory } from './../'; |
||||
|
|
||||
|
class LocalStoreMock { |
||||
|
private store = {}; |
||||
|
|
||||
|
public get(key: string) { |
||||
|
return this.store[key]; |
||||
|
} |
||||
|
|
||||
|
public set(key: string, value: string) { |
||||
|
this.store[key] = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
describe('OnboardingService', () => { |
||||
|
const localStore = new LocalStoreMock(); |
||||
|
|
||||
|
it('should instantiate from factory', () => { |
||||
|
const onboardingService = OnboardingServiceFactory(<any>localStore); |
||||
|
|
||||
|
expect(onboardingService).toBeDefined(); |
||||
|
}); |
||||
|
|
||||
|
it('should instantiate', () => { |
||||
|
const onboardingService = new OnboardingService(<any>localStore); |
||||
|
|
||||
|
expect(onboardingService).toBeDefined(); |
||||
|
}); |
||||
|
|
||||
|
it('should return true when value not in store', () => { |
||||
|
localStore.set('squidex.onboarding.disable.feature1', '0'); |
||||
|
|
||||
|
const onboardingService = new OnboardingService(<any>localStore); |
||||
|
|
||||
|
onboardingService.disable('feature2'); |
||||
|
|
||||
|
expect(onboardingService.shouldShow('feature1')).toBeTruthy(); |
||||
|
}); |
||||
|
|
||||
|
it('should return false when value in store', () => { |
||||
|
localStore.set('squidex.onboarding.disable.feature1', '1'); |
||||
|
|
||||
|
const onboardingService = new OnboardingService(<any>localStore); |
||||
|
|
||||
|
expect(onboardingService.shouldShow('feature1')).toBeFalsy(); |
||||
|
}); |
||||
|
|
||||
|
it('should return false when disabled', () => { |
||||
|
const onboardingService = new OnboardingService(<any>localStore); |
||||
|
|
||||
|
onboardingService.disable('feature1'); |
||||
|
|
||||
|
expect(onboardingService.shouldShow('feature1')).toBeFalsy(); |
||||
|
}); |
||||
|
|
||||
|
it('should return false when all disabled', () => { |
||||
|
const onboardingService = new OnboardingService(<any>localStore); |
||||
|
|
||||
|
onboardingService.disableAll(); |
||||
|
|
||||
|
expect(onboardingService.shouldShow('feature1')).toBeFalsy(); |
||||
|
}); |
||||
|
}); |
||||
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 40 KiB |
Loading…
Reference in new issue