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